def _make_namespace_with_nested_types(): # type: (...) -> ApiNamespace ns = ApiNamespace('ns_w_nested_types') struct = Struct(name='NestedTypes', namespace=ns, ast_node=None) struct.set_attributes( doc=None, fields=[ StructField( name='NullableList', data_type=Nullable( List(UInt64()) ), doc=None, ast_node=None, ), StructField( name='ListOfNullables', data_type=List( Nullable(UInt64()) ), doc=None, ast_node=None, ) ] ) ns.add_data_type(struct) return ns
def _make_namespace_with_nullable_and_dafault_fields(): # type: (...) -> ApiNamespace ns = ApiNamespace('ns_w_nullable__fields') struct = Struct(name='Struct1', namespace=ns, ast_node=None) default_field = StructField( name='DefaultField', data_type=UInt64(), doc=None, ast_node=None, ) default_field.set_default(1) struct.set_attributes(doc=None, fields=[ StructField( name='NullableField', data_type=Nullable(UInt64()), doc=None, ast_node=None, ), default_field, StructField( name='RequiredField', data_type=UInt64(), doc=None, ast_node=None, ) ]) ns.add_data_type(struct) return ns
def _make_namespace_with_many_structs(): # type: (...) -> ApiNamespace ns = ApiNamespace('ns_with_many_structs') struct1 = Struct(name='Struct1', namespace=ns, ast_node=None) struct1.set_attributes(None, [StructField('f1', Boolean(), None, None)]) ns.add_data_type(struct1) struct2 = Struct(name='Struct2', namespace=ns, ast_node=None) struct2.set_attributes( doc=None, fields=[ StructField('f2', List(UInt64()), None, None), StructField('f3', Timestamp(ISO_8601_FORMAT), None, None), StructField('f4', Map(String(), UInt64()), None, None) ] ) ns.add_data_type(struct2) return ns
def test_check_example(self): # # Test string # s = String(min_length=1, max_length=5) s.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value='hello', )) with self.assertRaises(InvalidSpec) as cm: s.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value='', )) self.assertIn("'' has fewer than 1 character(s)", cm.exception.msg) # # Test list # l1 = List(String(min_length=1), min_items=1, max_items=3) l1.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value=['asd'], )) with self.assertRaises(InvalidSpec) as cm: l1.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value=[], )) self.assertIn("has fewer than 1 item(s)", cm.exception.msg) # # Test list of lists # l1 = List(List(String(min_length=1), min_items=1)) l1.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value=[['asd']], )) with self.assertRaises(InvalidSpec) as cm: l1.check_example( AstExampleField( path='test.stone', lineno=1, lexpos=0, name='v', value=[[]], )) self.assertIn("has fewer than 1 item(s)", cm.exception.msg) # # Test Map type # m = Map(String(), String()) # valid example m.check_example( AstExampleField(path='test.stone', lineno=1, lexpos=0, name='v', value={"foo": "bar"})) # does not conform to declared type with self.assertRaises(InvalidSpec): m.check_example( AstExampleField(path='test.stone', lineno=1, lexpos=0, name='v', value={1: "bar"})) with self.assertRaises(ParameterError): # errors because only string types can be used as keys Map(Int32(), String()) s = Struct('S', None, None) s.set_attributes( "Docstring", [ StructField('a', UInt64(), 'a field', None), StructField('b', List(String()), 'a field', None), ], ) s._add_example( AstExample('test.stone', lineno=1, lexpos=0, label='default', text='Default example', fields={ 'a': AstExampleField( path='test.stone', lineno=2, lexpos=0, name='a', value=132, ), 'b': AstExampleField( path='test.stone', lineno=2, lexpos=0, name='b', value=['a'], ), }))
def test_struct(self): ns = ApiNamespace('test') quota_info = Struct( 'QuotaInfo', None, ns, ) quota_info.set_attributes( "Information about a user's space quota.", [ StructField('quota', UInt64(), 'Total amount of space.', None), ], ) # add an example that doesn't fit the definition of a struct with self.assertRaises(InvalidSpec) as cm: quota_info._add_example( AstExample(path=None, lineno=None, lexpos=None, label='default', text=None, fields={ 'bad_field': AstExampleField(None, None, None, 'bad_field', 'xyz123') })) self.assertIn('has unknown field', cm.exception.msg) quota_info._add_example( AstExample(path=None, lineno=None, lexpos=None, label='default', text=None, fields={ 'quota': AstExampleField(None, None, None, 'quota', 64000) })) # set null for a required field with self.assertRaises(InvalidSpec) as cm: quota_info._add_example( AstExample(path=None, lineno=None, lexpos=None, label='null', text=None, fields={ 'quota': AstExampleField(None, None, None, 'quota', None) })) self.assertEqual( "Bad example for field 'quota': null is not a valid integer", cm.exception.msg) self.assertTrue(quota_info._has_example('default')) quota_info.nullable = True # test for structs within structs account_info = Struct( 'AccountInfo', None, ns, ) account_info.set_attributes( "Information about an account.", [ StructField('account_id', String(), 'Unique identifier for account.', None), StructField('quota_info', quota_info, 'Quota', None) ], ) account_info._add_example( AstExample(path=None, lineno=None, lexpos=None, label='default', text=None, fields={ 'account_id': AstExampleField(None, None, None, 'account_id', 'xyz123'), 'quota_info': AstExampleField( None, None, None, 'quota_info', AstExampleRef(None, None, None, 'default')) })) account_info._compute_examples() # ensure that an example for quota_info is propagated up self.assertIn('quota_info', account_info.get_examples()['default'].value)
def test_int(self): i = Int32() # check valid Int32 i.check(42) # check number that is too large with self.assertRaises(ValueError) as cm: i.check(2**31) self.assertIn('not within range', cm.exception.args[0]) # check number that is too small with self.assertRaises(ValueError) as cm: i.check(-2**31 - 1) self.assertIn('not within range', cm.exception.args[0]) i = UInt32() # check number that is too large with self.assertRaises(ValueError) as cm: i.check(2**32) self.assertIn('not within range', cm.exception.args[0]) # check number that is too small with self.assertRaises(ValueError) as cm: i.check(-1) self.assertIn('not within range', cm.exception.args[0]) i = Int64() # check number that is too large with self.assertRaises(ValueError) as cm: i.check(2**63) self.assertIn('not within range', cm.exception.args[0]) # check number that is too small with self.assertRaises(ValueError) as cm: i.check(-2**63 - 1) self.assertIn('not within range', cm.exception.args[0]) i = UInt64() # check number that is too large with self.assertRaises(ValueError) as cm: i.check(2**64) self.assertIn('not within range', cm.exception.args[0]) # check number that is too small with self.assertRaises(ValueError) as cm: i.check(-1) self.assertIn('not within range', cm.exception.args[0]) i = Int64(min_value=0, max_value=10) with self.assertRaises(ValueError) as cm: i.check(20) self.assertIn('20 is greater than 10', cm.exception.args[0]) with self.assertRaises(ValueError) as cm: i.check(-5) self.assertIn('-5 is less than 0', cm.exception.args[0]) # check that bad ranges are rejected self.assertRaises(ParameterError, lambda: Int64(min_value=0.1)) self.assertRaises(ParameterError, lambda: Int64(max_value='10'))