The sum filter can now sum up attributes
[jinja2.git] / jinja2 / testsuite / filters.py
index ea015e51eed91c7218fd33daa82dd80a7b713b00..6331d76e424dd8c5600c6b62c2fbaa619af700f7 100644 (file)
@@ -204,15 +204,37 @@ class FilterTestCase(JinjaTestCase):
         tmpl = env.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''')
         assert tmpl.render() == '21'
 
+    def test_sum_attributes(self):
+        tmpl = env.from_string('''{{ values|sum('value') }}''')
+        assert tmpl.render(values=[
+            {'value': 23},
+            {'value': 1},
+            {'value': 18},
+        ]) == '42'
+
+    def test_sum_attributes_nested(self):
+        tmpl = env.from_string('''{{ values|sum('real.value') }}''')
+        assert tmpl.render(values=[
+            {'real': {'value': 23}},
+            {'real': {'value': 1}},
+            {'real': {'value': 18}},
+        ]) == '42'
+
     def test_abs(self):
         tmpl = env.from_string('''{{ -1|abs }}|{{ 1|abs }}''')
-        return tmpl.render() == '1|1'
+        assert tmpl.render() == '1|1', tmpl.render()
 
-    def test_round(self):
+    def test_round_positive(self):
         tmpl = env.from_string('{{ 2.7|round }}|{{ 2.1|round }}|'
-                               "{{ 2.1234|round(2, 'floor') }}|"
+                               "{{ 2.1234|round(3, 'floor') }}|"
                                "{{ 2.1|round(0, 'ceil') }}")
-        return tmpl.render() == '3.0|2.0|2.1|3.0'
+        assert tmpl.render() == '3.0|2.0|2.123|3.0', tmpl.render()
+
+    def test_round_negative(self):
+        tmpl = env.from_string('{{ 21.3|round(-1)}}|'
+                               "{{ 21.3|round(-1, 'ceil')}}|"
+                               "{{ 21.3|round(-1, 'floor')}}")
+        assert tmpl.render() == '20.0|30.0|20.0',tmpl.render()
 
     def test_xmlattr(self):
         tmpl = env.from_string("{{ {'foo': 42, 'bar': 23, 'fish': none, "
@@ -228,9 +250,13 @@ class FilterTestCase(JinjaTestCase):
         assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
 
     def test_sort2(self):
-        tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort(false, true)) }}')
+        tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}')
         assert tmpl.render() == 'AbcD'
 
+    def test_sort3(self):
+        tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''')
+        assert tmpl.render() == "['Bar', 'blah', 'foo']"
+
     def test_groupby(self):
         tmpl = env.from_string('''
         {%- for grouper, list in [{'foo': 1, 'bar': 2},
@@ -246,6 +272,32 @@ class FilterTestCase(JinjaTestCase):
             ""
         ]
 
+    def test_groupby_multidot(self):
+        class Date(object):
+            def __init__(self, day, month, year):
+                self.day = day
+                self.month = month
+                self.year = year
+        class Article(object):
+            def __init__(self, title, *date):
+                self.date = Date(*date)
+                self.title = title
+        articles = [
+            Article('aha', 1, 1, 1970),
+            Article('interesting', 2, 1, 1970),
+            Article('really?', 3, 1, 1970),
+            Article('totally not', 1, 1, 1971)
+        ]
+        tmpl = env.from_string('''
+        {%- for year, list in articles|groupby('date.year') -%}
+            {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
+        {%- endfor %}''')
+        assert tmpl.render(articles=articles).split('|') == [
+            '1970[aha][interesting][really?]',
+            '1971[totally not]',
+            ''
+        ]
+
     def test_filtertag(self):
         tmpl = env.from_string("{% filter upper|replace('FOO', 'foo') %}"
                                "foobar{% endfilter %}")
@@ -274,10 +326,6 @@ class FilterTestCase(JinjaTestCase):
         tmpl = env.from_string('{{ "<div>foo</div>" }}')
         assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
 
-    def test_sort2(self):
-        tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''')
-        assert tmpl.render() == "['Bar', 'blah', 'foo']"
-
 
 def suite():
     suite = unittest.TestSuite()