def test_silent_formal_reference_in_an_if_condition(self): template = quik.Template("#if(@!{a.b.c})yes!#end") self.assertEqual("yes!", template.render({'a':{'b':{'c':'d'}}})) self.assertEqual("", template.render({})) template = quik.Template("#if(@!a.b.c)yes!#end") self.assertEqual("yes!", template.render({'a':{'b':{'c':'d'}}})) self.assertEqual("", template.render({}))
def test_standalone_hashes(self): template = quik.Template('#') self.assertEqual('#', template.render({})) template = quik.Template('"#"') self.assertEqual('"#"', template.render({})) template = quik.Template('<a href="#">bob</a>') self.assertEqual('<a href="#">bob</a>', template.render({}))
def test_silent_reference_function_calls_in_if_conditions(self): template = quik.Template("#if(@!{a.b.c('cheese')})yes!#end") self.assertEqual("yes!", template.render({'a':{'b':{'c':lambda x: "hello %s" % x}}})) self.assertEqual("", template.render({'a':{'b':{'c':lambda x: None}}})) self.assertEqual("", template.render({})) template = quik.Template("#if(@!a.b.c('cheese'))yes!#end") self.assertEqual("yes!", template.render({'a':{'b':{'c':lambda x: "hello %s" % x}}})) self.assertEqual("", template.render({'a':{'b':{'c':lambda x: None}}})) self.assertEqual("", template.render({}))
def test_valid_parse_directive_outputs_parsed_content(self): class WorkingLoader: def load_template(self, name): if name == 'foo.tmpl': return quik.Template("@message") template = quik.Template('Message is: #parse ("foo.tmpl")!') self.assertEqual('Message is: hola!', template.render({'message': 'hola'}, loader=WorkingLoader())) template = quik.Template('Message is: #parse (@foo)!') self.assertEqual('Message is: hola!', template.render({'foo': 'foo.tmpl', 'message': 'hola'}, loader=WorkingLoader()))
def test_can_call_function_with_two_parameters(self): def multiply(number1, number2): return number1 * number2 template = quik.Template('@multiply(2, 4)') self.assertEqual("8", template.render(locals())) template = quik.Template('@multiply( 2 , 4 )') self.assertEqual("8", template.render(locals())) value1, value2 = 4, 12 template = quik.Template('@multiply(@value1,@value2)') self.assertEqual("48", template.render(locals()))
def test_can_call_function_with_one_parameter(self): def squared(number): return number * number template = quik.Template('@squared(8)') self.assertEqual("64", template.render(locals())) some_var = 6 template = quik.Template('@squared(@some_var)') self.assertEqual("36", template.render(locals())) template = quik.Template('@squared(@squared(@some_var))') self.assertEqual("1296", template.render(locals()))
def test_syntax_error_contains_line_and_column_pos(self): try: quik.Template('#if ( @hello )\n\n#elseif blah').render({}) except quik.TemplateSyntaxError as e: self.assertEqual((3, 9), (e.line, e.column)) else: self.fail('expected error') try: quik.Template('#else blah').render({}) except quik.TemplateSyntaxError as e: self.assertEqual((1, 1), (e.line, e.column)) else: self.fail('expected error')
def test_can_define_macros_in_parsed_files(self): class Loader: def load_template(self, name): if name == 'foo.tmpl': return quik.Template('#macro themacro:works#end') template = quik.Template('#parse("foo.tmpl")#themacro :') self.assertEqual('works', template.render({}, loader=Loader()))
def test_valid_include_directive_include_content(self): class WorkingLoader: def load_text(self, name): if name == 'foo.tmpl': return "howdy" template = quik.Template('Message is: #include ("foo.tmpl")!') self.assertEqual('Message is: howdy!', template.render({}, loader=WorkingLoader()))
def test_multiline_arguments_to_function_calls(self): class Thing: def func(self, arg): return 'y' template = quik.Template('''@x.func("multi line")''') self.assertEqual('y', template.render({'x':Thing()}))
def test_when_if_statement_is_nested_inside_a_successful_enclosing_if_it_gets_evaluated(self): template = quik.Template("Hello #if (@show_greeting)your name is @{name}.#if (@is_birthday) Happy Birthday.#end#end Good to see you") namespace = {"name": "Steve", "show_greeting": False} self.assertEqual("Hello Good to see you", template.render(namespace)) namespace["show_greeting"] = True self.assertEqual("Hello your name is Steve. Good to see you", template.render(namespace)) namespace["is_birthday"] = True self.assertEqual("Hello your name is Steve. Happy Birthday. Good to see you", template.render(namespace))
def test_if_statement_honours_custom_truth_value_of_objects(self): class BooleanValue: def __init__(self, value): self.value = value def __len__(self): return self.value template = quik.Template("#if (@v)yes#end") self.assertEqual('', template.render({'v': BooleanValue(False)})) self.assertEqual('yes', template.render({'v': BooleanValue(True)}))
def test_correct_scope_for_parameters_of_method_calls(self): template = quik.Template('@obj.get_self().method(@param)') class C: def get_self(self): return self def method(self, p): if p == 'bat': return 'monkey' value = template.render({'obj': C(), 'param':'bat'}) self.assertEqual('monkey', value)
def test_logical_negation_operator_honours_custom_truth_values(self): class BooleanValue: def __init__(self, value): self.value = value def __len__(self): return self.value template = quik.Template('#if ( !@v )yes#end') self.assertEqual('yes', template.render({'v': BooleanValue(False)})) self.assertEqual('', template.render({'v': BooleanValue(True)}))
def test_merge_to_stream(self): template = quik.Template('Hello @name!') try: from cStringIO import StringIO except ImportError: from io import StringIO output = StringIO() template.merge_to({"name": "Chris"}, output) self.assertEqual('Hello Chris!', output.getvalue())
def test_velocity_style_escaping(self): template = quik.Template('''\ #set @email = "foo" : @email \\@email \\\\@email \\\\\\@email''') self.assertEqual('''\ foo @email \\foo \\@email''', template.render({}))
def test_user_defined_directive(self): class DummyDirective(quik._Element): PLAIN = re.compile(r'#(monkey)man(.*)$', re.S + re.I) def parse(self): self.text, = self.identity_match(self.PLAIN) def evaluate(self, stream, namespace, loader): stream.write(self.text) quik.UserDefinedDirective.DIRECTIVES.append(DummyDirective) template = quik.Template("hello #monkeyman") self.assertEqual('hello monkey', template.render({})) quik.UserDefinedDirective.DIRECTIVES.remove(DummyDirective)
def test_when_if_statement_resolves_to_true_the_content_is_returned(self): template = quik.Template("Hello #if (@name)your name is @{name}#end Good to see you") self.assertEqual("Hello your name is Steve Good to see you", template.render({"name": "Steve"}))
def test_when_if_statement_resolves_to_false_the_content_is_skipped(self): template = quik.Template("Hello #if (@show_greeting)your name is @{name}#end Good to see you") self.assertEqual("Hello Good to see you", template.render({"name": "Steve", "show_greeting": False}))
def test_can_return_value_from_an_attribute_of_a_context_object(self): template = quik.Template("Hello @name.first_name") class MyObj: pass o = MyObj() o.first_name = 'Chris' self.assertEqual("Hello Chris", template.render({"name": o}))
def test_can_return_value_from_a_method_of_a_context_object(self): template = quik.Template("Hello @name.first_name()") class MyObj: def first_name(self): return "Chris" self.assertEqual("Hello Chris", template.render({"name": MyObj()}))
def test_addition_has_higher_precedence_than_comparison_other_direction(self): template = quik.Template('#set @a = 5 + 4 > 2:@a') self.assertEqual('True', template.render({}))
def test_accepts_dollar_digit_identifiers(self): template = quik.Template('@Something@0') self.assertEqual("@Something@0", template.render({}))
def test_unmatched_trailing_brace_preserved(self): template = quik.Template("Hello @name}.") self.assertEqual("Hello World}.", template.render({"name": "World"}))
def test_expressions_with_numbers_with_fractions(self): template = quik.Template('#set @a = 100.0 / 50:@a') self.assertEqual('2.0', template.render({}))
def test_subobject_assignment(self): template = quik.Template("#set @outer.inner = 'monkey':") x = {'outer':{}} template.render(x) self.assertEqual('monkey', x['outer']['inner'])
def test_if_whitespace_and_newlines_ignored(self): template = quik.Template('''#if(true) hello## #end''') self.assertEqual('hello', template.render({}))
def test_macro_whitespace_and_newlines_ignored(self): template = quik.Template('''#macro blah: hello## #end #blah :''') self.assertEqual('hello', template.render({}))
def test_parse_empty_dictionary(self): template = quik.Template('#set @a = {}:@a') self.assertEqual('{}', template.render({}))
def test_multiplication_has_higher_precedence_than_addition(self): template = quik.Template("#set @a = 5 * 4 - 2:@a") self.assertEqual('18', template.render({}))