def test_meta_attr_declarations_group(self): """ <xs:group name="attrDecls"> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="attribute" type="xs:attribute"/> <xs:element name="attributeGroup" type="xs:attributeGroupRef"/> </xs:choice> <xs:element ref="xs:anyAttribute" minOccurs="0"/> </xs:sequence> </xs:group> """ group = self.schema_class.meta_schema.groups['attrDecls'] model = ModelVisitor(group) for match in [False, False, True]: self.check_advance(model, match) self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model) self.check_advance_true(model) self.assertEqual(model.element, group[0][0]) model = ModelVisitor(group) for match in [False, True, False, False]: self.check_advance(model, match) self.assertEqual(model.element, group[1]) model = ModelVisitor(group) for match in [False, True, True, False, True, False, False]: self.check_advance(model, match) self.assertEqual(model.element, group[1])
def test_meta_simple_derivation_model(self): """ <xs:group name="simpleDerivation"> <xs:choice> <xs:element ref="xs:restriction"/> <xs:element ref="xs:list"/> <xs:element ref="xs:union"/> </xs:choice> </xs:group> """ group = XMLSchema10.meta_schema.groups['simpleDerivation'] model = ModelVisitor(group) self.check_advance_true(model) # <restriction> match self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model) # <list> not match with <restriction> self.check_advance_true(model) # <list> match self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model) # <union> not match with <restriction> self.check_advance_false(model) # <union> not match with <list> self.check_advance_true(model) # <union> match self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model) # <other> not match with <restriction> self.check_advance_false(model) # <other> not match with <list> self.check_advance_false( model, [(group, 0, group[:])]) # <other> not match with <union> self.assertIsNone(model.element)
def test_issue_086(self): issue_086_xsd = casepath('issues/issue_086/issue_086.xsd') schema = self.schema_class(issue_086_xsd) group = schema.types['Foo'].content_type # issue_086-1.xml sequence simulation model = ModelVisitor(group) self.assertEqual(model.element, group[0]) self.check_advance_true(model) # <header> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_true(model) # <a> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_true(model) # <a> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_false(model) self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_false(model) self.assertEqual(model.element, group[1][1][0]) # 'b' element self.check_advance_true(model) # <b> matching self.assertEqual(model.element, group[1][1][0]) # 'b' element self.check_advance_true(model) # <b> matching self.check_advance_false(model) self.assertEqual( model.element, group[1][0][0]) # 'a' element (choice group restarted) self.check_advance_false(model) self.check_advance_false(model) self.assertEqual(model.element, group[1][2][0]) # 'c' element self.check_advance_true(model) # <c> matching self.assertEqual(model.element, group[1][2][0]) # 'c' element self.check_advance_true(model) # <c> matching self.check_stop(model) # issue_086-2.xml sequence simulation model = ModelVisitor(group) self.check_advance_true(model) # <header> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_false(model) self.assertEqual(model.element, group[1][1][0]) # 'b' element self.check_advance_true(model) # <b> matching self.assertEqual(model.element, group[1][1][0]) # 'b' element self.check_advance_true(model) # <b> matching self.check_advance_false(model) self.assertEqual( model.element, group[1][0][0]) # 'a' element (choice group restarted) self.check_advance_false(model) self.check_advance_false(model) self.assertEqual(model.element, group[1][2][0]) # 'c' element self.check_advance_true(model) # <c> matching self.assertEqual(model.element, group[1][2][0]) # 'c' element self.check_advance_true(model) # <c> matching self.check_advance_false(model) self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_true(model) # <a> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_advance_true(model) # <a> matching self.assertEqual(model.element, group[1][0][0]) # 'a' element self.check_stop(model)
def test_iter_collapsed_content_with_repeated_elements(self): schema = self.get_schema(""" <xs:element name="A" type="A_type" /> <xs:complexType name="A_type"> <xs:sequence> <xs:element name="B1" minOccurs="0" /> <xs:element name="B2" minOccurs="0" maxOccurs="unbounded" /> <xs:element name="B3" maxOccurs="unbounded" /> <xs:element name="B4" /> <xs:element name="B5" maxOccurs="unbounded" /> <xs:element name="B6" minOccurs="0" /> <xs:element name="B7" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> """) model = ModelVisitor(schema.types['A_type'].content_type) content = [('B3', 10), ('B4', None), ('B5', True), ('B5', False), ('B6', 'alpha'), ('B7', 20)] self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B3', 10), ('B3', 11), ('B3', 12), ('B4', None), ('B5', True), ('B5', False), ('B6', 'alpha'), ('B7', 20), ('B7', 30)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B3', 10), ('B3', 11), ('B3', 12), ('B4', None), ('B5', True), ('B5', False)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content)
def test_model_group7(self): group = self.models_schema.types['complexType7'].content_type model = ModelVisitor(group) self.assertEqual(model.element, group[0][0]) self.check_stop(model, [(group[0][0], 0, [group[0][0]])]) group = self.models_schema.types['complexType7_emptiable'].content_type model = ModelVisitor(group) self.assertEqual(model.element, group[0][0]) self.check_stop(model)
def test_iter_collapsed_content_with_optional_elements(self): schema = self.get_schema(""" <xs:element name="A" type="A_type" /> <xs:complexType name="A_type"> <xs:sequence> <xs:element name="B1" minOccurs="0" /> <xs:element name="B2" minOccurs="0" /> <xs:element name="B3" /> <xs:element name="B4" /> <xs:element name="B5" /> <xs:element name="B6" minOccurs="0" /> <xs:element name="B7" /> </xs:sequence> </xs:complexType> """) model = ModelVisitor(schema.types['A_type'].content) content = [('B3', 10), ('B4', None), ('B5', True), ('B6', 'alpha'), ('B7', 20)] model.restart() self.assertListEqual( list(model.iter_collapsed_content(content)), content ) content = [('B3', 10), ('B5', True), ('B6', 'alpha'), ('B7', 20)] # Missing B4 model.restart() self.assertListEqual( list(model.iter_collapsed_content(content)), content )
def test_vehicles_model(self): # Sequence with two not-emptiable single-occurs elements group = self.vh_schema.elements['vehicles'].type.content_type model = ModelVisitor(group) self.check_advance_true(model) # <cars> self.check_advance_true(model) # <bikes> self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_true(model) # <cars> self.check_advance_true(model) # <bikes> self.check_advance_true(model, ValueError) # <bikes> self.assertIsNone(model.element)
def test_cars_model(self): # Emptiable 1:1 sequence with one emptiable and unlimited element. group = self.vh_schema.elements['cars'].type.content_type model = ModelVisitor(group) self.check_advance_true(model) # <car> self.check_advance_true(model) # <car> self.check_advance_true(model) # <car> self.check_advance_false(model) # (end) self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model) # <not-a-car> self.assertIsNone(model.element)
def test_collection_model(self): # Sequence with one not-emptiable and unlimited element. group = self.col_schema.elements['collection'].type.content model = ModelVisitor(group) self.check_advance_true(model) # <car> self.check_advance_true(model) # <car> self.check_advance_true(model) # <car> self.check_advance_true(model) # <car> self.check_advance_false(model) # (end) self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_false(model, [(group[0], 0, [group[0]])]) # <not-a-car> self.assertIsNone(model.element)
def test_empty_choice_groups(self): schema = self.schema_class("""<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:group name="group1"> <xs:sequence> <xs:choice minOccurs="0"> <xs:choice minOccurs="0"/> </xs:choice> <xs:element name="elem1"/> </xs:sequence> </xs:group> <xs:element name="root"> <xs:complexType> <xs:choice> <xs:group ref="group1"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema>""") xml_data = "<root><elem1/></root>" model = ModelVisitor(schema.elements['root'].type.content_type) self.assertIsInstance(model.element, XsdElement) self.assertEqual(model.element.name, 'elem1') self.assertIsNone(schema.validate(xml_data))
def test_model_group6(self): group = self.models_schema.groups['group6'] model = ModelVisitor(group) self.assertEqual(model.element, group[0][0]) self.check_advance_true(model) # match choice with <elem1> self.check_advance_true(model) # match choice with <elem2> self.assertIsNone(model.element)
def test_model_group4(self): group = self.models_schema.groups['group4'] model = ModelVisitor(group) self.assertEqual(model.element, group[0]) for match in [True, False, True]: self.check_advance(model, match) self.check_stop(model)
def test_meta_simple_restriction_model(self): """ <!-- XSD 1.0 --> <xs:group name="facets"> <xs:choice> <xs:element ref="xs:minExclusive"/> <xs:element ref="xs:minInclusive"/> <xs:element ref="xs:maxExclusive"/> <xs:element ref="xs:maxInclusive"/> <xs:element ref="xs:totalDigits"/> <xs:element ref="xs:fractionDigits"/> <xs:element ref="xs:length"/> <xs:element ref="xs:minLength"/> <xs:element ref="xs:maxLength"/> <xs:element ref="xs:enumeration"/> <xs:element ref="xs:whiteSpace"/> <xs:element ref="xs:pattern"/> </xs:choice> </xs:group> <xs:group name="simpleRestrictionModel"> <xs:sequence> <xs:element name="simpleType" type="xs:localSimpleType" minOccurs="0"/> <xs:group ref="xs:facets" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:group> <!-- XSD 1.1 --> <xs:group name="simpleRestrictionModel"> <xs:sequence> <xs:element name="simpleType" type="xs:localSimpleType" minOccurs="0"/> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="xs:facet"/> <!-- Use a substitution group --> <xs:any processContents="lax" namespace="##other"/> </xs:choice> </xs:sequence> </xs:group> """ # Sequence with an optional single element and an optional unlimited choice. group = self.schema_class.meta_schema.groups['simpleRestrictionModel'] model = ModelVisitor(group) if self.schema_class.XSD_VERSION == '1.0': self.assertEqual(model.element, group[0]) self.check_advance_true(model) # <simpleType> match self.assertEqual(model.element, group[1][0][0]) self.check_advance_false(model) # <maxExclusive> do not match self.assertEqual(model.element, group[1][0][1]) self.check_advance_false(model) # <maxExclusive> do not match self.assertEqual(model.element, group[1][0][2]) self.check_advance_true(model) # <maxExclusive> match self.assertEqual(model.element, group[1][0][0]) for _ in range(12): self.check_advance_false( model ) # no match for all the inner choice group "xs:facets" self.assertIsNone(model.element)
def test_schema_document_model(self): group = self.schema_class.meta_schema.elements[ 'schema'].type.content_type # A schema model with a wrong tag model = ModelVisitor(group) self.assertEqual(model.element, group[0][0]) self.check_advance_false(model) # eg. anyAttribute self.check_stop(model)
def test_model_group5(self): group = self.models_schema.groups['group5'] model = ModelVisitor(group) self.assertEqual(model.element, group[0][0]) for _ in range(5): # match [<elem1> .. <elem5>] self.check_advance_true(model) self.assertEqual(model.element.name, 'elem6') self.check_advance_true(model) # match choice with <elem6> self.check_stop(model)
def test_complex_type_model(self): """ <xs:group name="complexTypeModel"> <xs:choice> <xs:element ref="xs:simpleContent"/> <xs:element ref="xs:complexContent"/> <xs:sequence> <xs:group ref="xs:typeDefParticle" minOccurs="0"/> <xs:group ref="xs:attrDecls"/> </xs:sequence> </xs:choice> </xs:group> <xs:group name="typeDefParticle"> <xs:choice> <xs:element name="group" type="xs:groupRef"/> <xs:element ref="xs:all"/> <xs:element ref="xs:choice"/> <xs:element ref="xs:sequence"/> </xs:choice> </xs:group> """ group = self.schema_class.meta_schema.groups['complexTypeModel'] model = ModelVisitor(group) self.assertEqual(model.element, group[0]) self.check_advance_true(model) # <simpleContent> match self.assertIsNone(model.element) model.restart() self.assertEqual(model.element, group[0]) self.check_advance_false(model) self.check_advance_true(model) # <complexContent> match self.assertIsNone(model.element) model.restart() self.assertEqual(model.element, group[0]) for match in [False, False, False, False, True]: self.check_advance(model, match) # <all> match self.check_stop(model) self.assertIsNone(model.element) model.restart() self.assertEqual(model.element, group[0]) for match in [ False, False, False, False, True, False, True, False, False, False ]: self.check_advance(model, match) # <all> match, <attributeGroup> match self.assertIsNone(model.element)
def test_meta_schema_top_model(self): """ <xs:group name="schemaTop"> <xs:choice> <xs:group ref="xs:redefinable"/> <xs:element ref="xs:element"/> <xs:element ref="xs:attribute"/> <xs:element ref="xs:notation"/> </xs:choice> </xs:group> <xs:group name="redefinable"> <xs:choice> <xs:element ref="xs:simpleType"/> <xs:element ref="xs:complexType"/> <xs:element ref="xs:group"/> <xs:element ref="xs:attributeGroup"/> </xs:choice> </xs:group> """ group = self.schema_class.meta_schema.groups['schemaTop'] model = ModelVisitor(group) self.assertEqual(model.element, group[0][0][0]) self.check_advance_false(model) # <simpleType> doesn't match self.assertEqual(model.element, group[0][0][1]) self.check_advance_true(model) # <complexType> matches self.assertIsNone(model.element) model.restart() self.assertEqual(model.element, group[0][0][0]) self.check_advance_false(model) # <simpleType> doesn't match self.assertEqual(model.element, group[0][0][1]) self.check_advance_false(model) # <complexType> doesn't match self.assertEqual(model.element, group[0][0][2]) self.check_advance_false(model) # <group> doesn't match self.assertEqual(model.element, group[0][0][3]) self.check_advance_false(model) # <attributeGroup> doesn't match self.assertEqual(model.element, group[1]) self.check_advance_false(model) # <element> doesn't match self.assertEqual(model.element, group[2]) self.check_advance_false(model) # <attribute> doesn't match self.assertEqual(model.element, group[3]) self.check_advance_false( model, [(group, 0, group[0][0][:] + group[1:])]) # <notation> doesn't match model.restart() self.assertEqual(model.element, group[0][0][0]) self.check_advance_false(model) # <simpleType> doesn't match self.assertEqual(model.element, group[0][0][1]) self.check_advance_false(model) # <complexType> doesn't match self.assertEqual(model.element, group[0][0][2]) self.check_advance_false(model) # <group> doesn't match self.assertEqual(model.element, group[0][0][3]) self.check_advance_false(model) # <attributeGroup> doesn't match self.assertEqual(model.element, group[1]) self.check_advance_false(model) # <element> doesn't match self.assertEqual(model.element, group[2]) self.check_advance_true(model) # <attribute> doesn't match self.assertIsNone(model.element)
def test_person_type_model(self): # Sequence with four single elements, last two are also emptiable. group = self.col_schema.types['personType'].content model = ModelVisitor(group) self.check_advance_true(model) # <name> self.check_advance_true(model) # <born> self.check_advance_true(model) # <dead> self.check_advance_true(model) # <qualification> self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_true(model) # <name> self.check_advance_true(model) # <born> self.check_stop(model) self.assertIsNone(model.element) model = ModelVisitor(group) self.check_advance_true(model) # <name> match self.check_advance_false(model, [(group[1], 0, [group[1]])]) # <born> missing! self.check_advance_true(model) # <dead> match self.check_stop(model) # <qualification> is optional self.assertIsNone(model.element)
def test_model_group2(self): group = self.models_schema.groups['group2'] model = ModelVisitor(group) self.assertEqual(model.element, group[0]) for _ in range(3): self.check_advance_false(model) # group1 do not match self.assertEqual(model.element, group[1][0][0][2]) # <elem3> of group1 for _ in range(8): self.check_advance_false(model) self.assertEqual(model.element, group[2]) # <elem12> self.check_advance_false(model) self.assertEqual(model.element, group[3]) # <elem13> self.check_advance_false(model) self.assertIsNone(model.element)
def test_empty_choice_groups(self): schema = self.schema_class("""<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:group name="group1"> <xs:sequence> <xs:choice minOccurs="0"> <xs:choice minOccurs="0"/> </xs:choice> <xs:element name="elem1"/> </xs:sequence> </xs:group> <xs:element name="root"> <xs:complexType> <xs:choice> <xs:group ref="group1"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema>""") xml_data = "<root><elem1/></root>" model = ModelVisitor(schema.elements['root'].type.content) self.assertIsInstance(model.element, XsdElement) self.assertEqual(model.element.name, 'elem1') self.assertIsNone(schema.validate(xml_data)) # W3C test group 'complex022' schema = self.schema_class("""<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="root"> <xs:complexType> <xs:choice/> </xs:complexType> </xs:element> </xs:schema>""") reason = "an empty 'choice' group with minOccurs > 0 cannot validate any content" with self.assertRaises(XMLSchemaValidationError) as ctx: schema.validate("<root><elem1/></root>") self.assertIn(reason, str(ctx.exception)) with self.assertRaises(XMLSchemaValidationError) as ctx: schema.validate("<root/>") self.assertIn(reason, str(ctx.exception))
def test_model_group1(self): group = self.models_schema.groups['group1'] model = ModelVisitor(group) self.assertEqual(model.element, group[0]) self.check_stop(model) model.restart() self.assertEqual(model.element, group[0]) for _ in range(3): self.check_advance_false(model) self.assertIsNone(model.element) model.restart() for match in [False, True, False]: self.check_advance(model, match) self.assertIsNone(model.element)
def test_iter_collapsed_content_with_single_elements(self): schema = self.get_schema(""" <xs:element name="A" type="A_type" /> <xs:complexType name="A_type"> <xs:sequence> <xs:element name="B1" /> <xs:element name="B2" /> <xs:element name="B3" /> </xs:sequence> </xs:complexType> """) model = ModelVisitor(schema.types['A_type'].content_type) content = [('B1', 'abc'), ('B2', 10), ('B3', False)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B3', False), ('B1', 'abc'), ('B2', 10)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B1', 'abc'), ('B3', False), ('B2', 10)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B1', 'abc'), ('B1', 'def'), ('B2', 10), ('B3', False)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), [('B1', 'abc'), ('B2', 10), ('B3', False), ('B1', 'def')]) content = [('B1', 'abc'), ('B2', 10), ('X', None)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('X', None), ('B1', 'abc'), ('B2', 10), ('B3', False)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content)
def test_iter_collapsed_content_with_repeated_groups(self): schema = self.get_schema(""" <xs:element name="A" type="A_type" /> <xs:complexType name="A_type"> <xs:sequence minOccurs="1" maxOccurs="2"> <xs:element name="B1" minOccurs="0" /> <xs:element name="B2" minOccurs="0" /> </xs:sequence> </xs:complexType> """) model = ModelVisitor(schema.types['A_type'].content_type) content = [('B1', 1), ('B1', 2), ('B2', 3), ('B2', 4)] self.assertListEqual(list(model.iter_collapsed_content(content)), [('B1', 1), ('B2', 3), ('B1', 2), ('B2', 4)]) # Model broken by unknown element at start content = [('X', None), ('B1', 1), ('B1', 2), ('B2', 3), ('B2', 4)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B1', 1), ('X', None), ('B1', 2), ('B2', 3), ('B2', 4)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B1', 1), ('B1', 2), ('X', None), ('B2', 3), ('B2', 4)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), content) content = [('B1', 1), ('B1', 2), ('B2', 3), ('X', None), ('B2', 4)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), [('B1', 1), ('B2', 3), ('B1', 2), ('X', None), ('B2', 4)]) content = [('B1', 1), ('B1', 2), ('B2', 3), ('B2', 4), ('X', None)] model.restart() self.assertListEqual(list(model.iter_collapsed_content(content)), [('B1', 1), ('B2', 3), ('B1', 2), ('B2', 4), ('X', None)])
def test_sort_content(self): # test of ModelVisitor's sort_content/iter_unordered_content schema = self.get_schema(""" <xs:element name="A" type="A_type" /> <xs:complexType name="A_type"> <xs:sequence> <xs:element name="B1" type="xs:string"/> <xs:element name="B2" type="xs:integer"/> <xs:element name="B3" type="xs:boolean"/> </xs:sequence> </xs:complexType> """) model = ModelVisitor(schema.types['A_type'].content_type) self.assertListEqual( model.sort_content([('B2', 10), ('B1', 'abc'), ('B3', True)]), [('B1', 'abc'), ('B2', 10), ('B3', True)]) self.assertListEqual( model.sort_content([('B3', True), ('B2', 10), ('B1', 'abc')]), [('B1', 'abc'), ('B2', 10), ('B3', True)]) self.assertListEqual( model.sort_content([('B2', 10), ('B4', None), ('B1', 'abc'), ('B3', True)]), [('B1', 'abc'), ('B2', 10), ('B3', True), ('B4', None)]) content = [('B2', 10), ('B4', None), ('B1', 'abc'), (1, 'hello'), ('B3', True)] self.assertListEqual(model.sort_content(content), [(1, 'hello'), ('B1', 'abc'), ('B2', 10), ('B3', True), ('B4', None)]) content = [(2, 'world!'), ('B2', 10), ('B4', None), ('B1', 'abc'), (1, 'hello'), ('B3', True)] self.assertListEqual(model.sort_content(content), [(1, 'hello'), ('B1', 'abc'), (2, 'world!'), ('B2', 10), ('B3', True), ('B4', None)]) # With a dict-type argument content = ordered_dict_class([('B2', [10]), ('B1', ['abc']), ('B3', [True])]) self.assertListEqual(model.sort_content(content), [('B1', 'abc'), ('B2', 10), ('B3', True)]) content = ordered_dict_class([('B2', [10]), ('B1', ['abc']), ('B3', [True]), (1, 'hello')]) self.assertListEqual(model.sort_content(content), [(1, 'hello'), ('B1', 'abc'), ('B2', 10), ('B3', True)]) # With partial content self.assertListEqual(model.sort_content([]), []) self.assertListEqual(model.sort_content([('B1', 'abc')]), [('B1', 'abc')]) self.assertListEqual(model.sort_content([('B2', 10)]), [('B2', 10)]) self.assertListEqual(model.sort_content([('B3', True)]), [('B3', True)]) self.assertListEqual(model.sort_content([('B3', True), ('B1', 'abc')]), [('B1', 'abc'), ('B3', True)]) self.assertListEqual(model.sort_content([('B2', 10), ('B1', 'abc')]), [('B1', 'abc'), ('B2', 10)]) self.assertListEqual(model.sort_content([('B3', True), ('B2', 10)]), [('B2', 10), ('B3', True)])