Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Changes to the add filter #38

Merged
merged 3 commits into from

2 participants

@srstrong

The previous add filter only supported numbers, whereas the django spec indicates that the values will be coerced to numbers, and if that fails added anyway (i.e., string/list concatenation). The change is slightly messy, but I believe is at least closer to the spec.

@evanmiller
Owner

Hmm, OK. This behavior is poor API design but that is the fault of the Django spec. Please add unit tests (tests/src/erlydtl_unittests.erl) and I will merge this in.

@srstrong

Agreed on the API design! I've added in unit tests for the various combinations, let me know if there's anything else you need. Great library, BTW :)

@evanmiller evanmiller merged commit 8797a29 into erlydtl:master
@evanmiller
Owner

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 67 additions and 10 deletions.
  1. +46 −7 src/erlydtl_filters.erl
  2. +21 −3 tests/src/erlydtl_unittests.erl
View
53 src/erlydtl_filters.erl
@@ -152,13 +152,52 @@
-define(SECONDS_PER_MONTH, (30 * ?SECONDS_PER_DAY)).
-define(SECONDS_PER_YEAR, (365 * ?SECONDS_PER_DAY)).
-%% @doc Adds a number to the value.
-add(Input, Number) when is_binary(Input) ->
- list_to_binary(add(binary_to_list(Input), Number));
-add(Input, Number) when is_list(Input) ->
- integer_to_list(add(list_to_integer(Input), Number));
-add(Input, Number) when is_integer(Input) ->
- Input + Number.
+%% @doc Adds to values
+add(LHS, RHS) when is_number(LHS), is_number(RHS) ->
+ LHS + RHS;
+add(LHS, RHS) when is_binary(LHS) ->
+ add(binary_to_list(LHS), RHS);
+add(LHS, RHS) when is_binary(RHS) ->
+ add(LHS, binary_to_list(RHS));
+add(LHS, RHS) when is_list(LHS), is_list(RHS) ->
+ case {to_numeric(LHS), to_numeric(RHS)} of
+ {{number, LHSNum}, {number, RHSNum}} ->
+ LHSNum + RHSNum;
+ _ ->
+ LHS ++ RHS
+ end;
+add(LHS, RHS) when is_list(LHS), is_number(RHS) ->
+ case to_numeric(LHS) of
+ {number, LHSNum} ->
+ LHSNum + RHS;
+ _ ->
+ LHS ++ to_string(RHS)
+ end;
+add(LHS, RHS) when is_number(LHS), is_list(RHS) ->
+ case to_numeric(RHS) of
+ {number, RHSNum} ->
+ LHS + RHSNum;
+ _ ->
+ to_string(LHS) ++ RHS
+ end.
+
+to_string(Num) when is_integer(Num) ->
+ integer_to_list(Num);
+to_string(Num) when is_float(Num) ->
+ float_to_list(Num).
+
+to_numeric(List) ->
+ try
+ {number, list_to_integer(List)}
+ catch
+ error:badarg ->
+ try
+ {number, list_to_float(List)}
+ catch
+ error:badarg ->
+ undefined
+ end
+ end.
%% @doc Adds slashes before quotes.
addslashes(Input) when is_binary(Input) ->
View
24 tests/src/erlydtl_unittests.erl
@@ -366,9 +366,27 @@ tests() ->
{"Escape is applied last",
<<"{{ var1|escape|linebreaksbr }}">>, [{var1, <<"\n">>}],
<<"&lt;br /&gt;">>},
- {"|add:4",
- <<"{{ one|add:4 }}">>, [{one, "1"}],
- <<"5">>},
+ {"add; lhs number, rhs number",
+ <<"{{ one|add:4}}">>, [{one, 1}],
+ <<"5">>},
+ {"add; lhs numeric string, rhs number",
+ <<"{{ one|add:4}}">>, [{one, "1"}],
+ <<"5">>},
+ {"add; lhs number, rhs numeric string",
+ <<"{{ one|add:'4'}}">>, [{one, 1}],
+ <<"5">>},
+ {"add; lhs non-numeric string, rhs number",
+ <<"{{ one|add:4}}">>, [{one, "foo"}],
+ <<"foo4">>},
+ {"add; lhs number, rhs non-numeric string",
+ <<"{{ one|add:'foo'}}">>, [{one, 1}],
+ <<"1foo">>},
+ {"add; lhs non-numeric string, rhs non-numeric string",
+ <<"{{ one|add:'bar'}}">>, [{one, "foo"}],
+ <<"foobar">>},
+ {"add; lhs numeric string, rhs numeric string",
+ <<"{{ one|add:'4'}}">>, [{one, "1"}],
+ <<"5">>},
{"|addslashes",
<<"{{ var1|addslashes }}">>, [{var1, "Jimmy's \"great\" meats'n'things"}],
<<"Jimmy\\'s \\\"great\\\" meats\\'n\\'things">>},
Something went wrong with that request. Please try again.