Skip to content

Commit

Permalink
* Run functional tests from "make test"
Browse files Browse the repository at this point in the history
* Clean up the output from all test suites
* New README file
* Remove create_parser stuff because "make" handles this
* Make erlydtl:compile/2,3 a wrapper for erlydtl_compiler:compile/2,3
  • Loading branch information
evanmiller committed Aug 7, 2008
1 parent e171756 commit 7a2813e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 93 deletions.
3 changes: 2 additions & 1 deletion Makefile
Expand Up @@ -15,8 +15,9 @@ run:


test: test:
$(ERL) -noshell -pa ebin \ $(ERL) -noshell -pa ebin \
-s erlydtl_unittests run_tests \ -s erlydtl_functional_tests run_tests \
-s erlydtl_dateformat_tests run_tests \ -s erlydtl_dateformat_tests run_tests \
-s erlydtl_unittests run_tests \
-s init stop -s init stop


clean: clean:
Expand Down
79 changes: 79 additions & 0 deletions README
@@ -0,0 +1,79 @@
ErlyDTL
=======

ErlyDTL implements most but not all of the Django Template Language.

Project homepage: http://code.google.com/p/erlydtl/


Compilation
-----------

To compile ErlyDTL, type "make" in this directory.


Template compilation
--------------------

Four ways:

erlydtl:compile("/path/to/template.dtl", my_module_name)

erlydtl:compile("/path/to/template.dtl", my_module_name, Options)

erlydtl:compile(<<"<html>{{ foo }}</html>">>, my_module_name)

erlydtl:compile(<<"<html>{{ foo }}</html>">>, my_module_name, Options)

Options is a proplist possibly containing:

doc_root - Included template paths will be relative to this directory;
defaults to the compiled template's directory.

custom_tags_dir - Directory of DTL files (no extension) includable as tags.
E.g. if $custom_tags_dir/foo contains "<b>{{ bar }}</b>", then
"{{ foo bar=100 }}" will evaluate to "<b>100</b>". Get it?

vars - Variables (and their values) to evaluate at compile-time rather than
render-time.

reader - {module, function} tuple that takes a path to a template and returns
a binary with the file contents. Defaults to {file, read_file}. Useful
for reading templates from a network resource.

compiler_options - Proplist passed directly to compiler:forms/2

force_recompile - Recompile the module even if the source's checksum has not
changed. Useful for debugging.


Usage (of a compiled template)
------------------------------

my_compiled_template:render(Variables) -> {ok, IOList} | {error, Err}

Variables is a proplist, dict, gb_tree, or a parameterized module
(whose method names correspond to variable names). The variable
values can be atoms, strings, binaries, or (nested) variables.

IOList is the rendered template.

my_compiled_template:source() -> {FileName, CheckSum}

Name and checksum of the original template file.

my_compiled_template:dependencies() -> [{FileName, CheckSum}]

List of names/checksums of templates included by the original template
file. Useful for frameworks that recompile a template only when the
template's dependencies change.


Tests
-----

From a Unix shell, run:

make test

Note that the tests will create some output in examples/rendered_output.
60 changes: 6 additions & 54 deletions src/erlydtl/erlydtl.erl
Expand Up @@ -4,8 +4,7 @@
%%% @author Evan Miller <emmiller@gmail.com> %%% @author Evan Miller <emmiller@gmail.com>
%%% @copyright 2008 Roberto Saccon, Evan Miller %%% @copyright 2008 Roberto Saccon, Evan Miller
%%% @doc %%% @doc
%%% Helper module to start and stop ErlyDTL application and for %%% Public interface for ErlyDTL
%%% creating yecc-grammar based template parser
%%% @end %%% @end
%%% %%%
%%% The MIT License %%% The MIT License
Expand Down Expand Up @@ -37,57 +36,10 @@
-author('emmiller@gmail.com'). -author('emmiller@gmail.com').


