Commits

rsa...@a5195066-8e3e-0410-a82a-05b01b1b9875  committed f5f6d67

added new testsuite

  • Participants
  • Parent commits 3ed8f50

Comments (0)

Files changed (53)

-{"src/erlydtl/*", [debug_info, {d, debug}, {outdir, "ebin"}]}.
-{"src/demo/*", [debug_info, {d, debug}, {outdir, "ebin"}]}.
+{"src/erlydtl/*", [debug_info, {outdir, "ebin"}]}.
+{"src/tests/*", [debug_info, {outdir, "ebin"}]}.
+{"src/demo/*", [debug_info, {outdir, "ebin"}]}.

File src/erlydtl/erlydtl.erl

 -author('emmiller@gmail.com').
 
 %% API
--export([create_parser/0]).
+-export([create_parser/0, parser_src/0]).
 
 %% --------------------------------------------------------------------
 %% Definitions
 %% --------------------------------------------------------------------
--ifdef(debug). 
 -define(PRINT_ERR_WARNS, [report_warnings, report_errors]). 
--else. 
--define(PRINT_ERR_WARNS, []). 
--endif.
 
     
 %%--------------------------------------------------------------------
-%% @spec () -> any()
+%% @spec () ->  Ok::atom() | Err::tuple()
 %% @doc creates the yecc-based ErlyDTL parser
 %% @end 
 %%--------------------------------------------------------------------
 create_parser() ->
     create_parser("src/erlydtl/erlydtl_parser", "ebin").
 
-
+ 
+%%--------------------------------------------------------------------
+%% @spec () -> string()
+%% @doc creates the yecc-based ErlyDTL parser
+%% @end 
+%%--------------------------------------------------------------------   
+parser_src() ->
+    {file, Ebin} = code:is_loaded(?MODULE),
+    filename:join([filename:dirname(filename:dirname(Ebin)), 
+        "src", "erlydtl", "erlydtl_parser.yrl"]).
+    
+         
 %%====================================================================
 %% Internal functions
 %%====================================================================

File src/erlydtl/erlydtl_compiler.erl

 -author('rsaccon@gmail.com').
 -author('emmiller@gmail.com').
 
