fastpt / kajiki / tests / test_text.py

import os
import sys
import traceback
from unittest import TestCase, main

from kajiki import MockLoader, FileLoader, TextTemplate

class TestBasic(TestCase):

    def test_auto_escape(self):
        tpl = TextTemplate(source="${'<h1>'}")
        rsp = tpl().__kj__.render() 
        assert rsp == '&lt;h1&gt;', rsp

    def test_auto_escape_disable(self):
        tpl = TextTemplate(source="${literal('<h1>')}")
        rsp = tpl().__kj__.render() 
        assert rsp == '<h1>', rsp

    def test_expr_brace(self):
        tpl = TextTemplate(source='Hello, ${name}\n')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == 'Hello, Rick\n', rsp

    def test_expr_brace_complex(self):
        tpl = TextTemplate(source="Hello, ${{'name':name}['name']}\n")
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == 'Hello, Rick\n', rsp

    def test_expr_name(self):
        tpl = TextTemplate(source='Hello, $name\n')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == 'Hello, Rick\n', rsp
        tpl = TextTemplate(source='Hello, $obj.name\n')
        class Empty: pass
        Empty.name = 'Rick'
        rsp = tpl(dict(obj=Empty)).__kj__.render() 
        assert rsp == 'Hello, Rick\n', rsp

class TestSwitch(TestCase):

    def test_switch(self):
        tpl = TextTemplate('''%for i in range(2)
$i is {%switch i % 2 %}{%case 0%}even\n{%else%}odd\n{%end%}\\
%end''')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == '0 is even\n1 is odd\n', rsp

    def test_ljust(self):
        tpl = TextTemplate('''     %for i in range(2)
$i is {%switch i % 2 %}{%case 0%}even\n{%else%}odd\n{%end%}\\
%end''')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == '0 is even\n1 is odd\n', rsp
        tpl = TextTemplate('''     {%-for i in range(2)%}\\
$i is {%switch i % 2 %}{%case 0%}even{%else%}odd{%end%}
    {%-end%}''')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == '0 is even\n1 is odd\n', rsp

    def test_rstrip(self):
        tpl = TextTemplate('''     %for i in range(2)
$i is {%switch i % 2 %}{%case 0-%}    even\n{%else%}odd\n{%end%}\\
%end''')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == '0 is even\n1 is odd\n', rsp

class TestFunction(TestCase):

    def test_function(self):
        tpl = TextTemplate('''%def evenness(n)
{%if n % 2 == 0 %}even{%else%}odd{%end%}\\
%end
%for i in range(2)
$i is ${evenness(i)}
%end
''')
        rsp = tpl(dict(name='Rick')).__kj__.render() 
        assert rsp == '0 is even\n1 is odd\n', rsp

