12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547 |
- from __future__ import with_statement
-
- import os
- import sys
- import warnings
- from distutils.version import LooseVersion
- import operator
- from unittest import TestCase
-
- import django
- from django import template
- from django.core.exceptions import ImproperlyConfigured
- from django.template import Context, RequestContext
- from django.test import RequestFactory
-
- from classytags import arguments
- from classytags import core
- from classytags import exceptions
- from classytags import helpers
- from classytags import parser
- from classytags import utils
- from classytags import values
- from classytags.blocks import BlockDefinition
- from classytags.blocks import VariableBlockName
- from classytags.compat import compat_next
- from classytags.test.context_managers import SettingsOverride
- from classytags.test.context_managers import TemplateTags
-
- DJANGO_1_4_OR_HIGHER = (
- LooseVersion(django.get_version()) >= LooseVersion('1.4')
- )
- DJANGO_1_5_OR_HIGHER = (
- LooseVersion(django.get_version()) >= LooseVersion('1.5')
- )
-
- CLASSY_TAGS_DIR = os.path.abspath(os.path.dirname(__file__))
-
-
- class DummyTokens(list):
- def __init__(self, *tokens):
- super(DummyTokens, self).__init__(['dummy_tag'] + list(tokens))
-
- def split_contents(self):
- return self
-
-
- class DummyParser(object):
- @staticmethod
- def compile_filter(token):
- return utils.TemplateConstant(token)
- dummy_parser = DummyParser()
-
-
- class _Warning(object):
- def __init__(self, message, category, filename, lineno):
- self.message = message
- self.category = category
- self.filename = filename
- self.lineno = lineno
-
-
- def _collect_warnings(observe_warning, f, *args, **kwargs):
- def show_warning(message, category, filename, lineno, file=None,
- line=None):
- assert isinstance(message, Warning)
- observe_warning(
- _Warning(message.args[0], category, filename, lineno)
- )
-
- # Disable the per-module cache for every module otherwise if the warning
- # which the caller is expecting us to collect was already emitted it won't
- # be re-emitted by the call to f which happens below.
- for v in sys.modules.values(): # pragma: no cover
- if v is not None:
- try:
- v.__warningregistry__ = None
- except:
- # Don't specify a particular exception type to handle in case
- # some wacky object raises some wacky exception in response to
- # the setattr attempt.
- pass
-
- orig_filters = warnings.filters[:]
- orig_show = warnings.showwarning
- warnings.simplefilter('always')
- try:
- warnings.showwarning = show_warning
- result = f(*args, **kwargs)
- finally:
- warnings.filters[:] = orig_filters
- warnings.showwarning = orig_show
- return result
-
-
- class ClassytagsTests(TestCase):
- def failUnlessWarns(self, category, message, f, *args, **kwargs):
- warnings_shown = []
- result = _collect_warnings(warnings_shown.append, f, *args, **kwargs)
-
- if not warnings_shown: # pragma: no cover
- self.fail("No warnings emitted")
- first = warnings_shown[0]
- for other in warnings_shown[1:]: # pragma: no cover
- if ((other.message, other.category) !=
- (first.message, first.category)):
- self.fail("Can't handle different warnings")
- self.assertEqual(first.message, message)
- self.assertTrue(first.category is category)
-
- return result
- assertWarns = failUnlessWarns
-
- def _tag_tester(self, klass, templates):
- """
- Helper method to test a template tag by rendering it and checkout
- output.
-
- *klass* is a template tag class (subclass of core.Tag)
- *templates* is a sequence of a triple (template-string, output-string,
- context)
- """
-
- tag_message = ("Rendering of template %(in)r resulted in "
- "%(realout)r, expected %(out)r using %(ctx)r.")
-
- with TemplateTags(klass):
- for tpl, out, ctx in templates:
- t = template.Template(tpl)
- c = template.Context(ctx)
- s = t.render(c)
- self.assertEqual(s, out, tag_message % {
- 'in': tpl,
- 'out': out,
- 'ctx': ctx,
- 'realout': s,
- })
- for key, value in ctx.items():
- self.assertEqual(c.get(key), value)
-
- def test_simple_parsing(self):
- """
- Test very basic single argument parsing
- """
- options = core.Options(
- arguments.Argument('myarg'),
- )
- dummy_tokens = DummyTokens('myval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), 'myval')
-
- def test_simple_parsing_too_many_arguments(self):
- options = core.Options(
- arguments.Argument('myarg'),
- )
- dummy_tokens = DummyTokens('myval', 'myval2')
- self.assertRaises(exceptions.TooManyArguments,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_optional_default(self):
- """
- Test basic optional argument parsing
- """
- options = core.Options(
- arguments.Argument('myarg'),
- arguments.Argument('optarg', required=False, default=None),
- )
- dummy_tokens = DummyTokens('myval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 2)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), 'myval')
- self.assertEqual(kwargs['optarg'].resolve(dummy_context), None)
-
- def test_optional_given(self):
- options = core.Options(
- arguments.Argument('myarg'),
- arguments.Argument('optarg', required=False, default=None),
- )
- dummy_tokens = DummyTokens('myval', 'optval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 2)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), 'myval')
- self.assertEqual(kwargs['optarg'].resolve(dummy_context), 'optval')
-
- def test_breakpoints_not_enough_arguments(self):
- """
- Test parsing with breakpoints
- """
- options = core.Options(
- arguments.Argument('myarg'),
- 'as',
- arguments.Argument('varname'),
- 'using',
- arguments.Argument('using'),
- )
- dummy_tokens = DummyTokens('myval')
- self.assertRaises(exceptions.ArgumentRequiredError,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_breakpoint_breakpoint_expected(self):
- options = core.Options(
- arguments.Argument('myarg'),
- 'as',
- arguments.Argument('varname'),
- 'using',
- arguments.Argument('using'),
- )
- dummy_tokens = DummyTokens('myval', 'myname')
- self.assertRaises(exceptions.BreakpointExpected,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_breakpoint_breakpoint_expected_second(self):
- options = core.Options(
- arguments.Argument('myarg'),
- 'as',
- arguments.Argument('varname'),
- 'using',
- arguments.Argument('using'),
- )
- dummy_tokens = DummyTokens('myval', 'as', 'myname', 'something')
- self.assertRaises(exceptions.BreakpointExpected,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_breakpoint_trailing(self):
- options = core.Options(
- arguments.Argument('myarg'),
- 'as',
- arguments.Argument('varname', required=False),
- )
- dummy_tokens = DummyTokens('myval', 'as')
- self.assertRaises(exceptions.TrailingBreakpoint,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_breakpoint_okay(self):
- options = core.Options(
- arguments.Argument('myarg'),
- 'as',
- arguments.Argument('varname'),
- 'using',
- arguments.Argument('using'),
- )
- dummy_tokens = DummyTokens('myval', 'as', 'myname', 'using',
- 'something')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 3)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), 'myval')
- self.assertEqual(kwargs['varname'].resolve(dummy_context), 'myname')
- self.assertEqual(kwargs['using'].resolve(dummy_context), 'something')
-
- def test_flag_true_value(self):
- """
- Test flag arguments
- """
- options = core.Options(
- arguments.Flag('myflag', true_values=['on'], false_values=['off'])
- )
- dummy_tokens = DummyTokens('on')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(kwargs['myflag'].resolve(dummy_context), True)
-
- def test_flag_false_value(self):
- options = core.Options(
- arguments.Flag('myflag', true_values=['on'], false_values=['off'])
- )
- dummy_tokens = DummyTokens('off')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(kwargs['myflag'].resolve(dummy_context), False)
-
- def test_flag_wrong_value(self):
- options = core.Options(
- arguments.Flag('myflag', true_values=['on'], false_values=['off'])
- )
- # test exceptions
- dummy_tokens = DummyTokens('myval')
- self.assertRaises(exceptions.InvalidFlag,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_flag_wrong_value_no_false(self):
- options = core.Options(
- arguments.Flag('myflag', true_values=['on'])
- )
- dummy_tokens = DummyTokens('myval')
- self.assertRaises(exceptions.InvalidFlag,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_flag_wrong_value_no_true(self):
- options = core.Options(
- arguments.Flag('myflag', false_values=['off'])
- )
- dummy_tokens = DummyTokens('myval')
- self.assertRaises(exceptions.InvalidFlag,
- options.parse, dummy_parser, dummy_tokens)
- self.assertRaises(ImproperlyConfigured, arguments.Flag, 'myflag')
-
- def test_case_sensitive_flag_typo(self):
- # test case sensitive flag
- options = core.Options(
- arguments.Flag('myflag', true_values=['on'], default=False,
- case_sensitive=True)
- )
- dummy_tokens = DummyTokens('On')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(kwargs['myflag'].resolve(dummy_context), False)
-
- def test_case_sensitive_flag_okay(self):
- options = core.Options(
- arguments.Flag(
- 'myflag',
- true_values=['on'],
- default=False,
- case_sensitive=True
- )
- )
- dummy_tokens = DummyTokens('on')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(kwargs['myflag'].resolve(dummy_context), True)
-
- def test_multiflag(self):
- # test multi-flag
- options = core.Options(
- arguments.Flag('flagone', true_values=['on'], default=False),
- arguments.Flag('flagtwo', false_values=['off'], default=True),
- )
- dummy_tokens = DummyTokens('On', 'On')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(kwargs['flagone'].resolve(dummy_context), True)
- self.assertEqual(kwargs['flagtwo'].resolve(dummy_context), True)
-
- def test_multi_value_single_value(self):
- """
- Test simple multi value arguments
- """
- options = core.Options(
- arguments.MultiValueArgument('myarg')
- )
- # test single token MVA
- dummy_tokens = DummyTokens('myval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- # test resolving to list
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), ['myval'])
-
- def test_multi_value_two_values(self):
- options = core.Options(
- arguments.MultiValueArgument('myarg')
- )
- # test double token MVA
- dummy_tokens = DummyTokens('myval', 'myval2')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context),
- ['myval', 'myval2'])
-
- def test_multi_value_three_values(self):
- options = core.Options(
- arguments.MultiValueArgument('myarg')
- )
- # test triple token MVA
- dummy_tokens = DummyTokens('myval', 'myval2', 'myval3')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context),
- ['myval', 'myval2', 'myval3'])
-
- def test_multi_value_max_values_single(self):
- # test max_values option
- options = core.Options(
- arguments.MultiValueArgument('myarg', max_values=2)
- )
- dummy_tokens = DummyTokens('myval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context), ['myval'])
-
- def test_multi_value_max_values_double(self):
- options = core.Options(
- arguments.MultiValueArgument('myarg', max_values=2)
- )
- dummy_tokens = DummyTokens('myval', 'myval2')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 1)
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context),
- ['myval', 'myval2'])
-
- def test_multi_value_max_values_too_many(self):
- options = core.Options(
- arguments.MultiValueArgument('myarg', max_values=2)
- )
- dummy_tokens = DummyTokens('myval', 'myval2', 'myval3')
- self.assertRaises(exceptions.TooManyArguments,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_multi_value_no_resolve(self):
- # test no resolve
- options = core.Options(
- arguments.MultiValueArgument('myarg', resolve=False)
- )
- argparser = parser.Parser(options)
- dummy_tokens = DummyTokens('myval', "'myval2'")
- kwargs, blocks = argparser.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context),
- ['myval', 'myval2'])
-
- def test_multi_value_defaults(self):
- # test default
- options = core.Options(
- arguments.MultiValueArgument('myarg', default=['hello', 'world']),
- )
- argparser = parser.Parser(options)
- dummy_tokens = DummyTokens()
- kwargs, blocks = argparser.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- dummy_context = {}
- self.assertEqual(kwargs['myarg'].resolve(dummy_context),
- ['hello', 'world'])
-
- def test_complex_all_arguments(self):
- """
- test a complex tag option parser
- """
- options = core.Options(
- arguments.Argument('singlearg'),
- arguments.MultiValueArgument('multiarg', required=False),
- 'as',
- arguments.Argument('varname', required=False),
- 'safe',
- arguments.Flag('safe', true_values=['on', 'true'], default=False)
- )
- # test simple 'all arguments given'
- dummy_tokens = DummyTokens(1, 2, 3, 'as', 4, 'safe', 'true')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 4)
- expected = [
- ('singlearg', 1),
- ('multiarg', [2, 3]),
- ('varname', 4),
- ('safe', True)
- ]
- for key, value in expected:
- self.assertEqual(kwargs[key].resolve(dummy_context), value)
-
- def test_complex_only_first_argument(self):
- options = core.Options(
- arguments.Argument('singlearg'),
- arguments.MultiValueArgument('multiarg', required=False),
- 'as',
- arguments.Argument('varname', required=False),
- 'safe',
- arguments.Flag('safe', true_values=['on', 'true'], default=False)
- )
- # test 'only first argument given'
- dummy_tokens = DummyTokens(1)
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 4)
- expected = [
- ('singlearg', 1),
- ('multiarg', []),
- ('varname', None),
- ('safe', False)
- ]
- for key, value in expected:
- self.assertEqual(kwargs[key].resolve(dummy_context), value)
-
- def test_complext_first_and_last_argument(self):
- options = core.Options(
- arguments.Argument('singlearg'),
- arguments.MultiValueArgument('multiarg', required=False),
- 'as',
- arguments.Argument('varname', required=False),
- 'safe',
- arguments.Flag('safe', true_values=['on', 'true'], default=False)
- )
- # test first argument and last argument given
- dummy_tokens = DummyTokens(2, 'safe', 'false')
- dummy_context = {}
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 4)
- expected = [
- ('singlearg', 2),
- ('multiarg', []),
- ('varname', None),
- ('safe', False)
- ]
- for key, value in expected:
- self.assertEqual(kwargs[key].resolve(dummy_context), value)
-
- def test_cycle(self):
- """
- This test re-implements django's cycle tag (because it's quite crazy)
- and checks if it works.
- """
- from itertools import cycle as itertools_cycle
-
- class Cycle(core.Tag):
- name = 'classy_cycle'
-
- options = core.Options(
- arguments.MultiValueArgument('values'),
- 'as',
- arguments.Argument('varname', required=False, resolve=False),
- )
-
- def render_tag(self, context, values, varname):
- if self not in context.render_context:
- context.render_context[self] = itertools_cycle(values)
- cycle_iter = context.render_context[self]
- value = compat_next(cycle_iter)
- if varname:
- context[varname] = value
- return value
-
- origtpl = template.Template(
- '{% for thing in sequence %}'
- '{% cycle "1" "2" "3" "4" %}'
- '{% endfor %}'
- )
- sequence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- context = template.Context({'sequence': sequence})
- original = origtpl.render(context)
- with TemplateTags(Cycle):
- classytpl = template.Template(
- '{% for thing in sequence %}'
- '{% classy_cycle "1" "2" "3" "4" %}'
- '{% endfor %}'
- )
- classy = classytpl.render(context)
- self.assertEqual(original, classy)
- origtpl = template.Template(
- '{% for thing in sequence %}'
- '{% cycle "1" "2" "3" "4" as myvarname %}'
- '{% endfor %}'
- )
- sequence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- context = template.Context({'sequence': sequence})
- original = origtpl.render(context)
- with TemplateTags(Cycle):
- classytpl = template.Template(
- '{% for thing in sequence %}'
- '{% classy_cycle "1" "2" "3" "4" as myvarname %}'
- '{% endfor %}'
- )
- classy = classytpl.render(context)
- self.assertEqual(original, classy)
-
- def test_naming(self):
- # test implicit naming
- class MyTag(core.Tag):
- pass
- lib = template.Library()
- lib.tag(MyTag)
- msg = "'my_tag' not in %s" % lib.tags.keys()
- self.assertTrue('my_tag' in lib.tags, msg)
- # test explicit naming
-
- class MyTag2(core.Tag):
- name = 'my_tag_2'
-
- lib = template.Library()
- lib.tag(MyTag2)
- msg = "'my_tag_2' not in %s" % lib.tags.keys()
- self.assertTrue('my_tag_2' in lib.tags, msg)
- # test named registering
- lib = template.Library()
- lib.tag('my_tag_3', MyTag)
- msg = "'my_tag_3' not in %s" % lib.tags.keys()
- self.assertTrue('my_tag_3' in lib.tags, msg)
- msg = "'my_tag' in %s" % lib.tags.keys()
- self.assertTrue('my_tag' not in lib.tags, msg)
- lib = template.Library()
- lib.tag('my_tag_4', MyTag2)
- msg = "'my_tag_4' not in %s" % lib.tags.keys()
- self.assertTrue('my_tag_4' in lib.tags, msg)
- msg = "'my_tag2' in %s" % lib.tags.keys()
- self.assertTrue('my_tag2' not in lib.tags, msg)
-
- def test_hello_world(self):
- class Hello(core.Tag):
- options = core.Options(
- arguments.Argument('name', required=False, default='world'),
- 'as',
- arguments.Argument('varname', required=False, resolve=False)
- )
-
- def render_tag(self, context, name, varname):
- output = 'hello %s' % name
- if varname:
- context[varname] = output
- return ''
- return output
- tpls = [
- ('{% hello %}', 'hello world', {}),
- ('{% hello "classytags" %}', 'hello classytags', {}),
- ('{% hello as myvar %}', '', {'myvar': 'hello world'}),
- ('{% hello "my friend" as othervar %}', '',
- {'othervar': 'hello my friend'})
- ]
- self._tag_tester(Hello, tpls)
-
- def test_filters_in_arguments(self):
- class Filtered(core.Tag):
- options = core.Options(
- arguments.Argument('value'),
- )
-
- def render_tag(self, context, value):
- return value
- tpls = [
- ('{% filtered "hello" %}', 'hello', {}),
- ('{% filtered var %}', 'world', {'var': 'world'}),
- ('{% filtered var|default:"foo" %}', 'foo', {}),
- ]
- self._tag_tester(Filtered, tpls)
-
- def test_filtered_multi_keyword(self):
- class Filtered(core.Tag):
- options = core.Options(
- arguments.MultiKeywordArgument('kwargs'),
- )
-
- def render_tag(self, context, kwargs):
- return '|'.join('%s:%s' % (k, v) for k, v in kwargs.items())
- tpls = [
- ('{% filtered hello="world" %}', 'hello:world', {}),
- ('{% filtered hello=var %}', 'hello:world', {'var': 'world'}),
- ('{% filtered hello=var|default:"foo" %}', 'hello:foo', {}),
- ]
- self._tag_tester(Filtered, tpls)
-
- def test_blocks(self):
- class Blocky(core.Tag):
- options = core.Options(
- blocks=['a', 'b', 'c', 'd', 'e'],
- )
-
- def render_tag(self, context, **nodelists):
- tpl = "%(a)s;%(b)s;%(c)s;%(d)s;%(e)s"
- data = {}
- for key, value in nodelists.items():
- data[key] = value.render(context)
- return tpl % data
- templates = [
- ('{% blocky %}1{% a %}2{% b %}3{% c %}4{% d %}5{% e %}',
- '1;2;3;4;5', {},),
- ('{% blocky %}12{% b %}3{% c %}4{% d %}5{% e %}', '12;;3;4;5',
- {},),
- ('{% blocky %}123{% c %}4{% d %}5{% e %}', '123;;;4;5', {},),
- ('{% blocky %}1234{% d %}5{% e %}', '1234;;;;5', {},),
- ('{% blocky %}12345{% e %}', '12345;;;;', {},),
- ('{% blocky %}1{% a %}23{% c %}4{% d %}5{% e %}', '1;23;;4;5',
- {},),
- ('{% blocky %}1{% a %}23{% c %}45{% e %}', '1;23;;45;', {},),
- ]
- self._tag_tester(Blocky, templates)
-
- def test_astag(self):
- class Dummy(helpers.AsTag):
- options = core.Options(
- 'as',
- arguments.Argument('varname', resolve=False, required=False),
- )
-
- def get_value(self, context):
- return "dummy"
- templates = [
- ('{% dummy %}:{{ varname }}', 'dummy:', {},),
- ('{% dummy as varname %}:{{ varname }}', ':dummy', {},),
- ]
- self._tag_tester(Dummy, templates)
-
- def test_inclusion_tag(self):
- class Inc(helpers.InclusionTag):
- template = 'test.html'
-
- options = core.Options(
- arguments.Argument('var'),
- )
-
- def get_context(self, context, var):
- return {'var': var}
- templates = [
- ('{% inc var %}', 'inc', {'var': 'inc'},),
- ]
- self._tag_tester(Inc, templates)
-
- class Inc2(helpers.InclusionTag):
- template = 'test.html'
-
- templates = [
- ('{% inc2 %}', '', {},),
- ]
- self._tag_tester(Inc2, templates)
-
- def test_inclusion_tag_push_pop_context(self):
- class IncPollute(helpers.InclusionTag):
- template = 'test.html'
-
- options = core.Options(
- arguments.Argument('var')
- )
-
- def get_context(self, context, var):
- context.update({'var': 'polluted'})
- return context
-
- with TemplateTags(IncPollute):
- tpl = template.Template('{% inc_pollute var %}')
- ctx = template.Context({'var': 'test'})
- out = tpl.render(ctx)
- self.assertEqual(out, 'polluted')
- self.assertEqual(ctx['var'], 'polluted')
-
- # now enable pollution control
- IncPollute.push_context = True
-
- with TemplateTags(IncPollute):
- tpl = template.Template('{% inc_pollute var %}')
- ctx = template.Context({'var': 'test'})
- out = tpl.render(ctx)
- self.assertEqual(out, 'polluted')
- self.assertEqual(ctx['var'], 'test')
-
- def test_integer_variable(self):
- options = core.Options(
- arguments.IntegerArgument('integer', resolve=False),
- )
- # test okay
- with SettingsOverride(DEBUG=False):
- dummy_tokens = DummyTokens('1')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertEqual(kwargs['integer'].resolve(dummy_context), 1)
- # test warning
- dummy_tokens = DummyTokens('one')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- one = repr('one')
- message = arguments.IntegerValue.errors['clean'] % {'value': one}
- self.assertWarns(exceptions.TemplateSyntaxWarning,
- message, kwargs['integer'].resolve, dummy_context)
- self.assertEqual(kwargs['integer'].resolve(dummy_context),
- values.IntegerValue.value_on_error)
- # test exception
- with SettingsOverride(DEBUG=True):
- dummy_tokens = DummyTokens('one')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- message = values.IntegerValue.errors['clean'] % {
- 'value': repr('one')
- }
- self.assertRaises(template.TemplateSyntaxError,
- kwargs['integer'].resolve, dummy_context)
- # test the same as above but with resolving
-
- class IntegerTag(core.Tag):
- options = core.Options(
- arguments.IntegerArgument('integer')
- )
-
- def render_tag(self, context, integer):
- return integer
-
- with TemplateTags(IntegerTag):
- tpl = template.Template("{% integer_tag i %}")
- with SettingsOverride(DEBUG=False):
- # test okay
- context = template.Context({'i': '1'})
- self.assertEqual(tpl.render(context), '1')
- # test warning
- context = template.Context({'i': 'one'})
- message = values.IntegerValue.errors['clean'] % {
- 'value': repr('one')
- }
- self.assertWarns(exceptions.TemplateSyntaxWarning,
- message, tpl.render, context)
- self.assertEqual(int(tpl.render(context)),
- values.IntegerValue.value_on_error)
- # test exception
- with SettingsOverride(DEBUG=True):
- context = template.Context({'i': 'one'})
- message = arguments.IntegerValue.errors['clean'] % {'value': one}
- self.assertRaises(template.TemplateSyntaxError, tpl.render,
- context)
- # reset settings
-
- def test_not_implemented_errors(self):
- class Fail(core.Tag):
- pass
-
- class Fail2(helpers.AsTag):
- pass
-
- class Fail3(helpers.AsTag):
- options = core.Options(
- 'as',
- )
-
- class Fail4(helpers.AsTag):
- options = core.Options(
- 'as',
- arguments.Argument('varname', resolve=False),
- )
-
- if DJANGO_1_4_OR_HIGHER:
- exc_class = NotImplementedError
- else: # pragma: no cover
- exc_class = template.TemplateSyntaxError
-
- with TemplateTags(Fail, Fail2, Fail3, Fail4):
- context = template.Context({})
- tpl = template.Template("{% fail %}")
- self.assertRaises(exc_class, tpl.render, context)
- self.assertRaises(ImproperlyConfigured,
- template.Template, "{% fail2 %}")
- self.assertRaises(ImproperlyConfigured,
- template.Template, "{% fail3 %}")
- tpl = template.Template("{% fail4 as something %}")
- self.assertRaises(exc_class, tpl.render, context)
-
- def test_too_many_arguments(self):
- class NoArg(core.Tag):
- pass
- with TemplateTags(NoArg):
- self.assertRaises(exceptions.TooManyArguments,
- template.Template, "{% no_arg a arg %}")
-
- def test_choice_argument(self):
- options = core.Options(
- arguments.ChoiceArgument('choice',
- choices=['one', 'two', 'three']),
- )
- # this is settings dependant!
- with SettingsOverride(DEBUG=True):
- for good in ('one', 'two', 'three'):
- dummy_tokens = DummyTokens(good)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertEqual(kwargs['choice'].resolve(dummy_context), good)
- bad = 'four'
- dummy_tokens = DummyTokens(bad)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertRaises(template.TemplateSyntaxError,
- kwargs['choice'].resolve, dummy_context)
- with SettingsOverride(DEBUG=False):
- self.assertEqual(kwargs['choice'].resolve(dummy_context), 'one')
- # test other value class
-
- class IntegerChoiceArgument(arguments.ChoiceArgument):
- value_class = values.IntegerValue
-
- default = 2
- options = core.Options(
- IntegerChoiceArgument('choice', choices=[1, 2, 3],
- default=default),
- )
- with SettingsOverride(DEBUG=True):
- for good in ('1', '2', '3'):
- dummy_tokens = DummyTokens(good)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertEqual(kwargs['choice'].resolve(dummy_context),
- int(good))
- bad = '4'
- dummy_tokens = DummyTokens(bad)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertRaises(template.TemplateSyntaxError,
- kwargs['choice'].resolve, dummy_context)
- with SettingsOverride(DEBUG=False):
- self.assertEqual(kwargs['choice'].resolve(dummy_context), default)
- # reset settings
-
- def test_keyword_argument(self):
- class KeywordArgumentTag(core.Tag):
- name = 'kwarg_tag'
- options = core.Options(
- arguments.KeywordArgument('named', defaultkey='defaultkey'),
- )
-
- def render_tag(self, context, named):
- return '%s:%s' % (
- list(named.keys())[0], list(named.values())[0]
- )
-
- ctx = {'key': 'thekey', 'value': 'thevalue'}
- templates = [
- ("{% kwarg_tag key='value' %}", 'key:value', ctx),
- ("{% kwarg_tag 'value' %}", 'defaultkey:value', ctx),
- ("{% kwarg_tag key=value %}", 'key:thevalue', ctx),
- ("{% kwarg_tag value %}", 'defaultkey:thevalue', ctx),
- ]
- self._tag_tester(KeywordArgumentTag, templates)
-
- class KeywordArgumentTag2(KeywordArgumentTag):
- name = 'kwarg_tag'
- options = core.Options(
- arguments.KeywordArgument(
- 'named',
- defaultkey='defaultkey',
- resolve=False,
- required=False,
- default='defaultvalue'
- ),
- )
-
- templates = [
- ("{% kwarg_tag %}", 'defaultkey:defaultvalue', ctx),
- ("{% kwarg_tag key='value' %}", 'key:value', ctx),
- ("{% kwarg_tag 'value' %}", 'defaultkey:value', ctx),
- ("{% kwarg_tag key=value %}", 'key:value', ctx),
- ("{% kwarg_tag value %}", 'defaultkey:value', ctx),
- ]
- self._tag_tester(KeywordArgumentTag2, templates)
-
- def test_multi_keyword_argument(self):
- opts = core.Options(
- arguments.MultiKeywordArgument('multi', max_values=2),
- )
-
- class MultiKeywordArgumentTag(core.Tag):
- name = 'multi_kwarg_tag'
- options = opts
-
- def render_tag(self, context, multi):
- items = sorted(multi.items())
- return ','.join(['%s:%s' % item for item in items])
-
- ctx = {'key': 'thekey', 'value': 'thevalue'}
- templates = [
- ("{% multi_kwarg_tag key='value' key2='value2' %}",
- 'key:value,key2:value2', ctx),
- ("{% multi_kwarg_tag key=value %}", 'key:thevalue', ctx),
- ]
- self._tag_tester(MultiKeywordArgumentTag, templates)
- dummy_tokens = DummyTokens('key="value"', 'key2="value2"',
- 'key3="value3"')
- self.assertRaises(exceptions.TooManyArguments,
- opts.parse, dummy_parser, dummy_tokens)
-
- def test_custom_parser(self):
- class CustomParser(parser.Parser):
- def parse_blocks(self):
- return
-
- options = core.Options(
- blocks=[
- ('end_my_tag', 'nodelist'),
- ],
- parser_class=CustomParser
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
-
- def test_repr(self):
- class MyTag(core.Tag):
- name = 'mytag'
- tag = MyTag(dummy_parser, DummyTokens())
- self.assertEqual('<Tag: mytag>', repr(tag))
-
- def test_non_required_multikwarg(self):
- options = core.Options(
- arguments.MultiKeywordArgument('multi', required=False),
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertTrue('multi' in kwargs)
- self.assertEqual(kwargs['multi'], {})
- options = core.Options(
- arguments.MultiKeywordArgument('multi', required=False,
- default={'hello': 'world'}),
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertTrue('multi' in kwargs)
- self.assertEqual(kwargs['multi'].resolve({}), {'hello': 'world'})
-
- def test_resolve_kwarg(self):
- class ResolveKwarg(core.Tag):
- name = 'kwarg'
- options = core.Options(
- arguments.KeywordArgument('named'),
- )
-
- def render_tag(self, context, named):
- return '%s:%s' % (
- list(named.keys())[0], list(named.values())[0]
- )
-
- class NoResolveKwarg(core.Tag):
- name = 'kwarg'
- options = core.Options(
- arguments.KeywordArgument('named', resolve=False),
- )
-
- def render_tag(self, context, named):
- return '%s:%s' % (
- list(named.keys())[0], list(named.values())[0]
- )
-
- resolve_templates = [
- ("{% kwarg key=value %}", "key:test", {'value': 'test'}),
- ("{% kwarg key='value' %}", "key:value", {'value': 'test'}),
- ]
-
- noresolve_templates = [
- ("{% kwarg key=value %}", "key:value", {'value': 'test'}),
- ]
-
- self._tag_tester(ResolveKwarg, resolve_templates)
- self._tag_tester(NoResolveKwarg, noresolve_templates)
-
- def test_kwarg_default(self):
- options = core.Options(
- arguments.KeywordArgument('kwarg', required=False,
- defaultkey='mykey'),
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertTrue('kwarg' in kwargs)
- self.assertEqual(kwargs['kwarg'].resolve({}), {'mykey': None})
- options = core.Options(
- arguments.KeywordArgument('kwarg', required=False,
- default='hello'),
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertTrue('kwarg' in kwargs)
- self.assertEqual(kwargs['kwarg'].resolve({}), {})
- options = core.Options(
- arguments.KeywordArgument('kwarg', required=False,
- default='hello', defaultkey='key'),
- )
- dummy_tokens = DummyTokens()
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertTrue('kwarg' in kwargs)
- self.assertEqual(kwargs['kwarg'].resolve({}), {'key': 'hello'})
-
- def test_multikwarg_no_key(self):
- options = core.Options(
- arguments.MultiKeywordArgument('multi'),
- )
- with SettingsOverride(DEBUG=True):
- dummy_tokens = DummyTokens('value')
- self.assertRaises(template.TemplateSyntaxError,
- options.parse, dummy_parser, dummy_tokens)
- with SettingsOverride(DEBUG=False):
- dummy_tokens = DummyTokens('value')
- self.assertRaises(template.TemplateSyntaxError,
- options.parse, dummy_parser, dummy_tokens)
-
- def test_inclusion_tag_context_pollution(self):
- """
- Check the `keep_render_context` and `push_pop_context` attributes on
- InclusionTag work as advertised and prevent 'context pollution'
- """
- class NoPushPop(helpers.InclusionTag):
- template = 'inclusion.html'
-
- def get_context(self, context):
- return context.update({'pollution': True})
-
- class Standard(helpers.InclusionTag):
- template = 'inclusion.html'
-
- def get_context(self, context):
- return {'pollution': True}
-
- with TemplateTags(NoPushPop, Standard):
- # push pop pollution
- ctx1 = template.Context({'pollution': False})
- tpl1 = template.Template("{% no_push_pop %}")
- tpl1.render(ctx1)
- self.assertEqual(ctx1['pollution'], True)
- ctx2 = template.Context({'pollution': False})
- tpl2 = template.Template("{% standard %}")
- tpl2.render(ctx2)
- self.assertEqual(ctx2['pollution'], False)
-
- def test_named_block(self):
- class StartBlock(core.Tag):
- options = core.Options(
- arguments.Argument("myarg"),
- blocks=[
- BlockDefinition("nodelist",
- VariableBlockName("end_block %(value)s",
- 'myarg'),
- "end_block")
- ]
- )
-
- def render_tag(self, context, myarg, nodelist):
- return "nodelist:%s;myarg:%s" % (nodelist.render(context),
- myarg)
-
- with TemplateTags(StartBlock):
- ctx = template.Context()
- tpl = template.Template(
- "{% start_block 'hello' %}nodelist-content"
- "{% end_block 'hello' %}"
- )
- output = tpl.render(ctx)
- expected_output = 'nodelist:nodelist-content;myarg:hello'
- self.assertEqual(output, expected_output)
-
- ctx = template.Context({'hello': 'world'})
- tpl = template.Template(
- "{% start_block hello %}nodelist-content{% end_block hello %}"
- )
- output = tpl.render(ctx)
- expected_output = 'nodelist:nodelist-content;myarg:world'
- self.assertEqual(output, expected_output)
-
- def test_fail_named_block(self):
- vbn = VariableBlockName('endblock %(value)s', 'myarg')
- self.assertRaises(ImproperlyConfigured, core.Options,
- blocks=[BlockDefinition('nodelist', vbn)])
-
- def test_named_block_noresolve(self):
- class StartBlock(core.Tag):
- options = core.Options(
- arguments.Argument("myarg", resolve=False),
- blocks=[
- BlockDefinition("nodelist",
- VariableBlockName("end_block %(value)s",
- 'myarg'),
- "end_block")
- ]
- )
-
- def render_tag(self, context, myarg, nodelist):
- return "nodelist:%s;myarg:%s" % (nodelist.render(context),
- myarg)
-
- with TemplateTags(StartBlock):
- ctx = template.Context()
- tpl = template.Template(
- "{% start_block 'hello' %}nodelist-content"
- "{% end_block 'hello' %}"
- )
- output = tpl.render(ctx)
- expected_output = 'nodelist:nodelist-content;myarg:hello'
- self.assertEqual(output, expected_output)
-
- def test_strict_string(self):
- options = core.Options(
- arguments.StringArgument('string', resolve=False),
- )
- with SettingsOverride(DEBUG=False):
- # test ok
- dummy_tokens = DummyTokens('string')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertEqual(
- kwargs['string'].resolve(dummy_context), 'string'
- )
- # test warning
- dummy_tokens = DummyTokens(1)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- message = values.StrictStringValue.errors['clean'] % {
- 'value': repr(1)
- }
- self.assertWarns(
- exceptions.TemplateSyntaxWarning,
- message,
- kwargs['string'].resolve,
- dummy_context
- )
- with SettingsOverride(DEBUG=True):
- # test exception
- dummy_tokens = DummyTokens(1)
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- dummy_context = {}
- self.assertRaises(
- template.TemplateSyntaxError,
- kwargs['string'].resolve,
- dummy_context
- )
-
- def test_get_value_for_context(self):
- message = 'exception handled'
-
- class MyException(Exception):
- pass
-
- class SuppressException(helpers.AsTag):
- options = core.Options(
- arguments.Argument('name'),
- 'as',
- arguments.Argument('var', resolve=False, required=False),
- )
-
- def get_value(self, context, name):
- raise MyException(name)
-
- def get_value_for_context(self, context, name):
- try:
- return self.get_value(context, name)
- except MyException:
- return message
-
- dummy_tokens_with_as = DummyTokens('name', 'as', 'var')
- tag = SuppressException(DummyParser(), dummy_tokens_with_as)
- context = {}
- self.assertEqual(tag.render(context), '')
- self.assertEqual(context['var'], message)
-
- dummy_tokens_no_as = DummyTokens('name')
- tag = SuppressException(DummyParser(), dummy_tokens_no_as)
- self.assertRaises(MyException, tag.render, {})
-
-
- class MultiBreakpointTests(TestCase):
- def test_optional_firstonly(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check only using the first argument
- dummy_tokens = DummyTokens('firstval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 2)
- dummy_context = {}
- self.assertEqual(kwargs['first'].resolve(dummy_context), 'firstval')
- self.assertEqual(kwargs['second'].resolve(dummy_context), None)
-
- def test_optional_both(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check using both arguments and both breakpoints
- dummy_tokens = DummyTokens('firstval', 'also', 'using', 'secondval')
- kwargs, blocks = options.parse(dummy_parser, dummy_tokens)
- self.assertEqual(blocks, {})
- self.assertEqual(len(kwargs), 2)
- dummy_context = {}
- self.assertEqual(kwargs['first'].resolve(dummy_context), 'firstval')
- self.assertEqual(kwargs['second'].resolve(dummy_context), 'secondval')
-
- def test_partial_breakpoints(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check only using the first breakpoint
- dummy_tokens = DummyTokens('firstval', 'also')
- self.assertRaises(
- exceptions.TrailingBreakpoint,
- options.parse, dummy_parser, dummy_tokens
- )
-
- def test_partial_breakpoints_second(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check only using the second breakpoint
- dummy_tokens = DummyTokens('firstval', 'using')
- self.assertRaises(
- exceptions.BreakpointExpected,
- options.parse, dummy_parser, dummy_tokens
- )
-
- def test_partial_breakpoints_both(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check only using the first breakpoint
- dummy_tokens = DummyTokens('firstval', 'also', 'secondval')
- # should raise an exception
- self.assertRaises(
- exceptions.BreakpointExpected,
- options.parse, dummy_parser, dummy_tokens
- )
-
- def test_partial_breakpoints_second_both(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- # check only using the second breakpoint
- dummy_tokens = DummyTokens('firstval', 'using', 'secondval')
- self.assertRaises(
- exceptions.BreakpointExpected,
- options.parse, dummy_parser, dummy_tokens
- )
-
- def test_partial_breakpoints_both_trailing(self):
- options = core.Options(
- arguments.Argument('first'),
- 'also',
- 'using',
- arguments.Argument('second', required=False),
- )
- dummy_tokens = DummyTokens('firstval', 'also', 'using')
- self.assertRaises(
- exceptions.TrailingBreakpoint,
- options.parse, dummy_parser, dummy_tokens
- )
-
- def test_add_options(self):
- options1 = core.Options(
- arguments.Argument('first')
- )
- options2 = core.Options(
- arguments.Argument('second')
- )
- combined = options1 + options2
- self.assertEqual(len(combined.options), 1, combined.options)
- self.assertIn(None, combined.options)
- self.assertEqual(len(combined.options[None]), 2, combined.options[None])
- self.assertEqual(combined.all_argument_names, ['first', 'second'])
- self.assertEqual(len(combined.blocks), 0, combined.blocks)
-
- def test_add_options_blocks_first(self):
- options1 = core.Options(
- arguments.Argument('first'),
- blocks=['a']
- )
- options2 = core.Options(
- arguments.Argument('second'),
- )
- combined = options1 + options2
- self.assertEqual(len(combined.blocks), 1, combined.blocks)
- self.assertEqual(combined.blocks[0].alias, 'a')
- self.assertEqual(combined.blocks[0].names, ('a', ))
-
- def test_add_options_blocks_second(self):
- options1 = core.Options(
- arguments.Argument('first'),
- )
- options2 = core.Options(
- arguments.Argument('second'),
- blocks=['a']
- )
- combined = options1 + options2
- self.assertEqual(len(combined.blocks), 1, combined.blocks)
- self.assertEqual(combined.blocks[0].alias, 'a')
- self.assertEqual(combined.blocks[0].names, ('a', ))
-
- def test_add_options_blocks_both(self):
- options1 = core.Options(
- arguments.Argument('first'),
- blocks=['a'],
- )
- options2 = core.Options(
- arguments.Argument('second'),
- blocks=['a']
- )
- self.assertRaises(
- ValueError,
- operator.add,
- options1,
- options2,
- )
-
- def test_add_options_not_options(self):
- options = core.Options(
- arguments.Argument('first'),
- )
- self.assertRaises(
- TypeError,
- operator.add,
- options,
- 1
- )
-
- def test_add_options_custom_parser_same(self):
- class CustomParser(parser.Parser):
- def parse_blocks(self):
- return
-
- options1 = core.Options(
- parser_class=CustomParser,
- )
- options2 = core.Options(
- parser_class=CustomParser,
- )
- combined = options1 + options2
- self.assertIs(combined.parser_class, CustomParser)
-
- def test_add_options_custom_parser_different(self):
- class CustomParser(parser.Parser):
- def parse_blocks(self):
- return
-
- options1 = core.Options(
- parser_class=CustomParser,
- )
- options2 = core.Options(
- parser_class=parser.Parser,
- )
- self.assertRaises(
- ValueError,
- operator.add,
- options1,
- options2,
- )
-
- def test_repr(self):
- options = core.Options(
- arguments.Argument('first'),
- 'breakpoint',
- arguments.Flag('flag', true_values=['yes']),
- blocks=['block']
- )
- self.assertEqual(
- repr(options),
- '<Options:<Argument: first>,breakpoint,<Flag: flag>;block>'
- )
-
- def test_flatten_context(self):
- context = Context({'foo': 'bar'})
- context.push()
- context.update({'bar': 'baz'})
- context.push()
- context.update({'foo': 'test'})
- flat = utils.flatten_context(context)
- expected = {
- 'foo': 'test',
- 'bar': 'baz',
- }
- if DJANGO_1_5_OR_HIGHER:
- expected.update({
- 'None': None,
- 'True': True,
- 'False': False,
- })
- self.assertEqual(flat, expected)
- context.flatten = None
- flat = utils.flatten_context(context)
- self.assertEqual(flat, expected)
- flat = utils.flatten_context({'foo': 'test', 'bar': 'baz'})
- self.assertEqual(flat, {'foo': 'test', 'bar': 'baz'})
-
- def test_flatten_requestcontext(self):
- factory = RequestFactory()
- request = factory.get('/')
- expected = {
- 'foo': 'test',
- 'request': 'bar',
- 'bar': 'baz',
- }
- if DJANGO_1_5_OR_HIGHER:
- expected.update({
- 'None': None,
- 'True': True,
- 'False': False,
- })
-
- checked_keys = expected.keys()
-
- # Adding a requestcontext to a plain context
- context = Context({'foo': 'bar'})
- context.push()
- context.update({'bar': 'baz'})
- context.push()
- rcontext = RequestContext(request, {})
- rcontext.update({'request': 'bar'})
- context.update(rcontext)
- context.push()
- context.update({'foo': 'test'})
- flat = utils.flatten_context(context)
- self.assertEqual(
- expected, dict(filter(lambda item: item[0] in checked_keys, flat.items()))
- )
-
- # Adding a plain context to a requestcontext
- context = RequestContext(request, {})
- context.update({'request': 'bar'})
- normal_context = Context({'foo': 'bar'})
- context.push()
- context.update({'bar': 'baz'})
- context.push()
- context.update(normal_context)
- context.push()
- context.update({'foo': 'test'})
- flat = utils.flatten_context(context)
- self.assertEqual(
- expected, dict(filter(lambda item: item[0] in checked_keys, flat.items()))
- )
-
- # Adding a requestcontext to a requestcontext
- context = RequestContext(request, {})
- context.update({'request': 'bar'})
- rcontext = RequestContext(request, {'foo': 'bar'})
- context.push()
- context.update({'bar': 'baz'})
- context.push()
- context.update(rcontext)
- context.push()
- context.update({'foo': 'test'})
- flat = utils.flatten_context(context)
- self.assertEqual(
- expected, dict(filter(lambda item: item[0] in checked_keys, flat.items()))
- )
|