+%% --------------------------------------------------------------------
+%% Definitions
+%% --------------------------------------------------------------------
+-define(COMPILE_OPTIONS, [verbose, report_errors, report_warnings]).
+
 -export([compile/2, compile/3]).
 
 -record(dtl_context, {
             ok;
         {ok, DjangoParseTree, CheckSum} ->
             try body_ast(DjangoParseTree, Context, #treewalker{}) of
-                {{Ast, Info}, _} ->
-                    case compile:forms(forms(File, Module, Ast, Info, CheckSum), []) of
+                {{Ast, Info}, _} ->                  
+                    CompileOptions = case  proplists:get_value(verbose, Options, false) of
+                        true -> ?COMPILE_OPTIONS;
+                        _ -> []
+                    end,
+                    case compile:forms(forms(File, Module, Ast, Info, CheckSum), CompileOptions) of
                         {ok, Module1, Bin} -> 
                             OutDir = proplists:get_value(out_dir, Options, "ebin"),       
                             BeamFile = filename:join([OutDir, atom_to_list(Module1) ++ ".beam"]),

File src/tests/erlydtl_tests.erl

+%%%-------------------------------------------------------------------
+%%% File:      erlydtl_tests.erl
+%%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
+%%% @author    Evan Miller <emmiller@gmail.com>
+%%% @copyright 2008 Roberto Saccon, Evan Miller
+%%% @doc       ErlyDTS test suite
+%%% @end
+%%%
+%%% The MIT License
+%%%
+%%% Copyright (c) 2007 Roberto Saccon
+%%%
+%%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%%% of this software and associated documentation files (the "Software"), to deal
+%%% in the Software without restriction, including without limitation the rights
+%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%%% copies of the Software, and to permit persons to whom the Software is
+%%% furnished to do so, subject to the following conditions:
+%%%
+%%% The above copyright notice and this permission notice shall be included in
+%%% all copies or substantial portions of the Software.
+%%%
+%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%%% THE SOFTWARE.
+%%%
+%%% @since 2008-02-11 by Roberto Saccon
+%%%-------------------------------------------------------------------
+-module(erlydtl_tests).
+-author('rsaccon@gmail.com').
+-author('emmiller@gmail.com').
+
+
+%% API
+-export([setup/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% @spec (Name::string()) -> {CompileStatus::atom(), PresetVars::List, RenderStatus::atom(), RenderVars::List}
+%% @doc
+%% @end 
+%%--------------------------------------------------------------------
+setup("autoescape") ->
+    CompileVars = [],
+    RenderVars = [{var1, "<b>bold</b>"}],
+    {ok, CompileVars, ok, RenderVars};  
+setup("comment") ->
+    CompileVars = [],
+    RenderVars =[],
+    {ok, CompileVars, ok, RenderVars};   
+setup("extends") ->
+    CompileVars = [],
+    RenderVars = [{base_var, "base-barstring"}, {test_var, "test-barstring"}],
+    {ok, CompileVars, ok, RenderVars};
+setup("filters") ->
+    CompileVars = [],
+    RenderVars = [{'list', ["eins", "zwei", "drei"]}],
+    {ok, CompileVars, ok, RenderVars};
+setup("for") ->
+    CompileVars = [],
+    RenderVars = [{fruit_list, ["apple", "banana", "coconut"]}],
+    {ok, CompileVars, ok, RenderVars};
+setup("for_list") ->
+    CompileVars = [],
+    RenderVars = [{fruit_list, [["apple", "apples", "$1"], ["banana", "bananas", "$2"], ["coconut", "coconuts", "$500"]]}],
+    {ok, CompileVars, ok, RenderVars};
+setup("for_tuple") ->
+    CompileVars = [],
+    RenderVars = [{fruit_list, [{"apple", "apples"}, {"banana", "bananas"}, {"coconut", "coconuts"}]}],
+    {ok, CompileVars, ok, RenderVars};
+setup("for_list_preset") ->
+    CompileVars = [{fruit_list, [["apple", "apples"], ["banana", "bananas"], ["coconut", "coconuts"]]}],
+    RenderVars = [],
+    {ok, CompileVars, ok, RenderVars};
+setup("for_preset") ->
+    CompileVars = [{fruit_list, ["preset-apple", "preset-banana", "preset-coconut"]}],
+    RenderVars = [],
+    {ok, CompileVars, ok, RenderVars};
+setup("for_records") ->
+    CompileVars = [],
+    Link1 = [{name, "Amazon"}, {url, "http://amazon.com"}],
+    Link2 = [{name, "Google"}, {url, "http://google.com"}],
+    Link3 = [{name, "Microsoft"}, {url, "http://microsoft.com"}],
+    RenderVars = [{link_list, [Link1, Link2, Link3]}],
+    {ok, CompileVars, ok, RenderVars};  
+setup("for_records_preset") ->
+    Link1a = [{name, "Amazon (preset)"}, {url, "http://amazon.com"}],
+    Link2a = [{name, "Google (preset)"}, {url, "http://google.com"}],
+    Link3a = [{name, "Microsoft (preset)"}, {url, "http://microsoft.com"}],
+    CompileVars = [{software_links, [Link1a, Link2a, Link3a]}], 
+    Link1b = [{name, "Canon"}, {url, "http://canon.com"}],
+    Link2b = [{name, "Leica"}, {url, "http://leica.com"}],
+    Link3b = [{name, "Nikon"}, {url, "http://nikon.com"}],
+    RenderVars = [{photo_links, [Link1b, Link2b, Link3b]}],
+    {ok, CompileVars, ok, RenderVars};
+setup("include") ->
+    CompileVars = [],
+    RenderVars = [{var1, "foostring1"}, {var2, "foostring2"}],
+    {ok, CompileVars, ok, RenderVars};
+setup("if") ->
+    CompileVars = [],
+    RenderVars = [{var1, "something"}],
+    {ok, CompileVars, ok, RenderVars}; 
+setup("if_preset") ->
+    CompileVars = [{var1, "something"}],
+    RenderVars = [],
+    {ok, CompileVars, ok, RenderVars};   
+setup("ifequal") ->
+    CompileVars = [],
+    RenderVars = [{var1, "foo"}, {var2, "foo"}, {var3, "bar"}],
+    {ok, CompileVars, ok, RenderVars};      
+setup("ifequal_preset") ->
+    CompileVars = [{var1, "foo"}, {var2, "foo"}],
+    RenderVars = [{var3, "bar"}],
+    {ok, CompileVars, ok, RenderVars};   
+setup("ifnotequal") ->
+    CompileVars = [],
+    RenderVars = [{var1, "foo"}, {var2, "foo"}, {var3, "bar"}],
+    {ok, CompileVars, ok, RenderVars};        
+setup("ifnotequal_preset") ->
+    CompileVars = [{var1, "foo"}, {var2, "foo"}],
+    RenderVars = [],
+    {ok, CompileVars, ok, RenderVars}; 
+setup("var") ->
+    CompileVars = [],
+    RenderVars = [{var1, "foostring1"}, {var2, "foostring2"}, {var_not_used, "foostring3"}],
+    {ok, CompileVars, ok, RenderVars};
+setup("var_preset") ->
+    CompileVars = [{preset_var1, "preset-var1"}, {preset_var2, "preset-var2"}],
+    RenderVars = [{var1, "foostring1"}, {var2, "foostring2"}],
+    {ok, CompileVars, ok, RenderVars}; 
+setup("var_error") ->
+    CompileVars = [],
+    RenderVars = [{var1, "foostring1"}],   
+    {ok, CompileVars, error, RenderVars};        
+%% Custom tag
+setup("custom_tag") ->
+    CompileVars  = [],
+    RenderVars = [],
+    {ok, CompileVars, ok, RenderVars};  
+%% Custom tag      
+setup("custom_tag_error") ->
+    CompileVars  = [],
+    RenderVars = [],
+    {error, CompileVars, ignore, RenderVars};
+%% Custom tag        
+setup("custom_call") ->
+    CompileVars  = [],
+    RenderVars = [{var1, "something"}],
+    {ok, CompileVars, ok, RenderVars};        
+setup(_) ->
+    undefined.
+    
+
+
+
+
+
+
+
+
+
+

File src/tests/erlydtl_testsuite.erl

+%%%-------------------------------------------------------------------
+%%% File:      erlydtl_testsuite.erl
+%%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
+%%% @author    Evan Miller <emmiller@gmail.com>
+%%% @copyright 2008 Roberto Saccon, Evan Miller
+%%% @doc       ErlyDTS test suite
+%%% @end
+%%%
+%%% The MIT License
+%%%
+%%% Copyright (c) 2007 Roberto Saccon
+%%%
+%%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%%% of this software and associated documentation files (the "Software"), to deal
+%%% in the Software without restriction, including without limitation the rights
+%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%%% copies of the Software, and to permit persons to whom the Software is
+%%% furnished to do so, subject to the following conditions:
+%%%
+%%% The above copyright notice and this permission notice shall be included in
+%%% all copies or substantial portions of the Software.
+%%%
+%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%%% THE SOFTWARE.
+%%%
+%%% @since 2007-12-14 by Roberto Saccon
+%%%-------------------------------------------------------------------
+-module(erlydtl_testsuite).
+-author('rsaccon@gmail.com').
+-author('emmiller@gmail.com').
+
+
+
+%% API
+-export([run/0, run/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% @spec 
+%% @doc
+%% @end 
+%%--------------------------------------------------------------------
+
+run() ->    
+    case maybe_create_parser() of
+        ok ->
+            case fold_tests("^test_.*", false) of
+                {N, []}->
+                    Msg = lists:concat(["All ", N, " regression tests passed"]),
+                    {ok, Msg};
+                {_, Errs} -> 
+                    {error, Errs}
+            end;
+        Err ->
+            Err
+    end.
+    
+    
+run(Name) ->
+    case maybe_create_parser() of
+        ok ->
+            case fold_tests("^test_" ++ Name ++ "$", true) of
+                {0, _} -> {error, "Test not found: " ++ Name ++ ".js"};
+                {1, []} -> {ok, "Regression test passed"};
+                {1, Errs} -> {error, Errs};
+                {_, _} -> {error, "Testsuite requires different filename for each test"}
+            end;
+        Err ->
+            Err
+    end.
+    
+    
+%%====================================================================
+%% Internal functions
+%%====================================================================
+
+maybe_create_parser() ->
+    case filelib:is_regular(erlydtl:parser_src()) of
+        ok ->
+            ok; 
+        _ ->
+            erlydtl:create_parser()   
+    end.
+    
+
+fold_tests(RegExp, Verbose) ->
+    filelib:fold_files(templates_docroot(), RegExp, true, 
+        fun
+            (File, {AccCount, AccErrs}) ->
+                case test_compile_render(File, Verbose) of
+                    ok -> 
+                        {AccCount + 1, AccErrs};
+                    {error, Reason} -> 
+                        {AccCount + 1, [{File, Reason} | AccErrs]}
+                end
+        end, {0, []}). 
+        
+
+test_compile_render(File, Verbose) ->   
+    Module = filename:rootname(filename:basename(File)),
+	[$t, $e, $s, $t, $_ | Name] = Module,
+	case catch erlydtl_tests:setup(Name) of
+	    {CompileStatus, CompileVars, RenderStatus, RenderVars} ->
+	        Options = [
+	            {vars, CompileVars}, 
+	            {force_recompile, true},
+	            {verbose, Verbose}],
+            case erlydtl_compiler:compile(File, Module, Options) of
+                ok ->
+                    case CompileStatus of
+                        ok -> test_render(File, list_to_atom(Module), RenderStatus, RenderVars);
+                        _ -> {error, "compiling should have failed :" ++ File}
+                    end;
+                Err ->
+                    case CompileStatus of
+                        error ->  ok;
+                        _ -> Err
+                    end
+            end;
+        _ ->
+            {error, "no test clause for found in erlydtl_test.erl"}
+    end.
+ 
+ 
+test_render(File, Module, RenderStatus, Vars) ->   
+    case catch Module:render(Vars) of
+        {ok, Data} -> 
+            case RenderStatus of
+                ok ->
+                    {File, _} = Module:source(),
+                    OutFile = filename:join([templates_outdir(), filename:basename(File)]),
+                    case file:open(OutFile, [write]) of
+                        {ok, IoDev} ->
+                            file:write(IoDev, Data),
+                            file:close(IoDev),
+                            ok;    
+                        Err ->
+                            Err
+                    end;
+                _ ->
+                    {error, "rendering should have failed :" ++ File}
+            end;
+        {'EXIT', _} ->
+            {error, "failed invoking render method:" ++ Module};
+        Err ->
+            case RenderStatus of
+                error ->  ok;
+                _ -> Err
+            end
+    end.   
+        
+        
+templates_docroot() ->
+    {file, Ebin} = code:is_loaded(?MODULE),
+    filename:join([filename:dirname(filename:dirname(Ebin)), "tests", "templates"]).
+    
+templates_outdir() ->   
+    {file, Ebin} = code:is_loaded(?MODULE),
+    filename:join([filename:dirname(filename:dirname(Ebin)), "tests", "out"]).

File tests/out/test_autoescape

+
+    This is escaped: &lt;b&gt;bold&lt;/b&gt;
+    
+    This is not escaped: <b>bold</b>
+
+    This is escaped: &lt;b&gt;bold&lt;/b&gt;
+    
+

File tests/out/test_comment

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test Comment</title>								 
+  </head>
+  <body>
+	
+	bla
+	
+        blue
+        
+        black
+  </body>
+</html>

File tests/out/test_custom_call

+>>>> before custom call tag 'test_comment'
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test Comment</title>								 
+  </head>
+  <body>
+	
+	bla
+	
+        blue
+        
+        black
+  </body>
+</html>
+
+>>>> after custom call tag 'test_comment'
+
+>>>> before custom call tag 'test_if'
+One but not two:  two 
+Two but not one:  one 
+One: 
+None: 
+
+>>>> after custom call tag 'test_if'

File tests/out/test_custom_tag

+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test variable</title>								 
+  </head>
+  <body>
+	before
+	<object id="myvideo" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600">
+	<param name="movie" value="/static/mediaplayer.swf">
+    <param name="allowfullscreen" value="true">
+    <param name="menu" value="false">
+    <param name="flashvars" value="file=/myvid.mp4&image=/mypic.jpg">
+    <!--[if !IE]>-->
+    <object type="application/x-shockwave-flash" data="/static/mediaplayer.swf" width="800" height="620">
+    <param name="allowfullscreen" value="true">
+    <param name="menu" value="false">
+    <param name="flashvars" value="file=/myvid.mp4&image=/mypic.jpg">
+    <!--<![endif]-->
+    <h2>To view the Video:</h2>
+    <p>
+    	<a href="http://www.adobe.com/go/getflashplayer">
+        	<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"alt="Get Adobe Flash player">
+    	</a>
+    </p>
+    <!--[if !IE]>-->
+    </object>
+    <!--<![endif]-->
+</object>
+	after
+  </body>
+</html>

File tests/out/test_extends

+base-barstring
+
+base template
+
+replacing the base title
+
+more of base template
+
+replacing the base content - variable: test-barstring after variable 
+
+end of base template

File tests/out/test_filters

+Capfirst: Capitalized
+
+Centered:
+<pre>
+       center       
+</pre>
+
+Escape JS: \" \'
+
+First letter: f
+
+Fix ampersands: &amp;
+
+Force_escape: &lt;b&gt;&lt;/b&gt;
+
+Joined: 
+
+Last: t
+
+Length: 3
+
+Length is 2?: false
+
+Left adjust: 
+<pre>
+left                
+</pre>
+
+Line breaks: Line 1<br />Line 2<br />Line 3
+
+Lowercase: lowercase
+
+Plus: 2 + 2 = 4
+
+Right adjust:
+<pre>
+               right
+</pre>
+
+Uppercase: UPPERCASE
+
+URL Encode: Let%27s+go%21

File tests/out/test_for

+before
+
+<ul>
+
+<li>1. apple</li>
+
+<li>2. banana</li>
+
+<li>3. coconut</li>
+
+</ul>
+
+after

File tests/out/test_for_list

+
+More than one apple is called "apples". Only $1 each!
+
+More than one banana is called "bananas". Only $2 each!
+
+More than one coconut is called "coconuts". Only $500 each!
+

File tests/out/test_for_list_preset

+
+More than one apple is called "apples".
+
+More than one banana is called "bananas".
+
+More than one coconut is called "coconuts".
+

File tests/out/test_for_preset

+before
+
+<ul>
+
+	<li>preset-apple</li>
+
+	<li>preset-banana</li>
+
+	<li>preset-coconut</li>
+
+</ul>
+
+after

File tests/out/test_for_records

+before
+
+<ul>
+
+	<li><a href="http://amazon.com">Amazon</a></li>
+
+	<li><a href="http://google.com">Google</a></li>
+
+	<li><a href="http://microsoft.com">Microsoft</a></li>
+
+</ul>
+
+after

File tests/out/test_for_records_preset

+before
+
+<ul>
+
+	<li><a href="http://canon.com">Canon</a></li>
+
+	<li><a href="http://leica.com">Leica</a></li>
+
+	<li><a href="http://nikon.com">Nikon</a></li>
+
+</ul>
+
+<ul>
+
+	<li><a href="http://amazon.com">Amazon (preset)</a></li>
+
+	<li><a href="http://google.com">Google (preset)</a></li>
+
+	<li><a href="http://microsoft.com">Microsoft (preset)</a></li>
+
+</ul>
+
+after

File tests/out/test_for_tuple

+
+One apple, two apples!
+
+One banana, two bananas!
+
+One coconut, two coconuts!
+

File tests/out/test_if

+One but not two:  one 
+Two but not one:  two 
+One:  one 
+None: 

File tests/out/test_if_preset

+One but not two:  one 
+Two but not one:  two 
+One:  one 
+None: 

File tests/out/test_ifequal

+
+if: var1="foo" and var2="foo" are equal
+
+
+
+if: var1="foo" and var2="foo" are equal
+
+
+
+
+
+else: var1="foo" and var3="bar" are not equal
+
+
+
+if: "foo" and "foo" are equal
+
+
+
+else: "foo" and "bar" are not equal
+
+
+
+if: 99 and 99 are equal
+
+
+
+else: 77 and 99 are not equal

File tests/out/test_ifequal_preset

+
+if: var1="foo" and var2="foo" are equal
+
+
+
+if: var1="foo" and var2="foo" are equal
+
+
+
+
+
+else: var1="foo" and var3="bar" are not equal
+
+
+
+if: "foo" and "foo" are equal
+
+
+
+else: "foo" and "bar" are not equal
+
+
+
+if: 99 and 99 are equal
+
+
+
+else: 77 and 99 are not equal

File tests/out/test_ifnotequal

+
+
+
+else: var1="foo" and var2="foo" are not equal
+
+
+
+if: var1="foo" and var3="bar" are equal
+
+
+
+if: var1="foo" and var3="bar" are equal
+
+
+
+else: "foo" and "foo" are not equal
+
+
+
+if: "foo" and "bar" are equal
+
+
+
+else: 99 and 99 are not equal
+
+
+
+if: 77 and 99 are equal

File tests/out/test_ifnotequal_preset

+
+
+
+else: var1="foo" and var2="foo" are not equal
+
+
+
+if: var1="foo" and var3="bar" are equal
+
+
+
+if: var1="foo" and var3="bar" are equal
+
+
+
+else: "foo" and "foo" are not equal
+
+
+
+if: "foo" and "bar" are equal
+
+
+
+else: 99 and 99 are not equal
+
+
+
+if: 77 and 99 are equal

File tests/out/test_include

+Including another file: This is included! foostring1
+

File tests/out/test_var

+before varriable1
+foostring1
+after variable1
+foostring2
+after variable2 (HTML-comment-wrapped)

File tests/out/test_var_preset

+one
+foostring1
+two
+preset-var1
+three
+foostring2
+four
+preset-var2
+five

File tests/templates/base

+{{ base_var }}
+
+base template
+
+{% block title %}base title{% endblock %}
+
+more of base template
+
+{% block content %}base content{% endblock %}
+
+end of base template

File tests/templates/include

+This is included! {{ var1 }}

File tests/templates/test_autoescape

+{% autoescape on %}
+    This is escaped: {{ var1 }}
+    {% autoescape off %}
+    This is not escaped: {{ var1 }}
+
+    This is escaped: {{ var1|escape }}
+    {% endautoescape %}
+{% endautoescape %}

File tests/templates/test_comment

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test Comment</title>								 
+  </head>
+  <body>
+	{# comment1 #}
+	bla
+	{# comment2 #}
+        blue
+        {% comment %}
+        Block Comment
+        {% endcomment %}
+        black
+  </body>
+</html>

File tests/templates/test_custom_call

+>>>> before custom call tag 'test_comment'
+{% call test_comment %}
+>>>> after custom call tag 'test_comment'
+
+>>>> before custom call tag 'test_if'
+{% call test_if with var1 %}
+>>>> after custom call tag 'test_if'

File tests/templates/test_custom_tag

+{% load flashvideo %}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test variable</title>								 
+  </head>
+  <body>
+	before
+	{% flashvideo dom_id="myvideo" width="800" height="600" static="/static" path_to_video="/myvid.mp4" path_to_preview_image="/mypic.jpg" %}
+	after
+  </body>
+</html>

File tests/templates/test_custom_tag_error

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test variable</title>								 
+  </head>
+  <body>
+	before
+	{% flashvideo dom_id="myvideo" width="800" height="600" static="/static" path_to_video="/myvid.mp4" path_to_preview_image="/mypic.jpg" %}
+	after
+  </body>
+</html>

File tests/templates/test_extends

+{% extends "base" %}
+{% block title %}replacing the base title{% endblock %}
+{% block content %}replacing the base content - variable: {{ test_var }} after variable {% endblock %}

File tests/templates/test_filters

+Capfirst: {{ "capitalized"|capfirst }}
+
+Centered:
+<pre>
+{{ "center"|center:20 }}
+</pre>
+
+Escape JS: {{ "\" '"|escapejs }}
+
+First letter: {{ "first"|first }}
+
+Fix ampersands: {{ "&"|fix_ampersands }}
+
+Force_escape: {{ "<b></b>"|force_escape }}
+
+Joined: {{ list|join:", " }}
+
+Last: {{ "last"|last }}
+
+Length: {{ list|length }}
+
+Length is 2?: {{ list|length_is:2 }}
+
+Left adjust: 
+<pre>
+{{ "left"|ljust:20 }}
+</pre>
+
+Line breaks: {{ "Line 1\nLine 2\nLine 3"|linebreaksbr }}
+
+Lowercase: {{ "LOWERCASE"|lower }}
+
+Plus: 2 + 2 = {{ 2|plus:2 }}
+
+Right adjust:
+<pre>
+{{ "right"|rjust:20 }}
+</pre>
+
+Uppercase: {{ "uppercase"|upper }}
+
+URL Encode: {{ "Let's go!"|urlencode }}

File tests/templates/test_for

+before
+
+<ul>
+{% for iterator in fruit_list %}
+<li>{{ forloop.counter }}. {{ iterator }}</li>
+{% endfor %}
+</ul>
+
+after

File tests/templates/test_for_list

+{% for singular, plural, price in fruit_list %}
+More than one {{ singular }} is called "{{ plural }}". Only {{ price }} each!
+{% endfor %}

File tests/templates/test_for_list_preset

+{% for singular, plural in fruit_list %}
+More than one {{ singular }} is called "{{ plural }}".
+{% endfor %}

File tests/templates/test_for_preset

+before
+
+<ul>
+{% for iterator in fruit_list %}
+	<li>{{ iterator }}</li>
+{% endfor %}
+</ul>
+
+after

File tests/templates/test_for_records

+before
+
+<ul>
+{% for iterator in link_list %}
+	<li><a href="{{ iterator.url }}">{{ iterator.name }}</a></li>
+{% endfor %}
+</ul>
+
+after

File tests/templates/test_for_records_preset

+before
+
+<ul>
+{% for iterator in photo_links %}
+	<li><a href="{{ iterator.url }}">{{ iterator.name }}</a></li>
+{% endfor %}
+</ul>
+
+<ul>
+{% for iterator in software_links %}
+	<li><a href="{{ iterator.url }}">{{ iterator.name }}</a></li>
+{% endfor %}
+</ul>
+
+after

File tests/templates/test_for_tuple

+{% for singular, plural in fruit_list %}
+One {{ singular }}, two {{ plural }}!
+{% endfor %}

File tests/templates/test_if

+One but not two: {% if var1 %} one {% else %} two {% endif %}
+Two but not one: {% if not var1 %} one {% else %} two {% endif %}
+One: {% if var1 %} one {% endif %}
+None: {% if var2 %} one {% endif %}

File tests/templates/test_if_preset

+One but not two: {% if var1 %} one {% else %} two {% endif %}
+Two but not one: {% if not var1 %} one {% else %} two {% endif %}
+One: {% if var1 %} one {% endif %}
+None: {% if var2 %} one {% endif %}

File tests/templates/test_ifequal

+{% ifequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% endifequal %}
+
+{% ifequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% else %}
+else: var1="foo" and var2="foo" are not equal
+{% endifequal %}
+
+{% ifequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% endifequal %}
+
+{% ifequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% else %}
+else: var1="foo" and var3="bar" are not equal
+{% endifequal %}
+
+{% ifequal "foo" "foo" %}
+if: "foo" and "foo" are equal
+{% else %}
+else: "foo" and "foo" are not equal
+{% endifequal %}
+
+{% ifequal "foo" "bar" %}
+if: "foo" and "bar" are equal
+{% else %}
+else: "foo" and "bar" are not equal
+{% endifequal %}
+
+{% ifequal 99 99 %}
+if: 99 and 99 are equal
+{% else %}
+else: 99 and 99 are not equal
+{% endifequal %}
+
+{% ifequal 77 99 %}
+if: 77 and 99 are equal
+{% else %}
+else: 77 and 99 are not equal
+{% endifequal %}

File tests/templates/test_ifequal_preset

+{% ifequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% endifequal %}
+
+{% ifequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% else %}
+else: var1="foo" and var2="foo" are not equal
+{% endifequal %}
+
+{% ifequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% endifequal %}
+
+{% ifequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% else %}
+else: var1="foo" and var3="bar" are not equal
+{% endifequal %}
+
+{% ifequal "foo" "foo" %}
+if: "foo" and "foo" are equal
+{% else %}
+else: "foo" and "foo" are not equal
+{% endifequal %}
+
+{% ifequal "foo" "bar" %}
+if: "foo" and "bar" are equal
+{% else %}
+else: "foo" and "bar" are not equal
+{% endifequal %}
+
+{% ifequal 99 99 %}
+if: 99 and 99 are equal
+{% else %}
+else: 99 and 99 are not equal
+{% endifequal %}
+
+{% ifequal 77 99 %}
+if: 77 and 99 are equal
+{% else %}
+else: 77 and 99 are not equal
+{% endifequal %}

File tests/templates/test_ifnotequal

+{% ifnotequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% else %}
+else: var1="foo" and var2="foo" are not equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% else %}
+else: var1="foo" and var3="bar" are not equal
+{% endifnotequal %}
+
+{% ifnotequal "foo" "foo" %}
+if: "foo" and "foo" are equal
+{% else %}
+else: "foo" and "foo" are not equal
+{% endifnotequal %}
+
+{% ifnotequal "foo" "bar" %}
+if: "foo" and "bar" are equal
+{% else %}
+else: "foo" and "bar" are not equal
+{% endifnotequal %}
+
+{% ifnotequal 99 99 %}
+if: 99 and 99 are equal
+{% else %}
+else: 99 and 99 are not equal
+{% endifnotequal %}
+
+{% ifnotequal 77 99 %}
+if: 77 and 99 are equal
+{% else %}
+else: 77 and 99 are not equal
+{% endifnotequal %}

File tests/templates/test_ifnotequal_preset

+{% ifnotequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var2 %}
+if: var1="foo" and var2="foo" are equal
+{% else %}
+else: var1="foo" and var2="foo" are not equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% endifnotequal %}
+
+{% ifnotequal var1 var3 %}
+if: var1="foo" and var3="bar" are equal
+{% else %}
+else: var1="foo" and var3="bar" are not equal
+{% endifnotequal %}
+
+{% ifnotequal "foo" "foo" %}
+if: "foo" and "foo" are equal
+{% else %}
+else: "foo" and "foo" are not equal
+{% endifnotequal %}
+
+{% ifnotequal "foo" "bar" %}
+if: "foo" and "bar" are equal
+{% else %}
+else: "foo" and "bar" are not equal
+{% endifnotequal %}
+
+{% ifnotequal 99 99 %}
+if: 99 and 99 are equal
+{% else %}
+else: 99 and 99 are not equal
+{% endifnotequal %}
+
+{% ifnotequal 77 99 %}
+if: 77 and 99 are equal
+{% else %}
+else: 77 and 99 are not equal
+{% endifnotequal %}

File tests/templates/test_include

+Including another file: {% include "include" %}

File tests/templates/test_var

+before varriable1
+{{ var1 }}
+after variable1
+<!--{{ var2 }}-->
+after variable2 (HTML-comment-wrapped)

File tests/templates/test_var_error

+before varriable1
+{{ var1 }}
+after variable1
+<!--{{ var2 }}-->
+after variable2 (HTML-comment-wrapped)

File tests/templates/test_var_preset

+one
+{{ var1 }}
+two
+{{ preset_var1 }}
+three
+<!--{{ var2 }}-->
+four
+{{ preset_var2 }}
+five