class TestCall(TestCase):

    def test_call(self):
        tpl = TextTemplate('''%def quote(caller, speaker)
    %for i in range(2)
Quoth $speaker, "${caller(i)}."
    %end
%end
%call(n) quote(%caller ,'the raven')
Nevermore $n\\
%end''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert (
            rsp == 'Quoth the raven, "Nevermore 0."\n'
            'Quoth the raven, "Nevermore 1."\n'), rsp

class TestImport(TestCase):

    def test_import(self):
        lib = TextTemplate('''%def evenness(n)
%if n % 2 == 0
even\\
%else
odd\\
%end
%end
%def half_evenness(n)
 half of $n is ${evenness(n/2)}\\
%end''')
        tpl = TextTemplate('''%import "lib.txt" as simple_function
%for i in range(4)
$i is ${simple_function.evenness(i)}${simple_function.half_evenness(i)}
%end''')
        loader = MockLoader({
            'lib.txt':lib,
            'tpl.txt':tpl})
        tpl = loader.import_('tpl.txt')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert (rsp=='0 is even half of 0 is even\n'
                '1 is odd half of 1 is even\n'
                '2 is even half of 2 is odd\n'
                '3 is odd half of 3 is odd\n'), rsp

    def test_import_auto(self):
        lib = TextTemplate('''%def evenness(n)
%if n % 2 == 0
even\\
%else
odd\\
%end
%end
%def half_evenness(n)
 half of $n is ${evenness(n/2)}\\
%end''')
        tpl = TextTemplate('''%import "lib.txt"
%for i in range(4)
$i is ${lib.evenness(i)}${lib.half_evenness(i)}
%end''')
        loader = MockLoader({
            'lib.txt':lib,
            'tpl.txt':tpl})
        tpl = loader.import_('tpl.txt')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert (rsp=='0 is even half of 0 is even\n'
                '1 is odd half of 1 is even\n'
                '2 is even half of 2 is odd\n'
                '3 is odd half of 3 is odd\n'), rsp

    def test_include(self):
        loader = MockLoader({
                'hdr.txt': TextTemplate('# header\n'),
                'tpl.txt': TextTemplate('''a
%include "hdr.txt"
b
''')})
        tpl = loader.import_('tpl.txt')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == 'a\n# header\nb\n', rsp

class TestExtends(TestCase):

    def test_basic(self):
        parent = TextTemplate('''
%def header()
# Header name=$name
%end
%def footer()
# Footer
%end
%def body()
## Parent Body
id() = ${id()}
local.id() = ${local.id()}
self.id() = ${self.id()}
child.id() = ${child.id()}
%end
%def id()
parent\\
%end
${header()}${body()}${footer()}''')
        mid = TextTemplate('''%extends "parent.txt"
%def id()
mid\\
%end
''')
        child = TextTemplate('''%extends "mid.txt"
%def id()
child\\
%end
%def body()
## Child Body
${parent.body()}\\
%end
''')
        loader = MockLoader({
            'parent.txt':parent,
            'mid.txt':mid,
            'child.txt':child})
        tpl = loader.import_('child.txt')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert (rsp == '# Header name=Rick\n'
                '## Child Body\n'
                '## Parent Body\n'
                'id() = child\n'
                'local.id() = parent\n'
                'self.id() = child\n'
                'child.id() = mid\n'
                '# Footer\n'), rsp

    def test_dynamic(self):
        loader = MockLoader({
                'parent0.txt':TextTemplate('Parent 0'),
                'parent1.txt':TextTemplate('Parent 1'),
                'child.txt':TextTemplate('''%if p == 0
%extends "parent0.txt"
%else
%extends "parent1.txt"
%end
''')
                })
        tpl = loader.import_('child.txt')
        rsp = tpl(dict(p=0)).__kj__.render()
        assert rsp == 'Parent 0', rsp
        rsp = tpl(dict(p=1)).__kj__.render()
        assert rsp == 'Parent 1', rsp

    def test_block(self):
        loader = MockLoader({
                'parent.txt':TextTemplate('''%def greet(name)
Hello, $name!\\
%end
%def sign(name)
Sincerely,
$name\\
%end
${greet(to)}

%block body
It was good seeing you last Friday.  Thanks for the gift!
%end

${sign(from_)}
'''),
                'child.txt':TextTemplate('''%extends "parent.txt"
%def greet(name)
Dear $name:\\
%end
%block body
${parent_block()}\\

And don't forget you owe me money!
%end
''')})
        child = loader.import_('child.txt')
        rsp = child({'to':'Mark', 'from_':'Rick'}).__kj__.render()
        assert (rsp=='''Dear Mark:
It was good seeing you last Friday.  Thanks for the gift!

And don't forget you owe me money!

Sincerely,
Rick
'''), rsp
        

class TestClosure(TestCase):
    
    def test(self):
        tpl = TextTemplate('''%def add(x)
%def inner(y)
${x+y}\\
%end
${inner(x*2)}\\
%end
${add(5)}
''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == '15\n', rsp

class TestPython(TestCase):

    def test_basic(self):
        tpl = TextTemplate('''%py
import os
%end
${os.path.join('a','b','c')}''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == 'a/b/c'

    def test_indent(self):
        tpl = TextTemplate('''%py
    import os
    import re
%end
${os.path.join('a','b','c')}''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == 'a/b/c'

    def test_short(self):
        tpl = TextTemplate('''%py import os
${os.path.join('a','b','c')}''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == 'a/b/c'

    def test_mod(self):
        tpl = TextTemplate('''%py% import os
%def test()
${os.path.join('a','b','c')}\\
%end
${test()}''')
        rsp = tpl(dict(name='Rick')).__kj__.render()
        assert rsp == 'a/b/c'

class TestDebug(TestCase):
    
    def test_debug(self):
        loader = FileLoader(base=os.path.join(os.path.dirname(__file__), 'data'))
        tpl = loader.import_('debug.txt')
        try:
            tpl().__kj__.render()
            assert False, 'Should have raised ValueError'
        except ValueError:
            exc_info = sys.exc_info()
            stack = traceback.extract_tb(exc_info[2])
        # Verify we have stack trace entries in the template
        for fn, lno, func, line in stack:
            if fn.endswith('debug.txt'): break
        else:
            assert False, 'Stacktrace is all python'

if __name__ == '__main__':
    main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.