Introduction

Lately I've started working on this pelican-plugin that will use special command in markdown article to "magically" change it's content into a fancybox-alike.

I've started it with badly without TDD and that approach failed to leave me with successful plugin created.

My failure was also in copy-pasting others plugins content and trying to re-use it for my own purpose, but it didn't work properly.

This time using TDD and slower movement of source-code I'm working on describing and finding elements of "fancybox" in article.

So no more chit-chat, let's move to the actual source-code and content of this article! :)

Finding Fancybox elements

1. Describing fancybox elements

So I've been thinking how to easily add fancybox element in markdown so it will be easily added to markdown and then also easily readed at plugin for further manipulation of article content.

I've figure I'll start with something, that may be good for beginning and then If I find it will not suit my needs , I'll change it to something else.

That's why for sake of simplicity I'm going to use for now this element:

<fancybox>URL</fancybox>

Let's check how it will work for now! :)

2. Creating testing markdown article and adding it to tests.

I've created an example Article instance with "content" that had the <fancybox>URL</fancybox> element inside. Also I've figure out that I should also check if using pelican it-self will be of great benefit, so I've added a Markdown file in content for pelican.

And sure thing - it did! I found that my plugin function that was registered didn't have proper arguments.

Also I moved finally source-code of my plugin to fancybox.py instead of test_fancybox.py.

3. Adding testing article with fancybox elements

Test function looks like below:

def test_given_article_with_fancybox_find_fancybox_element():
    "Checks for finding fancybox element in article"
    article = Article('Data data data\n <fancybox>TEST</fancybox>\ndata data data')
    assert find_fancybox_element(article)

4. Testing and creating source code.

Source code for now looks like this:

from pelican import signals

class Article(object):
    "A simple Article class"
    def __init__(self, content = ""):
        self.content = content

def find_fancybox_element(article):
    found = None
    for content_line in article.content.split("\n"):
        if "<fancybox>" in content_line:
            found = content_line
    return found

def fancybox_plugin(generator):
    "Fanxybox plugin - temporary code placement"
    print find_fancybox_element(generator.articles[0])

def register():
    "Registers plugin"
    signals.article_generator_finalized.connect(fancybox_plugin)

And yes, I know that I'm currently using checking for first element and it may raise with IndexError.

I'll fix this properly - for sure.

Final result for testing fancybox plugin

"""
FancyBox unittests
"""
from pelican import signals
from fancybox import register
from fancybox import Article
from fancybox import find_fancybox_element
from fancybox import fancybox_plugin

def mock_article_generator():
    "Article generator"
    yield Article()

def assert_receiver_registered(receiver_name):
    'Checks if receiver is registered to signals generator'
    assert signals.article_generator_finalized.has_receivers_for(receiver_name)

def test_plugin_registers():
    """
    Check if plugin registers to article_generator_finalized
    """
    register()
    assert_receiver_registered(fancybox_plugin)

def test_article_generator_return_article():
    """
    Checks if generator return article
    """
    assert isinstance(mock_article_generator().next(), Article)

def test_given_article_generator_check_article_content_exists():
    "Checks if article content field exists in article"
    for article in mock_article_generator():
        assert hasattr(article, 'content')

def test_given_article_with_fancybox_find_fancybox_element():
    "Checks for finding fancybox element in article"
    article = Article('Data data data\n <fancybox>TEST</fancybox>\ndata data data')
    assert find_fancybox_element(article)

Code commits done for this post:

Tools and applications used:

Accomplished:

1. Make more tests and source-code of fancybox plugin

What's next

1. Make final commit for source-code of fancybox plugin

2. Start working on plugin for asciinema player.

3. See ISSUES task-list for this 'mini' growing project :)



Comments

comments powered by Disqus