def test_instantiate(self): noname = extypes.ConstrainedSet(['a', 'b', 'c']) self.assertEqual('ConstrainedSet', noname.name) self.assertEqual(['a', 'b', 'c'], noname.choices) pretty = extypes.ConstrainedSet(['a', 'b', 'c'], name='Shiny') self.assertEqual('Shiny', pretty.name) self.assertEqual('Shiny', pretty.__name__)
def __init__(self, choices, *args, **kwargs): if (isinstance(choices, type) and issubclass(choices, extypes_base.BaseConstrainedSet)): set_definition = choices if hasattr(choices.choices, 'items'): django_choices = list(choices.choices.items()) else: django_choices = [(c, c) for c in choices.choices] else: if not is_iterable(choices): raise ValueError("choices must be an iterable of (code, human_readable) tuples; got %r" % (choices,)) for item in choices: if len(item) != 2: raise ValueError( "choices must be an iterable of (code, human_readable) tuples; got entry %r in %r" % (item, choices) ) django_choices = choices set_definition = extypes.ConstrainedSet(collections.OrderedDict(django_choices)) for opt in set_definition.choices: if self.db_separator in opt: raise ValueError( "%r is forbidden in choices; found in %r" % (self.db_separator, opt) ) self.django_choices = django_choices self.set_definition = set_definition kwargs['max_length'] = len(self.get_prep_value(set_definition.choices)) super(SetField, self).__init__(*args, **kwargs)
def test_choices_with_existing_set(self): """SetField accepts an already-defined ConstrainedSet.""" Foods = extypes.ConstrainedSet( {'eggs': "Eggs", 'spam': "Spam", 'bacon': "Bacon"}, ) field = django_extypes.SetField(choices=Foods) self.assertEqual(Foods, field.set_definition) self.assertEqual(Foods.choices, dict(field.django_choices))
def test_extra_operations(self): """ConstrainedSet should get extra features when 'choices' is a dict.""" Foods = extypes.ConstrainedSet( { 'spam': "Spam", 'eggs': "Eggs", 'bacon': "Bacon", }, name='Foods') meat = Foods(['spam', 'bacon']) self.assertEqual(set(['spam', 'bacon']), set(meat.keys())) self.assertEqual(set(["Spam", "Bacon"]), set(meat.values())) self.assertEqual(set([('spam', "Spam"), ('bacon', "Bacon")]), set(meat.items())) self.assertEqual("Spam", meat['spam']) self.assertEqual("Bacon", meat['bacon']) with self.assertRaises(KeyError): meat['eggs']
def test_set_operations(self): Foods = extypes.ConstrainedSet(['spam', 'eggs', 'bacon'], name='Foods') Cooking = extypes.ConstrainedSet(['cook', 'burn'], name='Cooking') fridge = Foods(['spam', 'bacon']) self.assertTrue('spam' in fridge) self.assertTrue('eggs' not in fridge) self.assertEqual(2, len(fridge)) self.assertTrue(fridge) self.assertFalse(Foods()) # ConstrainedSet retain the ordering of the constrainer self.assertEqual(['spam', 'bacon'], list(fridge)) # Equality self.assertEqual(fridge, Foods(['spam', 'bacon'])) # Equality doesn't care about ordering self.assertEqual(fridge, Foods(['spam', 'bacon'])) self.assertNotEqual(fridge, Foods(['spam'])) # Compare with other types self.assertFalse(Foods() == Cooking()) self.assertTrue(Foods() != Cooking()) # Set operations meat = Foods(['spam', 'bacon']) fresh = Foods(['eggs', 'bacon']) white = Foods(['eggs']) # Bonus operations self.assertEqual(white, ~meat) self.assertEqual(meat, ~~meat) # Comparison self.assertTrue(meat.isdisjoint(white)) self.assertTrue(white.isdisjoint(meat)) self.assertTrue(white.issubset(fresh)) self.assertTrue(white <= fresh) self.assertFalse(meat.issubset(fresh)) self.assertFalse(meat <= fresh) self.assertTrue(white < fresh) self.assertFalse(white < white) self.assertTrue(fresh.issuperset(white)) self.assertTrue(fresh >= white) self.assertFalse(fresh.issuperset(meat)) self.assertFalse(fresh >= meat) self.assertTrue(fresh > white) self.assertFalse(white > white) # Combination self.assertEqual(Foods(['spam', 'bacon', 'eggs']), meat.union(fresh)) self.assertEqual(Foods(['spam', 'bacon', 'eggs']), meat | fresh) self.assertEqual(fresh, fresh | white) self.assertEqual(Foods(['bacon']), meat.intersection(fresh)) self.assertEqual(Foods(['bacon']), meat & fresh) self.assertEqual(white, fresh & white) self.assertEqual(Foods(['bacon']), fresh.difference(white)) self.assertEqual(Foods(['bacon']), fresh - white) self.assertEqual(white, fresh - meat) self.assertEqual(Foods(['spam', 'eggs']), fresh.symmetric_difference(meat)) self.assertEqual(Foods(['spam', 'eggs']), fresh ^ meat) self.assertEqual(Foods(['bacon']), white ^ fresh) # Copy meat2 = meat.copy() self.assertEqual(meat, meat2) meat2.add('eggs') self.assertNotEqual(meat, meat2) # Edition: add/remove/pop/clear meat2 = meat.copy() meat2.add('eggs') self.assertEqual(Foods(['eggs', 'spam', 'bacon']), meat2) # Involutive add meat2 = meat.copy() meat2.add('spam') self.assertEqual(meat, meat2) meat2 = meat.copy() meat2.remove('spam') self.assertEqual(Foods(['bacon']), meat2) meat2 = meat.copy() with self.assertRaises(KeyError): meat2.remove('eggs') self.assertIsNone(meat2.discard('eggs')) meat2 = meat.copy() meat2.discard('bacon') self.assertEqual(Foods(['spam']), meat2) meat2 = meat.copy() elem1 = meat2.pop() self.assertEqual(1, len(meat2)) elem2 = meat2.pop() self.assertEqual(Foods(), meat2) self.assertEqual(set(['spam', 'bacon']), set([elem1, elem2])) meat2 = meat.copy() meat2.clear() self.assertEqual(Foods(), meat2) # Edition: update meat2 = meat.copy() meat2.update(white) self.assertEqual(Foods(['spam', 'eggs', 'bacon']), meat2) meat2 = meat.copy() meat2 |= fresh self.assertEqual(Foods(['spam', 'eggs', 'bacon']), meat2) # Edition: intersection update meat2 = meat.copy() meat2.intersection_update(fresh) self.assertEqual(Foods(['bacon']), meat2) fresh2 = fresh.copy() fresh2 &= white self.assertEqual(white, fresh2) # Edition: symmetric difference update meat2 = meat.copy() meat2.symmetric_difference_update(fresh) self.assertEqual(Foods(['eggs', 'spam']), meat2) fresh2 = fresh.copy() fresh2 ^= white self.assertEqual(Foods(['bacon']), fresh2)
# -*- coding: utf-8 -*- # Copyright (c) 2014 Raphaël Barrois # This code is distributed under the two-clause BSD License. from django.db import models import extypes from extypes import django as extypes_django flags = extypes.ConstrainedSet(['clean', 'online', 'open']) class Fridge(models.Model): contents = extypes_django.SetField( choices=[ ('spam', "Spam"), ('bacon', "Bacon"), ('eggs', "Eggs"), ], blank=True, ) flags = extypes_django.SetField(choices=flags, blank=True)