Ticket #6271: 6271.diff

File 6271.diff, 9.5 KB (added by gwilson, 7 years ago)
  • django/utils/text.py

     
    196196    return str(ustring_re.sub(fix, s))
    197197javascript_quote = allow_lazy(javascript_quote, unicode)
    198198
    199 smart_split_re = re.compile('("(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'|[^\\s]+)')
     199smart_split_re = re.compile('([^"\\\\ ]*"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"[^"\\\\ ]*'
     200                            "|[^'\\\\ ]*'(?:[^'\\\\]*(?:\\\\.[^'\\\\]*)*)'[^'\\\\ ]*"
     201                            '|[^\\s]+)')
    200202def smart_split(text):
    201203    """
    202204    Generator that splits a string by spaces, leaving quoted phrases together.
  • django/template/defaulttags.py

     
    160160    def __init__(self, nodelist, *varlist):
    161161        self.nodelist = nodelist
    162162        self._last_seen = None
    163         self._varlist = map(Variable, varlist)
     163        self._varlist = varlist
    164164
    165165    def render(self, context):
    166166        if 'forloop' in context and context['forloop']['first']:
     
    611611        ==========================  ================================================
    612612
    613613    """
    614     bits = token.contents.split()
     614    bits = token.split_contents()
    615615    if len(bits) < 4:
    616616        raise TemplateSyntaxError("'for' statements should have at least four"
    617617                                  " words: %s" % token.contents)
     
    635635do_for = register.tag("for", do_for)
    636636
    637637def do_ifequal(parser, token, negate):
    638     bits = list(token.split_contents())
     638    bits = token.split_contents()
    639639    if len(bits) != 3:
    640640        raise TemplateSyntaxError, "%r takes two arguments" % bits[0]
    641641    end_tag = 'end' + bits[0]
     
    799799                {% endifchanged %}
    800800            {% endfor %}
    801801    """
    802     bits = token.contents.split()
     802    bits = token.split_contents()
    803803    nodelist = parser.parse(('endifchanged',))
    804804    parser.delete_first_token()
    805     return IfChangedNode(nodelist, *bits[1:])
     805    return IfChangedNode(nodelist, *[parser.compile_filter(bit) for bit in bits[1:]])
    806806ifchanged = register.tag(ifchanged)
    807807
    808808#@register.tag
     
    923923        {% regroup people|dictsort:"gender" by gender as grouped %}
    924924
    925925    """
    926     bits = token.contents.split()
     926    bits = token.split_contents()
    927927    if len(bits) != 6:
    928928        raise TemplateSyntaxError, "'regroup' tag takes five arguments"
    929929    target = parser.compile_filter(bits[1])
     
    10881088            {{ total }} object{{ total|pluralize }}
    10891089        {% endwith %}
    10901090    """
    1091     bits = list(token.split_contents())
     1091    bits = token.split_contents()
    10921092    if len(bits) != 4 or bits[2] != "as":
    10931093        raise TemplateSyntaxError("%r expected format is 'value as name'" %
    10941094                                  bits[0])
  • tests/regressiontests/templates/tests.py

     
    88
    99import os
    1010import unittest
    11 from datetime import datetime, timedelta
     11from datetime import datetime, date
    1212
    1313from django import template
    1414from django.template import loader
     
    922922            # implementation details (fortunately, the (no)autoescape block
    923923            # tags can be used in those cases)
    924924            'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
     925           
     926            ### Tags using a filtered argument that is passed an argument #####
     927            ### with a space (see #6271). #####################################
     928            'argfilter01': ('{% regroup data by bar|date:"F Y" as grouped %}' + \
     929                            '{% for group in grouped %}' + \
     930                                '{{ group.grouper }}:' + \
     931                                '{% for item in group.list %}' + \
     932                                    '{{ item.foo }}' + \
     933                                '{% endfor %},' + \
     934                            '{% endfor %}',
     935                            {'data': [{'foo':'c', 'bar':datetime(2000,1,1)},
     936                                      {'foo':'d', 'bar':datetime(2000,1,1)},
     937                                      {'foo':'a', 'bar':datetime(2000,2,1)},
     938                                      {'foo':'b', 'bar':datetime(2000,2,1)},
     939                                      {'foo':'x', 'bar':datetime(2000,3,1)} ]},
     940                            'January 2000:cd,February 2000:ab,March 2000:x,'),
     941# The firstof, if, ifequal, and ifnotequal tags need some more work to accept
     942# arguments with filters.
     943#            'argfilter02': ('{% firstof date|date:"F Y" "text" %}',
     944#                            {'date': date(2007, 6, 2)}, 'June 2007'),
     945#            # This test fails when TEMPLATE_STRING_IF_INVALID='INVALID'
     946#            #'argfilter03': ('{% firstof date|date:"F Y" "text" %}',
     947#            #                {}, 'text'),
     948#            'argfilter04': ('{% firstof "text" date|date:"F Y" %}',
     949#                            {'date': date(2007, 6, 2)}, 'text'),
     950#            'argfilter05': ('{% for letter in date|date:"F Y" %}{{ letter }}-{% endfor %}',
     951#                            {'date': date(2007, 6, 2)}, 'J-u-n-e- -2-0-0-7-'),
     952#            'argfilter06': ('{% ifequal date|date:"F Y" "June 2007" %}equal{% endifequal %}',
     953#                            {'date': date(2007, 6, 2)}, 'equal'),
     954#            'argfilter07': ('{% ifnotequal date|date:"F Y" "June 2008" %}notequal{% endifnotequal %}',
     955#                            {'date': date(2007, 6, 2)}, 'notequal'),
     956#            'argfilter08': ('{% if date|date:"F Y" %}true{% endif %}',
     957#                            {'date': date(2007, 6, 2)}, 'true'),
     958#            'argfilter09': ('{% if date|date:"F Y" %}{% else %}false{% endif %}',
     959#                            {}, 'false'),
     960            'argfilter10': ('{% for date in data %}{% ifchanged date|date:"F Y" %}changed{% endifchanged %}{% endfor %}',
     961                            {'data': [date(2007, 6, 2),
     962                                      date(2007, 6, 10),
     963                                      date(2007, 12, 30),
     964                                      date(2007, 12, 31),
     965                                      ]},
     966                            'changedchanged'),
     967            'argfilter11': ('{% with date|date:"F Y" as formatted_date %}{{ formatted_date }}{% endwith %}',
     968                            {'date': date(2007, 6, 2)}, 'June 2007'),
    925969        }
    926970
    927971if __name__ == "__main__":
  • tests/regressiontests/utils/tests.py

     
    44
    55from unittest import TestCase
    66
    7 from django.utils import html, checksums
     7from django.utils import html, checksums, text
    88
    99import timesince
    1010import datastructures
     
    1515    'datastructures': datastructures,
    1616}
    1717
    18 class TestUtilsHtml(TestCase):
    1918
     19class UtilsTestCase(TestCase):
     20   
    2021    def check_output(self, function, value, output=None):
    2122        """
    2223        Check that function(value) equals output.  If output is None,
     
    2627            output = value
    2728        self.assertEqual(function(value), output)
    2829
     30    def check_generator_output(self, function, value, output=None):
     31        """
     32        Check that list(function(value)) equals output.  If output is None,
     33        check that list(function(value)) equals value.
     34        """
     35        if output is None:
     36            output = value
     37        self.assertEqual(list(function(value)), output)
     38
     39class TestUtilsText(UtilsTestCase):
     40
     41    def test_smart_split(self):
     42        f = text.smart_split
     43        items = (
     44            # Double quotes.
     45            ('arg1 arg2|filter:"1" arg3', ['arg1', 'arg2|filter:"1"', 'arg3']),
     46            ('arg1 arg2|filter:"1 2" arg3', ['arg1', 'arg2|filter:"1 2"', 'arg3']),
     47            ('arg1 arg2|filter:"1  2" arg3', ['arg1', 'arg2|filter:"1  2"', 'arg3']),
     48            ('arg1 arg2|filter:"1\t2" arg3', ['arg1', 'arg2|filter:"1\t2"', 'arg3']),
     49            #('arg1 arg2|filter:"1\"1" arg3', ['arg1', 'arg2|filter:"1"1', 'arg3']),
     50            # Singe quotes.
     51            ("arg1 arg2|filter:'1' arg3", ['arg1', "arg2|filter:'1'", 'arg3']),
     52            ("arg1 arg2|filter:'1 2' arg3", ['arg1', "arg2|filter:'1 2'", 'arg3']),
     53            ("arg1 arg2|filter:'1  2' arg3", ['arg1', "arg2|filter:'1  2'", 'arg3']),
     54            ("arg1 arg2|filter:'1\t2' arg3", ['arg1', "arg2|filter:'1\t2'", 'arg3']),
     55        )
     56        for value, output in items:
     57            self.check_generator_output(f, value, output)
     58
     59
     60class TestUtilsHtml(UtilsTestCase):
     61
    2962    def test_escape(self):
    3063        f = html.escape
    3164        items = (
     
    123156        for value, output in items:
    124157            self.check_output(f, value, output)
    125158
    126 class TestUtilsChecksums(TestCase):
     159class TestUtilsChecksums(UtilsTestCase):
    127160
    128     def check_output(self, function, value, output=None):
    129         """
    130         Check that function(value) equals output.  If output is None,
    131         check that function(value) equals value.
    132         """
    133         if output is None:
    134             output = value
    135         self.assertEqual(function(value), output)
    136 
    137161    def test_luhn(self):
    138162        f = checksums.luhn
    139163        items = (
Back to Top