def test_format_household_name_possessive_with_no_names(self): # Given name = [Undefined(), Undefined()] # When format_value = format_household_name_possessive(name) self.assertIsNone(format_value)
def test_format_address_list_undefined_values(self): user_entered_address = [ Undefined(), Undefined(), Undefined(), Undefined(), Undefined() ] metadata_address = ['123', 'Testy', 'Place', 'Newport', 'NP5 7AR'] self.assertEqual( '123<br />Testy<br />Place<br />Newport<br />NP5 7AR', format_address_list(user_entered_address, metadata_address))
def attribute(self, path): if path: if path.startswith('source.'): if self.parent: return self.parent.attribute(path[7:]) else: return Undefined(name=path) else: if path in self.attributes: return self.attributes[path] else: return Undefined(name=path) else: return Undefined()
def test_first_non_empty_item_filter_raises_exception_when_all_empty(self): # Given scenarios = [[(Undefined())], [(Undefined(), Undefined())], [(None, None)], [('', '')], [(Undefined(), None, '')], [(Undefined(), None, '')], [(None, '')], [(None, [], {}, (), '', set(), b'')]] # When for scenario in scenarios: with self.assertRaises(Exception) as exception: with self.app_request_context('/'): first_non_empty_item(self.autoescape_context, *scenario[0]) # Then assert 'No valid items provided.' in str(exception.exception)
def format_description(self): """Returns the format of the image.""" rv = self._get_image_info()['format_description'] if rv is not None: return rv return Undefined('The format description of the image ' 'could not be determined.')
def created_at(self): """Date the image was created.""" try: return datetime.strptime(self['Image.DateTime'], '%Y:%m:%d %H:%M:%S') except KeyError: return Undefined('The exif data does not contain a creation date.')
def test_default_undefined(self): env = Environment(undefined=Undefined) assert env.from_string("{{ missing }}").render() == "" pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render) assert env.from_string("{{ missing|list }}").render() == "[]" assert env.from_string("{{ missing is not defined }}").render() == "True" assert env.from_string("{{ foo.missing }}").render(foo=42) == "" assert env.from_string("{{ not missing }}").render() == "True" pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render) und1 = Undefined(name="x") und2 = Undefined(name="y") assert und1 == und2 assert und1 != 42 assert hash(und1) == hash(und2) == hash(Undefined()) with pytest.raises(AttributeError): getattr(Undefined, "__slots__") # noqa: B009
def test_undefined_and_special_attributes(self): try: Undefined('Foo').__dict__ except AttributeError: pass else: assert False, "Expected actual attribute error"
def test_object_repr(self): try: Undefined(obj=42, name='upper')() except UndefinedError as e: assert e.message == "'int object' has no attribute 'upper'" else: assert False, 'expected exception'
def test_format_currency(self): self.assertEqual(format_currency('11', 'GBP'), '£11.00') self.assertEqual(format_currency('11.99', 'GBP'), '£11.99') self.assertEqual(format_currency('11000', 'USD'), 'US$11,000.00') self.assertEqual(format_currency(0), '£0.00') self.assertEqual(format_currency(0.00), '£0.00') self.assertEqual(format_currency('', ), '') self.assertEqual(format_currency(None), '') self.assertEqual(format_currency(Undefined()), '')
def render_template_jinja(something): if recursion_detected(inspect.currentframe(), {"something", "device", "namespace", "key"}): # When recursing, just give a bogus value return Undefined(name="RecursionReached") template = self.native_env.from_string(something) scope = self.classifier.scope(device) return template.render(device=device, **scope)
def test_default_undefined(self): env = Environment(undefined=Undefined) assert env.from_string('{{ missing }}').render() == u'' pytest.raises(UndefinedError, env.from_string('{{ missing.attribute }}').render) assert env.from_string('{{ missing|list }}').render() == '[]' assert env.from_string('{{ missing is not defined }}').render() \ == 'True' assert env.from_string('{{ foo.missing }}').render(foo=42) == '' assert env.from_string('{{ not missing }}').render() == 'True' pytest.raises(UndefinedError, env.from_string('{{ missing - 1}}').render) und1 = Undefined(name='x') und2 = Undefined(name='y') assert und1 == und2 assert und1 != 42 assert hash(und1) == hash(und2) == hash(Undefined()) with pytest.raises(AttributeError): getattr(Undefined, '__slots__')
def test_format_number(self): self.assertEqual(format_number(123), "123") self.assertEqual(format_number("123.4"), "123.4") self.assertEqual(format_number("123.40"), "123.4") self.assertEqual(format_number("1000"), "1,000") self.assertEqual(format_number("10000"), "10,000") self.assertEqual(format_number("100000000"), "100,000,000") self.assertEqual(format_number(0), "0") self.assertEqual(format_number(0.00), "0") self.assertEqual(format_number(""), "") self.assertEqual(format_number(None), "") self.assertEqual(format_number(Undefined()), "")
def test_min_value_undefined(self): # Given args = ('foo', Undefined()) # When with self.assertRaises(Exception) as exception: min_value(*args) # Then self.assertIn( "Cannot determine minimum of incompatible types min(<class 'str'>," " <class 'jinja2.runtime.Undefined'>)", str(exception.exception))
def test_format_number(self): self.assertEqual(format_number(123), '123') self.assertEqual(format_number('123.4'), '123.4') self.assertEqual(format_number('123.40'), '123.4') self.assertEqual(format_number('1000'), '1,000') self.assertEqual(format_number('10000'), '10,000') self.assertEqual(format_number('100000000'), '100,000,000') self.assertEqual(format_number(0), '0') self.assertEqual(format_number(0.00), '0') self.assertEqual(format_number(''), '') self.assertEqual(format_number(None), '') self.assertEqual(format_number(Undefined()), '')
def test_format_currency_for_input(self): self.assertEqual(format_currency_for_input('100', 2), '100.00') self.assertEqual(format_currency_for_input('100.0', 2), '100.00') self.assertEqual(format_currency_for_input('100.00', 2), '100.00') self.assertEqual(format_currency_for_input('1000'), '1,000') self.assertEqual(format_currency_for_input('10000'), '10,000') self.assertEqual(format_currency_for_input('100000000'), '100,000,000') self.assertEqual(format_currency_for_input('100000000', 2), '100,000,000.00') self.assertEqual(format_currency_for_input(0, 2), '0.00') self.assertEqual(format_currency_for_input(0), '0') self.assertEqual(format_currency_for_input(''), '') self.assertEqual(format_currency_for_input(None), '') self.assertEqual(format_currency_for_input(Undefined()), '')
def get_asset_url(asset): """Calculates the asset URL relative to the current record.""" ctx = get_ctx() if ctx is None: raise RuntimeError('No context found') asset = site_proxy.get_asset(asset) if asset is None: return Undefined('Asset not found') info = ctx.build_state.get_file_info(asset.source_filename) return '%s?h=%s' % ( ctx.source.url_to('!' + asset.url_path), info.checksum[:8], )
def test_undefined_attribute_error(self): # Django's LazyObject turns the __class__ attribute into a # property that resolves the wrapped function. If that wrapped # function raises an AttributeError, printing the repr of the # object in the undefined message would cause a RecursionError. class Error: @property # type: ignore def __class__(self): raise AttributeError() u = Undefined(obj=Error(), name="hello") with pytest.raises(UndefinedError): getattr(u, "recursion", None)
class Dict(dict): GARD = Undefined() def __getattr__(self, attr): value = self.get(attr, Dict.GARD) if value is Dict.GARD: raise AttributeError(attr) if not isinstance(value, Dict) and isinstance(value, dict): value = Dict(value) return value def __setattr__(self, attr, value): if not isinstance(value, Dict) and isinstance(value, dict): value = Dict(value) super().__setitem__(attr, value) __getitem__, __setitem__ = __getattr__, __setattr__
def test_first_non_empty_item_filter_returns_first_non_empty_item(self): # Given expected_actual_scenarios = [ ['only value', (Markup('only value'), )], [ 'first valid value', (Markup('first valid value'), Markup('second valid value')) ], [ 'first valid value', (Markup('first valid value'), Markup('second valid value'), '') ], [ 'first valid value', (Markup('first valid value'), Markup('second valid value'), Undefined()) ], [ 'first valid value', (Markup('first valid value'), Markup('second valid value'), None) ], ['first valid value', (Markup(''), Markup('first valid value'))], ['first valid value', (Undefined(), Markup('first valid value'))], ['first valid value', (None, Markup('first valid value'))], [ 'first valid value', (Markup(''), Undefined(), None, Markup('first valid value')) ], [ 'False', (None, False, [], {}, (), '', set(), b'', Markup('first valid value')) ], ['0', (Markup(''), Undefined(), None, Markup('0'))], ['0', (0, Markup(''), Undefined(), None, Markup('0'))], ['0.0', (0.00, 0, None, Markup('0'))], ['0j', ('', 0j, None, Undefined())], ['False', ('', False, None, Undefined())] ] # When for scenario in expected_actual_scenarios: with self.app_request_context('/'): value = first_non_empty_item(self.autoescape_context, *scenario[1]) # Then assert scenario[0] == value
def test_format_currency(self): self.assertEqual(format_currency(self.autoescape_context, '11', 'GBP'), "<span class='date'>£11.00</span>") self.assertEqual( format_currency(self.autoescape_context, '11.99', 'GBP'), "<span class='date'>£11.99</span>") self.assertEqual( format_currency(self.autoescape_context, '11000', 'USD'), "<span class='date'>US$11,000.00</span>") self.assertEqual(format_currency(self.autoescape_context, 0), "<span class='date'>£0.00</span>") self.assertEqual(format_currency(self.autoescape_context, 0.00), "<span class='date'>£0.00</span>") self.assertEqual(format_currency( self.autoescape_context, '', ), "<span class='date'></span>") self.assertEqual(format_currency(self.autoescape_context, None), "<span class='date'></span>") self.assertEqual(format_currency(self.autoescape_context, Undefined()), "<span class='date'></span>")
def find_record_for_flowblock(blck): """The record that contains this flow block. This might be unavailable in certain situations, it is however very useful when using the generic block template rendering. """ ctx = get_ctx() if ctx is None: raise RuntimeError('Context unavailable') record = ctx.record if record is None: raise RuntimeError('Context does not point to a record') # It's only the correct record, if we are contained as a field in it. # This could be improved by making a better mapping for this on the # datamodel probably but it's good enough for the moment. for key, value in record.iter_fields(): if isinstance(value, Flow): for other_blck in value.blocks: if other_blck is blck: return record return Undefined('Associated record unavailable.', name='record')
def test_get_template_undefined(self, env): """Passing Undefined to get/select_template raises an UndefinedError or shows the undefined message in the list. """ env.loader = DictLoader({}) t = Undefined(name="no_name_1") with pytest.raises(UndefinedError): env.get_template(t) with pytest.raises(UndefinedError): env.get_or_select_template(t) with pytest.raises(UndefinedError): env.select_template(t) with pytest.raises(TemplatesNotFound) as exc_info: env.select_template([t, "no_name_2"]) exc_message = str(exc_info.value) assert "'no_name_1' is undefined" in exc_message assert "no_name_2" in exc_message
def render_to_native(self, template: Any) -> Any: """ Render the value to its native type based on the inputs """ try: val = self.jinja_native_env.from_string( str(template)).render(**self.rendering_context) if val == Undefined(): raise UndefinedError if isinstance(val, _RawValue): return val.render() return val except UndefinedError: logger.debug( f'Failed to render to native. Template: {str(template)}. Context: {self.rendering_context}' ) return None except TemplateSyntaxError as e: raise ConfigError( f'Invalid configuration for the managed connector: {e.message}' )
def site_proxy(): """Returns the current pad.""" ctx = get_ctx() if ctx is None: return Undefined(hint='Cannot access the site from here', name='site') return ctx.pad
def test_object_repr(self): try: Undefined(obj=42, name='upper')() except UndefinedError as e: pass
def test_undefined_and_special_attributes(self): try: Undefined('Foo').__dict__ except AttributeError: pass
def missing_value(self, reason): return Undefined(hint=self._get_hint('Missing value', reason), obj=self.value)
def __init__(self, *args, **kwargs): ch = logging.StreamHandler(sys.stdout) self.logger.addHandler(ch) Undefined.__init__(self, *args, **kwargs)
def fancy_date(value, format='long'): """Generate a fancy date string. Handles both :class:`~datetime.datetime` objects and potentially partial YYYY-MM-DD string values. The format is one of: * long - Month day in the year (with fallbacks for missing data) * year - Just a year * month - Just a month as the month name * day - Just the day of the month with suffix * any combination of the last three separated by ``'-'``, with an optional `'`?`'` prefix to optional parts.""" if not value: return value if format == 'long': day = fancy_date(value, format='day') month = fancy_date(value, format='month') year = fancy_date(value, format='year') if year: if month: if day: return '{0} {1} in the year {2}'.format(month, day, year) else: return '{0} in the year {1}'.format(month, year) else: return year return Undefined(format='long') elif format == 'year': if isinstance(value, datetime): return value.year else: value = value.split('-') if len(value) >= 1: return int(value[0]) return Undefined(name='year') elif format == 'month': month = Undefined(name='month') if isinstance(value, datetime): month = value.month else: value = value.split('-') if len(value) >= 2: month = int(value[1]) if month: return MONTHS[month] return month elif format == 'day': day = Undefined(name='day') if isinstance(value, datetime): day = value.day else: value = value.split('-') if len(value) == 3: day = int(value[2]) if day: if day in [1, 21, 31]: return '{0}st'.format(day) elif day in [2, 22]: return '{0}nd'.format(day) elif day == 3: return '{0}rd'.format(day) else: return '{0}th'.format(day) return day else: format = format.split('-') result = [] for part in format: if part.startswith('?'): part_value = fancy_date(value, part[1:]) else: part_value = fancy_date(value, part) if part_value: result.append(part_value) elif not part.startswith('?'): return Undefined(name=format) return ' '.join(result)
def test_undefined_and_special_attributes(self): with pytest.raises(AttributeError): Undefined('Foo').__dict__