def test_error_paths(self): """ Test various loader error situations""" fn = env.input_path('loadererror1.yaml') with self.assertRaises(ValueError, msg="Unknown slot domain should fail") as e: SchemaLoader(fn).resolve() self.assertIn('loadererror1.yaml", line 11, col 13', str(e.exception)) fn = env.input_path('loadererror2.yaml') with self.assertRaises(ValueError, msg="No Type URI") as e: SchemaLoader(fn).resolve() self.assertIn('type "string" does not declare a URI', str(e.exception)) fn = env.input_path('loadererror2a.yaml') with self.assertRaises(ValueError, msg="Optional key slot should fail") as e: SchemaLoader(fn).resolve() self.assertIn('slot: s1 - key and identifier slots cannot be optional', str(e.exception)) fn = env.input_path('loadertest1.yaml') schema = SchemaLoader(fn).resolve() self.assertEqual('string', schema.slots['s1'].range) fn = env.input_path('loadererror4.yaml') with self.assertRaises(ValueError, msg="Default prefix is not defined") as e: SchemaLoader(fn).resolve() self.assertIn('loadererror4.yaml", line 6, col 17', str(e.exception))
def test_load_raw_file(self): """ Test loading a data file """ self._verify_schema1_content( load_raw_schema(env.input_path('schema1.yaml')), 'schema1') # Verify that we can't pass source_file parameters when we've got a directory name with self.assertRaises(AssertionError): load_raw_schema(env.input_path('schema1.yaml'), source_file_size=117)
def test_missing_type_uri(self): """ A type with neither a typeof or uri is an error """ fn = env.input_path('loadererror10.yaml') with self.assertRaises(ValueError, msg="A non-typeof type has to have a URI") as e: _ = SchemaLoader(fn).resolve() self.assertIn('loadererror10.yaml", line 12, col 3', str(e.exception)) fn = env.input_path('loaderpass11.yaml') _ = SchemaLoader(fn).resolve()
def test_representation_errors(self): """ Test misformed schema elements """ fn = env.input_path('typeerror1.yaml') with self.assertRaises(ValueError): SchemaLoader(fn) fn = env.input_path('typeerror2.yaml') with self.assertRaises(ValueError): SchemaLoader(fn) fn = env.input_path('typeerror3.yaml') with self.assertRaises(ValueError): SchemaLoader(fn) fn = env.input_path('typeerror4.yaml') with self.assertRaises(ValueError): SchemaLoader(fn)
def test_dupcheck_loader(self): """ Make sure the duplicate checker finds duplicates """ with open(env.input_path('yaml1.yaml')) as f: y1 = yaml.safe_load(f) self.assertEqual(17, y1['f1']) with open(env.input_path('yaml1.yaml')) as f: with self.assertRaises(ValueError): yaml.load(f, DupCheckYamlLoader) with open(env.input_path('yaml2.yaml')) as f: with self.assertRaises(ValueError): yaml.load(f, DupCheckYamlLoader) with open(env.input_path('schema1.yaml')) as f: s1 = yaml.load(f, DupCheckYamlLoader) self.assertEqual('schema1', s1['name'])
def test_default_range(self): """ Validate default slot range settings """ schema = SchemaLoader(env.input_path('resolver1.yaml')).resolve() self.assertEqual({ 's1': 't1', 's2': 't2' }, {slot.name: slot.range for slot in schema.slots.values()}) schema = SchemaLoader(env.input_path('resolver2.yaml')).resolve() self.assertEqual({ 's1': 'string', 's2': 't2' }, {slot.name: slot.range for slot in schema.slots.values()})
def test_multi_key(self): """ Multiple keys are not supported """ fn = env.input_path('loadererror6.yaml') with self.assertRaises( ValueError, msg='Multiple keys/identifiers not allowed') as e: _ = SchemaLoader(fn).resolve() self.assertIn('multiple keys/identifiers not allowed', str(e.exception)) fn = env.input_path('loadererror7.yaml') with self.assertRaises(ValueError, msg="Two or more keys are not allowed") as e: _ = SchemaLoader(fn).resolve() self.assertIn('multiple keys/identifiers not allowed', str(e.exception))
def test_empty_range(self): """ A type must have either a base or a parent """ fn = env.input_path('loadererror5.yaml') with self.assertRaises(ValueError, msg="Range error should be raised") as e: _ = SchemaLoader(fn).resolve() self.assertIn('loadererror5.yaml", line 9, col 3', str(e.exception))
def test_undefined_subset(self): """ Throw an error on an undefined subset reference """ fn = env.input_path('loadererror11.yaml') with self.assertRaises(ValueError, msg="Subset references must be valid") as e: _ = SchemaLoader(fn).resolve() self.assertIn('loadererror11.yaml", line 22, col 16', str(e.exception))
def test_as_yaml(self): """ Test the YAML output representation """ schema = self.fix_schema_metadata( load_raw_schema(env.input_path('schema4.yaml'))) env.eval_single_file(env.expected_path('schema4.yaml'), as_yaml(schema), filtr=lambda s: s)
def test_multi_schemas(self): """ Test multiple schemas in the same file """ def check_types(s: SchemaDefinition) -> None: output = env.expected_path('schema4.json') if not os.path.exists(output): with open(output, 'w') as f: f.write( as_json( JsonObj( **{ k: as_dict(loads(as_json(v))) for k, v in s.types.items() }))) with open(output) as f: expected = as_dict(load(f)) self.assertEqual( expected, {k: as_dict(loads(as_json(v))) for k, v in s.types.items()}) s.types = None self._verify_schema1_content( load_raw_schema(env.input_path('schema4.yaml')), 'schema4', check_types)
def test_uri_and_curie(self): """ Compile a model of URI's and Curies and then test the various types """ self.single_file_generator('py', PythonGenerator, filtr=metadata_filter, comparator=compare_python) # Check that the interpretations are correct self.single_file_generator( 'jsonld', ContextGenerator, filtr=ldcontext_metadata_filter, comparator=lambda expected, actual: compare_rdf( expected, actual, fmt="json-ld")) self.single_file_generator('json', JSONLDGenerator, filtr=json_metadata_filter) module = compile_python(env.expected_path(self.model_name + '.py')) curie_obj = module.C1("ex:obj1", hasCurie="ex:curie", hasURI="http://example.org/test/uri", hasNcName="A123", id2="ex:id2") instance_jsonld = loads('{ "ex": "http://example.org/test/inst#" }') g = as_rdf( curie_obj, [env.input_path(self.model_name + '.jsonld'), instance_jsonld]) env.eval_single_file(env.expected_path('uriandcurie.ttl'), g.serialize(format='ttl').decode(), lambda s: s, compare_rdf)
def test_multi_usages_3(self): """ Illegal alias usage """ with self.assertRaises(ValueError) as e: schema = SchemaLoader( env.input_path('multi_usages_3.yaml')).resolve() self.assertIn( 'Class: "child_class1" - alias not permitted in slot_usage slot: foo', str(e.exception))
def test_mergeerror1(self): """ Test conflicting definitions path """ fn = env.input_path('mergeerror1.yaml') with self.assertRaises(ValueError) as ve: SchemaLoader(fn) self.assertEqual( "Conflicting URIs (http://example.org/schema2, http://example.org/schema1) for item: c1", str(ve.exception))
def test_pred_types(self): self.env.generate_single_file( 'owl2.owl', lambda: OwlSchemaGenerator(env.input_path('owl2.yaml'), importmap=env.import_map).serialize(), filtr=filtr, comparator=compare_rdf, value_is_returned=True)
def test_multi_usages_2(self): """ Slot usage chain with starting alias """ schema = SchemaLoader(env.input_path('multi_usages_2.yaml')).resolve() self._eval_expected(schema, 's1', 'value', 'root_class', None, None, 'string') self._eval_expected(schema, 'child_class1_s1', 'value', 'child_class1', 's1', 's1', 'boolean') self._eval_expected(schema, 'child_class2_s1', 'value', 'child_class2', 'child_class1_s1', 's1', 'integer') self._eval_expected(schema, 'child_class3_s1', 'value', 'child_class3', 'child_class2_s1', 's1', 'integer') env.eval_single_file(env.expected_path('multi_usages_2.yaml'), as_yaml(schema), filtr=yaml_filter)
def test_key_and_id(self): """ A slot cannot be both a key and an identifier """ fn = env.input_path('loadererror8.yaml') with self.assertRaises( ValueError, msg="A slot cannot be both a key and identifier") as e: _ = SchemaLoader(fn).resolve() self.assertIn( 'A slot cannot be both a key and identifier at the same time', str(e.exception)) fn = env.input_path('loadererror9.yaml') with self.assertRaises( ValueError, msg="A slot cannot be both a key and identifier") as e: _ = SchemaLoader(fn).resolve() self.assertIn( 'A slot cannot be both a key and identifier at the same time', str(e.exception))
def test_type_uri(self): """ Validate type URI's and the fact that they aren't inherited """ schema = SchemaLoader(env.input_path('resolver2.yaml')).resolve() self.assertEqual( { 'string': 'xsd:string', 't1': 'xsd:string', 't2': 'xsd:int', 't3': 'xsd:string' }, {t.name: t.uri for t in schema.types.values()})
def test_importmap(self): """ Test the importmap parameter """ fn = env.input_path('import_test_1.yaml') importmap = { "http://example.org/import_test_2": "import_test_2", "loc/imp3": "import_test_3", "base:import_test_4": "http://example.org/import_test_4", "http://example.org/import_test_4": "import_test_4", "types": "http://w3id.org/biolink/biolinkml/types" } self.env.generate_single_file( 'import_test_1.json', lambda: as_json(SchemaLoader(fn, importmap=importmap).resolve()), filtr=json_metadata_filter)
def test_element_slots(self): """ Test all element slots and their inheritence """ schema = SchemaLoader(env.input_path('resolver3.yaml')).resolve() x = { k: v for k, v in as_dict(schema.slots['s1']).items() if v is not None and v != [] } outfile = env.expected_path('resolver3.json') if not os.path.exists(outfile): with open(outfile, 'w') as f: f.write(as_json(JsonObj(**x))) with open(outfile) as f: expected = as_dict(load(f)) self.assertEqual(expected, x)
def eval_synopsis(self, base_name: str, source: Optional[str] = None) -> None: schema = SchemaLoader(source if source else env.input_path(base_name + '.yaml'), importmap=env.import_map) schema.resolve() self.summary = schema.synopsis.summary() self.env.generate_single_file( base_name + '.errs', lambda: '\n'.join(schema.synopsis.errors()), value_is_returned=True) self.env.generate_single_file(base_name + '.synopsis', lambda: self.summary, value_is_returned=True)
def test_slot_class_paths(self): """ Test for aliased slot name, class identifier path and slot type path """ gen = GeneratorTest(env.input_path('ownalltest.yaml')) gen.sort_class_slots = True self.assertEqual(['s1', 's5', 's6', 's2', 's3', 's4'], [ gen.aliased_slot_name(s.name) for s in gen.all_slots(cast(ClassDefinitionName, 'c4')) ]) self.assertEqual(['s5', 's1', 's6', 's2', 's3', 's4'], [ gen.aliased_slot_name(s) for s in gen.all_slots(cast(ClassDefinitionName, 'c5')) ]) self.assertEqual( { 'c4_s1': ['int'], 'c4_s5': ['Bool', 'T5'], 'c4_s6': ['int', 'C1S1', 'C2S1', 'C3S1', 'C4S1'], 's2': ['int', 'C1S1'], 's3': ['int', 'T2', 'T3'], 's4': ['Bool'] }, { s.name: gen.slot_range_path(s) for s in gen.all_slots(cast(ClassDefinitionName, 'c4')) }) self.assertEqual( { 'c4_s5': ['Bool', 'T5'], 'c5_s1': ['int'], 'c5_s6': ['str'], 's2': ['int', 'C1S1'], 's3': ['int', 'T2', 'T3'], 's4': ['Bool'] }, { s.name: gen.slot_range_path(s) for s in gen.all_slots(cast(ClassDefinitionName, 'c5')) }) self.assertEqual({ 's1': ['int'], 's3': ['int', 'T2', 'T3'] }, { s.name: gen.slot_range_path(s) for s in gen.all_slots(cast(ClassDefinitionName, 'c1')) })
def test_visitors(self): """ Test the generator visitor functions """ gen = GeneratorTest(env.input_path('generator1.yaml')) gen.serialize() self.assertEqual(expected1, gen.visited) gen.visit_all_class_slots = False gen.serialize() self.assertEqual(expected2, gen.visited) gen.visit_all_class_slots = True gen.visits_are_sorted = True gen.serialize() self.assertEqual(expected3, gen.visited) gen.visits_are_sorted = False gen.sort_class_slots = True gen.serialize() self.assertEqual(expected4, gen.visited) gen.sort_class_slots = False gen.visit_class_return = False gen.serialize() self.assertEqual(expected5, gen.visited)
def test_import_from_url(self): """ Validate namespace bindings """ shex = ShExGenerator(env.input_path('import_test_l2.yaml')).serialize() self.assertEqual( """BASE <http://example.org/l2/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX l1: <http://example.org/l1/> PREFIX base: <http://example.org/b/> l1:Int xsd:integer base:String xsd:string base:BaseClass CLOSED { ( $base:BaseClass_tes base:base_slot @base:String ? ; rdf:type [ base:BaseClass ] ? ) } l1:L1Class ( CLOSED { ( $l1:L1Class_tes ( l1:l1_slot1 @base:String ? ; l1:l1_slot2 @l1:Int ? ) ; rdf:type [ l1:L1Class ] ? ) } OR @<L2Class> ) <L2Class> CLOSED { ( $<L2Class_tes> ( &l1:L1Class_tes ; rdf:type [ l1:L1Class ] ? ; <l2_slot1> @base:String ? ; <l2_slot2> @l1:Int ? ) ; rdf:type [ <L2Class> ] ? ) }""", shex.strip())
def test_inherited_slot(self): """ Validate default slot range settings """ schema = SchemaLoader(env.input_path('inherited_slots.yaml')).resolve() self.assertTrue('same as' in schema.classes['named thing'].slots)
def test_name_from_sourcefile(self): """ Test no identifier at all """ with self.assertRaises(ValueError): load_raw_schema(env.input_path('schema5.yaml'))
def test_own_slots(self): """ Test the generator own_slots and all_slots helper functions """ gen = GeneratorTest(env.input_path('ownalltest.yaml')) gen.sort_class_slots = True self.assertEqual( ['s6'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'at1'))]) self.assertEqual( ['s6'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'at1'))]) self.assertEqual(['s6'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'at1'), cls_slots_first=True) ]) self.assertEqual( ['s5', 's6'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'm2'))]) self.assertEqual( ['s5', 's6'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'm2'))]) self.assertEqual(['s5', 's6'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'm2'), cls_slots_first=True) ]) self.assertEqual( ['s4'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'm1'))]) self.assertEqual( ['s4'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'm1'))]) self.assertEqual(['s4'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'm1'), cls_slots_first=True) ]) self.assertEqual( ['s1', 's3'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'c1'))]) self.assertEqual( ['s1', 's3'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c1'))]) self.assertEqual(['s1', 's3'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c1'), cls_slots_first=True) ]) self.assertEqual( ['s2', 's4'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'c2'))]) self.assertEqual( ['s1', 's2', 's3', 's4'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c2'))]) self.assertEqual(['s2', 's4', 's1', 's3'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c2'), cls_slots_first=True) ]) self.assertEqual( ['s5', 's6'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'c3'))]) self.assertEqual( ['s1', 's2', 's3', 's4', 's5', 's6'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c3'))]) self.assertEqual(['s5', 's6', 's2', 's4', 's1', 's3'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c3'), cls_slots_first=True) ]) self.assertEqual( ['c4_s1', 'c4_s5', 'c4_s6'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'c4'))]) self.assertEqual( ['c4_s1', 'c4_s5', 'c4_s6', 's2', 's3', 's4'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c4'))]) self.assertEqual(['c4_s1', 'c4_s5', 'c4_s6', 's2', 's4', 's3'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c4'), cls_slots_first=True) ]) self.assertEqual( ['c5_s1', 'c5_s6'], [s.name for s in gen.own_slots(cast(ClassDefinitionName, 'c5'))]) self.assertEqual( ['c4_s5', 'c5_s1', 'c5_s6', 's2', 's3', 's4'], [s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c5'))]) self.assertEqual(['c5_s1', 'c5_s6', 'c4_s5', 's2', 's4', 's3'], [ s.name for s in gen.all_slots(cast(ClassDefinitionName, 'c5'), cls_slots_first=True) ])
def test_load_text(self): """ Test loading straight text """ with open(env.input_path('schema1.yaml')) as f: self._verify_schema1_content( load_raw_schema(f.read(), 'schema1.yaml', "Mon Dec 31 11:25:38 2018", 76), 'schema1')
def test_orphan_slot_usage(self): """ Make sure an orphan slot_usage works """ # The bug is that this goes into an endless loop output_dir = env.temp_file_path('slottest') GolrSchemaGenerator(env.input_path('orphan_slot_usage.yaml')).serialize(directory=output_dir)
def test_as_json(self): schema = self.fix_schema_metadata( load_raw_schema(env.input_path('schema6.yaml'))) env.eval_single_file(env.expected_path('schema6.json'), as_json(schema), filtr=lambda s: s)