def test_list_production(self): self.assertEqual( [1, 2, 3], c.list(c.String)([1, 2, 3], ctx=context.create(production_mode=True)) ) self.assertIsNone( c.list(c.String)(None, ctx=context.create(production_mode=True)) )
def test_enums_custom_error(self): Enum = c.enum({'V1': '1', 'V2': '2', 'V3': '3'}) observer = Mock() ctx = context.create(validation_error_observer=observer) Enum('V4', ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'V1 or V2 or V3', 'V4')
def test_struct_production(self): my_struct = c.struct({ 'a': c.Int, 'b': c.String }) base_dict = {'a': 'hello', 'b': 'world'} s = my_struct(base_dict, ctx=context.create(production_mode=True)) self.assertEqual(base_dict, s)
def test_intersection_production(self): name_type = c.struct({'name': c.String}) age_type = c.struct({'age': c.Int}) my_type = c.intersection(name_type, age_type) base_dict = {'name': 'mirko', 'age': '36'} self.assertEqual(base_dict, my_type(base_dict, ctx=context.create(production_mode=True)))
def test_object_production(self): class TestClass(object): def __init__(self, f1, f2): self.f1 = f1 self.f2 = f2 t = TestClass('hello', 10) type1 = generic_object({'f1': Int, 'f2': Int}, TestClass) self.assertEqual(t, type1(t, ctx=context.create(production_mode=True)))
def test_intersection_custom_error(self): name_type = c.struct({'name': c.String}) age_type = c.struct({'age': c.Int}) my_type = c.intersection(name_type, age_type) observer = Mock() ctx = context.create(validation_error_observer=observer) my_type({'name': 'mirko', 'age': '36'}, ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'Struct{name: String} or Struct{age: Int}', dict)
def _object(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) assert_type(type(x) == object_type, ctx=new_ctx, expected=name, found_type=type(x)) for field in fields_combinators: cur_field_combinator = fields_combinators[field] field_new_ctx = context.create(new_ctx) field_new_ctx.append(field) cur_field_combinator(getattr(x, field), ctx=field_new_ctx) return x
def _subtype(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) assert_type(_subtype.is_type(x), ctx=new_ctx, expected=name, found_type=type(x)) return combinator(x, new_ctx)
def _function(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) assert_type(_function.is_type(x), ctx=new_ctx, expected=name, found_type=type(x)) return x if '__pycomb__meta__' in dir(x) else _typedef(args, kwargs, ctx=new_ctx)(x)
def _irreducible(value, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return value if new_ctx.empty: new_ctx.append(name) assert_type(_irreducible.is_type(value), ctx=new_ctx, expected=name, found_type=type(value)) return value
def _maybe(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) assert_type( _maybe.is_type(x), ctx=new_ctx, found_type=type(x), expected='None or {}'.format(get_type_name(combinator))) return combinator(x, new_ctx) if x else None
def test_tuple_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) c.list(c.String)('hello') c.list(c.String)((1, 2, 3), ctx=ctx) observer.on_error.assert_has_calls( [ mock.call(_ANY_CONTEXT, 'String', int), mock.call(_ANY_CONTEXT, 'String', int), mock.call(_ANY_CONTEXT, 'String', int) ] )
def test_struct_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) d = {'name': c.String, 'value': c.Int} c.struct(d)('hello', ctx=ctx) call = observer.on_error.call_args_list self.assertEqual(1, len(call)) call = call[0] self.assertTrue( call == mock.call(_ANY_CONTEXT, 'Struct{value: Int, name: String}', str) or \ call == mock.call(_ANY_CONTEXT, 'Struct{name: String, value: Int}', str), msg=str(call) )
def test_should_be_idempotent_production(self): production_ctx = ctx.create(production_mode=True) numbers0 = [1, 2] numbers1 = self.ListOfNumbers(numbers0, ctx=production_ctx) numbers2 = self.ListOfNumbers(numbers1, ctx=production_ctx) self.assertTrue(numbers0 is numbers1) self.assertTrue(numbers1 is numbers2) path0 = [{"x": 0, "y": 0}, {"x": 1, "y": 1}] path1 = self.Path(path0, ctx=production_ctx) path2 = self.Path(path1, ctx=production_ctx) self.assertTrue(path0 is path1) self.assertTrue(path1 is path2)
def test_object_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) class TestClass(object): def __init__(self, f1, f2): self.f1 = f1 self.f2 = f2 t = TestClass('hello', 10) type1 = generic_object({'f1': Int, 'f2': Int}, TestClass) type1(t, ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'Int', str)
def _list(x, ctx=None): new_ctx_list = context.create(ctx) if new_ctx_list.production_mode: return x if new_ctx_list.empty: new_ctx_list.append(name) assert_type(bool(x), ctx=new_ctx_list, expected='List', found_type=type(None)) if not x: return None result = [] i = 0 for d in x: new_ctx = context.create(new_ctx_list) new_ctx.append('[{}]'.format(i), separator='') result.append(combinator_element(d, ctx=new_ctx)) i += 1 return tuple(result)
def _struct(x, ctx=None): ctx = context.create(ctx) if ctx.production_mode: return x if ctx.empty: ctx.append(name) is_type = _struct.is_type(x) or type(x) is dict assert_type(is_type, ctx=ctx, expected=name, found_type=type(x)) # Cannot proceed, this is not even a struct. if not is_type: return x if type(x) == p.StructType: return x new_dict = {} for k in combinators: new_ctx = context.create(ctx) new_ctx.append('[{}]'.format(k), separator='') new_dict[k] = combinators[k](x.get(k), ctx=new_ctx) return p.StructType(new_dict)
def _enum(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) is_type = _enum.is_type(x) assert_type( is_type, ctx=new_ctx, expected=' or '.join(sorted_enums), found_type=str(x)) if not is_type: return None return values[x]
def _intersection(x, ctx=None): new_ctx = context.create(ctx) if new_ctx.production_mode: return x new_ctx.append(name) assert_type(_intersection.is_type(x), ctx=new_ctx, expected=' or '.join(map(lambda d: get_type_name(d), combinators)), found_type=type(x)) if dispatcher: default_combinator = dispatcher(x) assert default_combinator in combinators else: default_combinator = _default_composite_dispatcher(x, combinators) return default_combinator(x, ctx=new_ctx)
def test_list_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) c.list(c.String)('hello', ctx=ctx) self.assertEqual(0, observer.on_error.call_count) c.list(c.String)([1, 2, 3], ctx=ctx) observer.on_error.assert_has_calls( [ mock.call(_ANY_CONTEXT, 'String', int), mock.call(_ANY_CONTEXT, 'String', int), mock.call(_ANY_CONTEXT, 'String', int) ]) self.assertFalse(c.list(c.String).is_type([1, 2, 3])) observer.reset_mock() c.list(c.String)(['1', 2, '3'], ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'String', int) observer.reset_mock() self.assertIsNone( c.list(c.String)(None, ctx=ctx) ) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'List', type(None))
def test_function_production(self): # noinspection PyUnresolvedReferences Fun = c.function(c.String, c.Int, a=c.Float, b=c.enum.of(['X', 'Y', 'Z'])) new_f = Fun(lambda: None, ctx=context.create(production_mode=True)) new_f()
def test_enums_production(self): Enum = c.enum({'V1': '1', 'V2': '2', 'V3': '3'}) self.assertEqual('V4', Enum('V4', ctx=context.create(production_mode=True)))
def test_subtype_production(self): SmallString = c.subtype(c.String, lambda d: len(d) <= 10) self.assertEqual('12345678901', SmallString('12345678901', ctx=context.create(production_mode=True)))
def test_union_production(self): Number = c.union(c.Int, c.Float) self.assertEqual('hello', Number('hello', ctx=context.create(production_mode=True)))
def test_int_production(self): my_int = c.Int('hello', ctx=context.create(production_mode=True)) self.assertEqual('hello', my_int)
def f(*inner_args, **inner_kwargs): result = fun(*inner_args, **inner_kwargs) return combinator(result, ctx=context.create())
def test_maybe_production(self): my_maybe = c.maybe(c.String) self.assertEqual(1, my_maybe(1, ctx=context.create(production_mode=True)))
def test_subtype_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) SmallString = c.subtype(c.String, lambda d: len(d) <= 10) SmallString('12345678901', ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'Subtype(String)', str)
def test_union_custom_error(self): observer = Mock() ctx = context.create(validation_error_observer=observer) Number = c.union(c.Int, c.Float) Number('hello', ctx=ctx) observer.on_error.assert_called_once_with(_ANY_CONTEXT, 'Int or Float', str)
def test_hydrate_production(self): instance = self.MyList([{}], ctx=ctx.create(production_mode=True)) self.assertTrue(self.MyElement.is_type(instance[0]))