def test_gen_structure_list_scalar_docs(self): schema = { "type": "object", "properties": { "Consistent": { "type": "boolean", }, "Args": { "type": "array", "items": { "type": "string" } } } } argument_model = create_argument_model_from_schema(schema) m = model.DenormalizedStructureBuilder().with_members( OrderedDict([ ('Consistent', { 'type': 'boolean' }), ('Args', { 'type': 'list', 'member': { 'type': 'string', } }), ])).build_model() generated_example = self.shorthand_documenter.generate_shorthand_example( '--foo', m) self.assertIn('Consistent=boolean,Args=string,string', generated_example)
def test_gen_list_structure_multiple_scalar_docs(self): expected = ('Scalar1=string,' 'Scalar2=string,' 'List1=string,string ...') arg = model.DenormalizedStructureBuilder().with_members( OrderedDict([ ('List', { 'type': 'list', 'member': { 'type': 'structure', 'members': OrderedDict([ ('Scalar1', { 'type': 'string' }), ('Scalar2', { 'type': 'string' }), ('List1', { 'type': 'list', 'member': { 'type': 'string' }, }), ]), } }), ])).build_model().members['List'] rendered = self.shorthand_documenter.generate_shorthand_example( '--foo', arg) self.assertIn(expected, rendered)
def test_gen_list_structure_multiple_scalar_docs(self): expected = ('Scalar1=string,' 'Scalar2=string,' 'List1=string,string ...') m = model.DenormalizedStructureBuilder().with_members( OrderedDict([ ('List', { 'type': 'list', 'member': { 'type': 'structure', 'members': OrderedDict([ ('Scalar1', { 'type': 'string' }), ('Scalar2', { 'type': 'string' }), ('List1', { 'type': 'list', 'member': { 'type': 'string' }, }), ]), } }), ])).build_model().members['List'] argument = mock.Mock() argument.argument_model = m argument.name = 'foo' argument.cli_name = '--foo' generated_example = self.get_generated_example_for(argument) self.assertIn(expected, generated_example)
def test_ordered_shape_builder(self): b = model.DenormalizedStructureBuilder() shape = b.with_members(OrderedDict( [ ('A', { 'type': 'string' }), ('B', { 'type': 'structure', 'members': OrderedDict( [ ('C', { 'type': 'string' }), ('D', { 'type': 'string' }) ] ) }) ] )).build_model() # Members should be in order self.assertEqual(['A', 'B'], list(shape.members.keys())) # Nested structure members should *also* stay ordered self.assertEqual(['C', 'D'], list(shape.members['B'].members.keys()))
def test_skip_deeply_nested_shorthand(self): # The eventual goal is to have a better way to document # deeply nested shorthand params, but for now, we'll # only document shorthand params up to a certain stack level. m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'structure', 'members': { 'B': { 'type': 'structure', 'members': { 'C': { 'type': 'structure', 'members': { 'D': { 'type': 'string' }, } } } } } }, }).build_model() generated_example = self.shorthand_documenter.generate_shorthand_example( '--foo', m) self.assertEqual(generated_example, '')
def test_can_convert_scalar_types_from_string(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'integer' }, 'B': { 'type': 'string' }, 'C': { 'type': 'float' }, 'D': { 'type': 'boolean' }, 'E': { 'type': 'boolean' }, }).build_model() b = shorthand.BackCompatVisitor() params = { 'A': '24', 'B': '24', 'C': '24.12345', 'D': 'true', 'E': 'false' } b.visit(params, m) self.assertEqual(params, { 'A': 24, 'B': '24', 'C': float('24.12345'), 'D': True, 'E': False })
def test_multiple_structures_list_returns_struture(self): # This is to handle the scenario when something is modeled # as a structure and instead a list of structures is returned. # For this case, a single element from the list should be parsed # For botocore, this will be the first element. # Currently, this logic may happen in s3's GetBucketLifecycle # operation. headers = {} parser = parsers.RestXMLParser() body = ( '<?xml version="1.0" ?>' '<OperationName xmlns="http://s3.amazonaws.com/doc/2006-03-01/">' ' <Foo><Bar>first_value</Bar></Foo>' ' <Foo><Bar>middle_value</Bar></Foo>' ' <Foo><Bar>last_value</Bar></Foo>' '</OperationName>') builder = model.DenormalizedStructureBuilder() output_shape = builder.with_members({ 'Foo': { 'type': 'structure', 'members': { 'Bar': { 'type': 'string', } } } }).build_model() parsed = parser.parse( { 'body': body, 'headers': headers, 'status_code': 200 }, output_shape) # Ensure the first element is used out of the list. self.assertEqual(parsed['Foo'], {'Bar': 'first_value'})
def test_unknown_shape_type(self): b = model.DenormalizedStructureBuilder() with self.assertRaises(model.InvalidShapeError): b.with_members({ 'A': { 'type': 'brand-new-shape-type', }, }).build_model()
def test_empty_values_not_added(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': {'type': 'boolean'}, }).build_model() b = shorthand.BackCompatVisitor() params = {} b.visit(params, m) self.assertEqual(params, {})
def create_argument(self, argument_model, argument_name=None): if argument_name is None: argument_name = 'foo' argument = mock.Mock() m = model.DenormalizedStructureBuilder().with_members(argument_model) argument.argument_model = m.build_model() argument.name = argument_name argument.cli_name = "--" + argument_name return argument
def test_use_shape_name_when_provided(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'string', 'shape_name': 'MyStringShape', }, }).build_model() self.assertEqual(shape.members['A'].name, 'MyStringShape')
def test_documentation_on_shape_used(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'string', 'documentation': 'MyDocs', }, }).build_model() self.assertEqual(shape.members['A'].documentation, 'MyDocs')
def test_structure_shape_builder_with_scalar_types(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': {'type': 'string'}, 'B': {'type': 'integer'}, }).build_model() self.assertIsInstance(shape, model.StructureShape) self.assertEqual(sorted(list(shape.members)), ['A', 'B']) self.assertEqual(shape.members['A'].type_name, 'string') self.assertEqual(shape.members['B'].type_name, 'integer')
def test_enum_values_on_scalar_used(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'string', 'enum': ['foo', 'bar', 'baz'], }, }).build_model() self.assertIsInstance(shape, model.StructureShape) self.assertEqual(shape.members['A'].metadata['enum'], ['foo', 'bar', 'baz'])
def test_handle_special_case_value_struct_not_documented(self): m = model.DenormalizedStructureBuilder().with_members({ 'Value': { 'type': 'string' } }).build_model() generated_example = self.shorthand_documenter.generate_shorthand_example( '--foo', m) # This is one of the special cases, we shouldn't generate any # shorthand example for this shape. self.assertIsNone(generated_example)
def test_structure_shape_with_list(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'list', 'member': { 'type': 'string' } }, }).build_model() self.assertIsInstance(shape.members['A'], model.ListShape) self.assertEqual(shape.members['A'].member.type_name, 'string')
def test_promote_to_list_of_ints(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'list', 'member': {'type': 'string'} }, }).build_model() b = shorthand.BackCompatVisitor() params = {'A': 'foo'} b.visit(params, m) self.assertEqual(params, {'A': ['foo']})
def test_min_max_used_in_metadata(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'string', 'documentation': 'MyDocs', 'min': 2, 'max': 3, }, }).build_model() metadata = shape.members['A'].metadata self.assertEqual(metadata.get('min'), 2) self.assertEqual(metadata.get('max'), 3)
def test_structure_shape_with_map_type(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'map', 'key': {'type': 'string'}, 'value': {'type': 'string'}, } }).build_model() self.assertIsInstance(shape.members['A'], model.MapShape) map_shape = shape.members['A'] self.assertEqual(map_shape.key.type_name, 'string') self.assertEqual(map_shape.value.type_name, 'string')
def test_structure_shape_with_structure_type(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'structure', 'members': { 'A-1': {'type': 'string'}, } }, }).build_model() self.assertIsInstance(shape, model.StructureShape) self.assertEqual(list(shape.members), ['A']) self.assertEqual(shape.members['A'].type_name, 'structure') self.assertEqual(list(shape.members['A'].members), ['A-1'])
def test_can_generated_nested_maps(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'map', 'key': { 'type': 'string' }, 'value': { 'type': 'string' } }, }).build_model() generated_example = self.shorthand_documenter.generate_shorthand_example( '--foo', m) self.assertIn('A={KeyName1=string,KeyName2=string}', generated_example)
def test_can_convert_list_of_integers(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'list', 'member': { 'type': 'integer', }, }, }).build_model() b = shorthand.BackCompatVisitor() params = {'A': ['1', '2']} b.visit(params, m) # We should have converted each list element to an integer # because the type of the list member is integer. self.assertEqual(params, {'A': [1, 2]})
def test_can_document_nested_lists(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'list', 'member': { 'type': 'list', 'member': { 'type': 'string' }, }, }, }).build_model() generated_example = self.shorthand_documenter.generate_shorthand_example( '--foo', m) self.assertIn('A=[[string,string],[string,string]]', generated_example)
def test_dont_promote_list_if_none_value(self): m = model.DenormalizedStructureBuilder().with_members({ 'A': { 'type': 'list', 'member': { 'type': 'structure', 'members': { 'Single': {'type': 'string'} }, }, }, }).build_model() b = shorthand.BackCompatVisitor() params = {} b.visit(params, m) self.assertEqual(params, {})
def test_nested_structure(self): b = model.DenormalizedStructureBuilder() shape = b.with_members({ 'A': { 'type': 'structure', 'members': { 'B': { 'type': 'structure', 'members': { 'C': { 'type': 'string', } } } } } }).build_model() self.assertEqual( shape.members['A'].members['B'].members['C'].type_name, 'string')
def construct_model(self, members): model_builder = model.DenormalizedStructureBuilder() return model_builder.with_members(members).build_model()