%% API %% API
-export([create_parser/0, parser_src/0]). -export([compile/2, compile/3]).


%% -------------------------------------------------------------------- compile(FileOrBinary, Module) ->
%% Definitions erlydtl_compiler:compile(FileOrBinary, Module).
%% --------------------------------------------------------------------
-define(PRINT_ERR_WARNS, [report_warnings, report_errors]).



compile(FileOrBinary, Module, Options) ->
%%-------------------------------------------------------------------- erlydtl_compiler:compile(FileOrBinary, Module, Options).
%% @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
%%====================================================================

create_parser(Path, Outdir) ->
case yecc:file(Path) of
{ok, _} ->
compile_parser(Path, Outdir);
_ ->
{error, "yecc parser generation failed"}
end.


compile_parser(Path, Outdir) ->
case compile:file(Path, ?PRINT_ERR_WARNS ++ [{outdir, Outdir}]) of
{ok, Bin} ->
code:purge(Bin),
case code:load_file(Bin) of
{module, _} ->
ok;
_ ->
{error, "yecc parser reload failed"}
end;
_ ->
{error, "yecc parser compilation failed"}
end.
13 changes: 8 additions & 5 deletions src/tests/erlydtl_dateformat_tests.erl
Expand Up @@ -5,7 +5,8 @@
-define(DISPLAY_PASSES, false). -define(DISPLAY_PASSES, false).


