@@ -1826,6 +1826,13 @@ def sv_range_riid_gen(request: pytest.FixtureRequest) -> tuple[SchemaView, tuple
18261826 for key , value in ranges_replaced_by_defaults ["none_range" ].items ()
18271827}
18281828
1829+ induced_range_strict_errors = {
1830+ "any_of_and_exactly_one_of_range" : "ClassWithRanges slot any_of_and_exactly_one_of_range has range specified in both `exactly_one_of` and `any_of`" ,
1831+ "invalid_any_range_no_linkml_any" : "ClassWithRanges slot invalid_any_range_no_linkml_any has range specified in `exactly_one_of` or `any_of` but the slot range is not linkml:Any" ,
1832+ "invalid_any_range_enum" : "ClassWithRanges slot invalid_any_range_enum has range specified in `exactly_one_of` or `any_of` but the slot range is not linkml:Any" ,
1833+ "invalid_any_range_class" : "ClassWithRanges slot invalid_any_range_class has range specified in `exactly_one_of` or `any_of` but the slot range is not linkml:Any" ,
1834+ }
1835+
18291836
18301837def test_generated_range_schema (sv_range_riid_gen : tuple [SchemaView , tuple [str , str | None , str | None ]]) -> None :
18311838 """Tests for generation of range schemas.
@@ -1842,8 +1849,17 @@ def test_generated_range_schema(sv_range_riid_gen: tuple[SchemaView, tuple[str,
18421849 assert isinstance (sv_range , SchemaView )
18431850
18441851
1845- @pytest .mark .parametrize ("range_function" , ["slot_range" , "slot_range_as_union" , "slot_applicable_range_elements" ])
18461852@pytest .mark .parametrize ("slot_name" , ranges_no_defaults .keys ())
1853+ @pytest .mark .parametrize (
1854+ "range_function" ,
1855+ [
1856+ "slot_range" ,
1857+ "slot_range_as_union" ,
1858+ "induced_slot_range" ,
1859+ "induced_range_strict" ,
1860+ "slot_applicable_range_elements" ,
1861+ ],
1862+ )
18471863def test_slot_range (
18481864 range_function : str ,
18491865 slot_name : str ,
@@ -1859,25 +1875,37 @@ def test_slot_range(
18591875 :type sv_range_riid_gen: tuple[SchemaView, tuple[str, str | None, str | None]]
18601876 """
18611877 (sv_range , range_tuple ) = sv_range_riid_gen
1862-
1863- slots_by_name = {s .name : s for s in sv_range .class_induced_slots ("ClassWithRanges" )}
1878+ slot_object = sv_range .induced_slot (slot_name , "ClassWithRanges" )
18641879 expected = ranges_no_defaults [slot_name ]
1880+
18651881 if slot_name in ranges_replaced_by_defaults :
18661882 expected = ranges_replaced_by_defaults [slot_name ][range_tuple ]
1883+
18671884 if range_function == "slot_range" :
1868- assert slots_by_name [ slot_name ] .range == expected [0 ]
1885+ assert slot_object .range == expected [0 ]
18691886 elif range_function == "slot_range_as_union" :
1870- assert set (sv_range .slot_range_as_union (slots_by_name [ slot_name ] )) == expected [1 ]
1887+ assert set (sv_range .slot_range_as_union (slot_object )) == expected [1 ]
18711888 elif range_function == "induced_slot_range" :
1872- assert sv_range .induced_slot_range (slots_by_name [slot_name ]) == expected [2 ]
1889+ assert sv_range .induced_slot_range (slot_object ) == expected [2 ]
1890+ elif range_function == "induced_range_strict" :
1891+ # err_msg will be None if there is no error in the slot range specification
1892+ err_msg = induced_range_strict_errors .get (slot_name )
1893+ if not err_msg and expected [2 ] == set ():
1894+ err_msg = f"ClassWithRanges slot { slot_name } has no range specified"
1895+
1896+ if err_msg :
1897+ with pytest .raises (ValueError , match = err_msg ):
1898+ sv_range .induced_slot_range (slot_object , strict = True )
1899+ else :
1900+ assert sv_range .induced_slot_range (slot_object , strict = True ) == expected [2 ]
18731901 elif range_function == "slot_applicable_range_elements" :
18741902 if slot_name in ranges_replaced_by_defaults and len (expected ) < 4 :
18751903 expected = ranges_no_defaults [slot_name ]
18761904 if isinstance (expected [3 ], set ):
1877- assert set (sv_range .slot_applicable_range_elements (slots_by_name [ slot_name ] )) == expected [3 ]
1905+ assert set (sv_range .slot_applicable_range_elements (slot_object )) == expected [3 ]
18781906 else :
18791907 with pytest .raises (expected [3 ], match = "Unrecognized range: None" ):
1880- sv_range .slot_applicable_range_elements (slots_by_name [ slot_name ] )
1908+ sv_range .slot_applicable_range_elements (slot_object )
18811909 else :
18821910 pytest .fail (f"Unexpected range_function value: { range_function } " )
18831911
0 commit comments