def __init__(self, bind, name=None, label=None, description=None, html_attributes=None, modifiers=None, **kwargs): # increment the instance counter self.instance_counter = Widget.instance_counter Widget.instance_counter += 1 self.html_attributes = HTMLAttrs() self.schema = Schema() self.modifiers = [] # default properties self.bind = bind # is an HTML attribute (see properties) self.name = name # is an HTML attribute (see properties) self.label = label self.description = description if self.atomic_schema is not None: self.schema[bind] = copy.deepcopy(self.atomic_schema) self._apply_customize(**kwargs) # final user's stuff override everything else if modifiers is not None: self.modifiers += modifiers if html_attributes is not None: self.html_attributes.update(html_attributes) self.apply_modifiers()
def setUp(self): self.attr = HTMLAttrs() self.attr['attribute'] = 'ok' self.attr['boolean'] = None self.attr['camelCase'] = 'too' self.attr['dash-syntax'] = 'yeah'
def test_alternate_init(self): attr = HTMLAttrs(attribute='ok', boolean=None, camelCase='too') self.assertIn('boolean', attr) self.assertEqual(attr['boolean'], None) self.assertIn('attribute', attr) self.assertEqual(attr['attribute'], 'ok') self.assertIn('camel-case', attr) self.assertIn('camelCase', attr) self.assertEqual(attr['camel-case'], 'too') self.assertEqual(attr['camelCase'], 'too')
class Widget(object): """ """ # the instance counter is used to keep track of the widget order in a form. instance_counter = 0 # the default HTML template html_template = ( '<em>' 'This widget is not renderable.' '</em>' ) # the atomic_schema atomic_schema = None @property def bind(self): return self.html_attributes.get('ngModel', None) @bind.setter def bind(self, value): self.html_attributes['ngModel'] = value @property def name(self): return self.html_attributes.get('name', None) @name.setter def name(self, value): self.html_attributes['name'] = value @property def label(self): if self._label is None: return self.name return self._label @label.setter def label(self, value): self._label = value def __init__(self, bind, name=None, label=None, description=None, html_attributes=None, modifiers=None, **kwargs): # increment the instance counter self.instance_counter = Widget.instance_counter Widget.instance_counter += 1 self.html_attributes = HTMLAttrs() self.schema = Schema() self.modifiers = [] # default properties self.bind = bind # is an HTML attribute (see properties) self.name = name # is an HTML attribute (see properties) self.label = label self.description = description if self.atomic_schema is not None: self.schema[bind] = copy.deepcopy(self.atomic_schema) self._apply_customize(**kwargs) # final user's stuff override everything else if modifiers is not None: self.modifiers += modifiers if html_attributes is not None: self.html_attributes.update(html_attributes) self.apply_modifiers() def _apply_customize(self, **kwargs): """ A recusive method calling each customize method found in the inheritance tree of the widget. """ def recursion(cls): if cls.__base__ != Widget: recursion(cls.__base__) customize = getattr(cls, 'customize', None) if customize is not None: # Get the list minus the first argument (self) args = inspect.getargspec(customize).args[1:] customize( self, **dict((k, v) for k, v in kwargs.items() if k in args) ) if self.__class__ is not Widget: recursion(self.__class__) def apply_modifiers(self): for modifier in self.modifiers: modifier.apply_to(self) def __unicode__(self): return jinja2.Template(self.html_template).render( widget=self, attrs=self.html_attributes ) def __str__(self): # Python2/3 compatibility if sys.version_info > (3, 0): return self.__unicode__() return unicode(self).encode('utf-8')
class HTMLAttrsTest(unittest.TestCase): def setUp(self): self.attr = HTMLAttrs() self.attr['attribute'] = 'ok' self.attr['boolean'] = None self.attr['camelCase'] = 'too' self.attr['dash-syntax'] = 'yeah' def test_simple_attr(self): self.assertIn('attribute', self.attr) self.assertEqual(self.attr['attribute'], 'ok') def test_conversion_0(self): self.assertIn('camel-case', self.attr) self.assertIn('camelCase', self.attr) self.assertEqual(self.attr['camel-case'], 'too') self.assertEqual(self.attr['camelCase'], 'too') def test_conversion_1(self): self.assertIn('dash-syntax', self.attr) self.assertIn('dashSyntax', self.attr) self.assertEqual(self.attr['dash-syntax'], 'yeah') self.assertEqual(self.attr['dashSyntax'], 'yeah') def test_remove_attr_0(self): del self.attr['attribute'] self.assertNotIn('attribute', self.attr) def test_remove_attr_1(self): del self.attr['camelCase'] self.assertNotIn('camel-case', self.attr) self.assertNotIn('camelCase', self.attr) def test_remove_attr_2(self): del self.attr['camel-case'] self.assertNotIn('camel-case', self.attr) self.assertNotIn('camelCase', self.attr) def test_rendering(self): self.assertEqual( str(self.attr), 'attribute="ok" boolean camel-case="too" dash-syntax="yeah"' ) def test_exception_0(self): with self.assertRaises(KeyError): self.attr['missing'] def test_exception_1(self): with self.assertRaises(KeyError): del self.attr['missing'] def test_iter(self): for k in self.attr: self.assertIn( k, ['attribute', 'boolean', 'camel-case', 'dash-syntax'] ) def test_items(self): res = { 'attribute': 'ok', 'boolean': None, 'camel-case': 'too', 'dash-syntax': 'yeah', } for k, v in self.attr.items(): self.assertIn( k, ['attribute', 'boolean', 'camel-case', 'dash-syntax'] ) self.assertEqual(v, res[k]) def test_alternate_init(self): attr = HTMLAttrs(attribute='ok', boolean=None, camelCase='too') self.assertIn('boolean', attr) self.assertEqual(attr['boolean'], None) self.assertIn('attribute', attr) self.assertEqual(attr['attribute'], 'ok') self.assertIn('camel-case', attr) self.assertIn('camelCase', attr) self.assertEqual(attr['camel-case'], 'too') self.assertEqual(attr['camelCase'], 'too')
class HTMLAttrsTest(unittest.TestCase): def setUp(self): self.attr = HTMLAttrs() self.attr['attribute'] = 'ok' self.attr['boolean'] = None self.attr['camelCase'] = 'too' self.attr['dash-syntax'] = 'yeah' def test_simple_attr(self): self.assertIn('attribute', self.attr) self.assertEqual(self.attr['attribute'], 'ok') def test_conversion_0(self): self.assertIn('camel-case', self.attr) self.assertIn('camelCase', self.attr) self.assertEqual(self.attr['camel-case'], 'too') self.assertEqual(self.attr['camelCase'], 'too') def test_conversion_1(self): self.assertIn('dash-syntax', self.attr) self.assertIn('dashSyntax', self.attr) self.assertEqual(self.attr['dash-syntax'], 'yeah') self.assertEqual(self.attr['dashSyntax'], 'yeah') def test_remove_attr_0(self): del self.attr['attribute'] self.assertNotIn('attribute', self.attr) def test_remove_attr_1(self): del self.attr['camelCase'] self.assertNotIn('camel-case', self.attr) self.assertNotIn('camelCase', self.attr) def test_remove_attr_2(self): del self.attr['camel-case'] self.assertNotIn('camel-case', self.attr) self.assertNotIn('camelCase', self.attr) def test_rendering(self): self.assertEqual( str(self.attr), 'attribute="ok" boolean camel-case="too" dash-syntax="yeah"') def test_exception_0(self): with self.assertRaises(KeyError): self.attr['missing'] def test_exception_1(self): with self.assertRaises(KeyError): del self.attr['missing'] def test_iter(self): for k in self.attr: self.assertIn( k, ['attribute', 'boolean', 'camel-case', 'dash-syntax']) def test_items(self): res = { 'attribute': 'ok', 'boolean': None, 'camel-case': 'too', 'dash-syntax': 'yeah', } for k, v in list(self.attr.items()): self.assertIn( k, ['attribute', 'boolean', 'camel-case', 'dash-syntax']) self.assertEqual(v, res[k]) def test_alternate_init(self): attr = HTMLAttrs(attribute='ok', boolean=None, camelCase='too') self.assertIn('boolean', attr) self.assertEqual(attr['boolean'], None) self.assertIn('attribute', attr) self.assertEqual(attr['attribute'], 'ok') self.assertIn('camel-case', attr) self.assertIn('camelCase', attr) self.assertEqual(attr['camel-case'], 'too') self.assertEqual(attr['camelCase'], 'too')