run_tests() -> run_tests() ->
test_group_runner([ io:format("Running date format tests...~n"),
Failures = test_group_runner([
{ {
"date 1", "date 1",
{1979, 7, 8}, % just a date {1979, 7, 8}, % just a date
Expand Down Expand Up @@ -155,19 +156,21 @@ run_tests() ->
{ "Ordinal suffix 22", {1984,1,121}, [{"S", "st"}] } { "Ordinal suffix 22", {1984,1,121}, [{"S", "st"}] }
]), ]),


io:format("Date format failures: ~p~n~n", [Failures]),

ok. ok.


test_group_runner([]) -> ok; test_group_runner([]) -> 0;
test_group_runner([{Info, DateParam, Tests} | Rest]) -> test_group_runner([{Info, DateParam, Tests} | Rest]) ->
io:format("Running ~p -> ", [Info]), io:format(" Test ~p -> ", [Info]),
PassCount = test_runner(DateParam, Tests), PassCount = test_runner(DateParam, Tests),
case PassCount =:= length(Tests) of case PassCount =:= length(Tests) of
true -> true ->
io:format("Passed ~p/~p~n", [PassCount, length(Tests)]); io:format("Passed ~p/~p~n", [PassCount, length(Tests)]);
_ -> _ ->
io:format("~nFailed ~p/~p~n", [length(Tests) - PassCount, length(Tests)]) io:format("~nFailed ~p/~p~n", [length(Tests) - PassCount, length(Tests)])
end, end,
test_group_runner(Rest). test_group_runner(Rest) + length(Tests) - PassCount.


test_runner(DateParam, Tests) -> test_runner(DateParam, Tests) ->
test_runner(DateParam, Tests, 1, 0). test_runner(DateParam, Tests, 1, 0).
Expand All @@ -184,6 +187,6 @@ is(TestNum, Text, Input1, Input2) when Input1 =:= Input2, ?DISPLAY_PASSES ->
is(_TestNum, _Text, Input1, Input2) when Input1 =:= Input2 -> is(_TestNum, _Text, Input1, Input2) when Input1 =:= Input2 ->
1; 1;
is(TestNum, Text, Input1, Input2) -> is(TestNum, Text, Input1, Input2) ->
io:format("~nnot ok ~p - ~s~n got : ~p~n expcted : ~p", [ io:format("~nnot ok ~p - ~s~n got : ~p~n expected : ~p", [
TestNum, Text, Input1, Input2]), TestNum, Text, Input1, Input2]),
0. 0.
41 changes: 12 additions & 29 deletions src/tests/erlydtl_functional_tests.erl
Expand Up @@ -178,43 +178,26 @@ setup(_) ->




run_tests() -> run_tests() ->
case maybe_create_parser() of io:format("Running functional tests...~n"),
ok -> case fold_tests() of
case fold_tests() of {N, []}->
{N, []}-> Msg = lists:concat(["All ", N, " functional tests passed~n~n"]),
Msg = lists:concat(["All ", N, " functional tests passed"]), io:format(Msg),
{ok, Msg}; {ok, Msg};
{_, Errs} -> {_, Errs} ->
io:format("Errors: ~p~n",[Errs]), io:format("Errors: ~p~n~n",[Errs]),
failed failed
end;
Err ->
Err
end. end.




run_test(Name) -> run_test(Name) ->
case maybe_create_parser() of test_compile_render(filename:join([templates_docroot(), Name])).
ok ->
test_compile_render(filename:join([templates_docroot(), Name]));
Err ->
Err
end.




%%==================================================================== %%====================================================================
%% Internal functions %% Internal functions
%%==================================================================== %%====================================================================


maybe_create_parser() ->
case filelib:is_regular(erlydtl:parser_src()) of
ok ->
ok;
_ ->
erlydtl:create_parser()
end.


fold_tests() -> fold_tests() ->
filelib:fold_files(templates_docroot(), "^[^\.].+", false, filelib:fold_files(templates_docroot(), "^[^\.].+", false,
fun fun
Expand All @@ -236,8 +219,8 @@ test_compile_render(File) ->
Options = [ Options = [
{vars, CompileVars}, {vars, CompileVars},
{force_recompile, true}], {force_recompile, true}],
io:format("Template: ~p, ... compiling ... ", [Name]), io:format(" Template: ~p, ... compiling ... ", [Name]),
case erlydtl_compiler:compile(File, Module, Options) of case erlydtl:compile(File, Module, Options) of
ok -> ok ->
case CompileStatus of case CompileStatus of
ok -> test_render(File, list_to_atom(Module), RenderStatus, RenderVars); ok -> test_render(File, list_to_atom(Module), RenderStatus, RenderVars);
Expand Down
8 changes: 4 additions & 4 deletions src/tests/erlydtl_unittests.erl
Expand Up @@ -315,11 +315,12 @@ tests() ->
]. ].


run_tests() -> run_tests() ->
io:format("Running unit tests...~n"),
Failures = lists:foldl( Failures = lists:foldl(
fun({Group, Assertions}, GroupAcc) -> fun({Group, Assertions}, GroupAcc) ->
io:format("Running test group ~p...~n", [Group]), io:format(" Test group ~p...~n", [Group]),
lists:foldl(fun({Name, DTL, Vars, Output}, Acc) -> lists:foldl(fun({Name, DTL, Vars, Output}, Acc) ->
case erlydtl_compiler:compile(DTL, erlydtl_running_test, []) of case erlydtl:compile(DTL, erlydtl_running_test, []) of
{ok, _} -> {ok, _} ->
{ok, IOList} = erlydtl_running_test:render(Vars), {ok, IOList} = erlydtl_running_test:render(Vars),
{ok, IOListBin} = erlydtl_running_test:render(vars_to_binary(Vars)), {ok, IOListBin} = erlydtl_running_test:render(vars_to_binary(Vars)),
Expand All @@ -340,8 +341,7 @@ run_tests() ->
end, GroupAcc, Assertions) end, GroupAcc, Assertions)
end, [], tests()), end, [], tests()),


io:format("Failures: ~p~n", [Failures]), io:format("Unit test failures: ~p~n", [Failures]).
erlang:halt().


vars_to_binary(Vars) when is_list(Vars) -> vars_to_binary(Vars) when is_list(Vars) ->
lists:map(fun lists:map(fun
Expand Down

0 comments on commit 7a2813e

Please sign in to comment.