:- module(test_rdf11, [ test_rdf11/0, set_graph/1 % +Name ]). :- include(local_test). :- use_module(library(semweb/rdf11)). :- use_module(library(plunit)). :- use_module(library(debug)). :- use_module(library(yall)). :- use_module(library(apply)). test_rdf11 :- rdf_reset_db, run_tests([ literal, enumerate, query_numerical, lexical_comparison, query_lang, query_mixed, query_search, migrate ]). :- discontiguous graph/2. % Allow for name-space declarations in test options. The body should be % properly compiled anyway. term_expansion((test(Name, Options0) :- Body), (test(Name, Options1) :- Body)) :- rdf_global_term(Options0, Options1). /******************************* * LITERAL ASSERT/QUERY * *******************************/ :- begin_tests(literal, [cleanup(rdf_reset_db)]). test(integer, L == 42^^xsd:integer) :- rdf_assert(integer, p1, 42), rdf(integer, p1, L). test(float, L == 3.2^^xsd:double) :- rdf_assert(float, p1, 3.2), rdf(float, p1, L). test(float, [L == 3.0^^xsd:float]) :- rdf_assert(float, p2, "3."^^xsd:float), rdf(float, p2, L). test(float, [L == 0.3^^xsd:float]) :- rdf_assert(float, p3, ".3"^^xsd:float), rdf(float, p3, L). test(byte, L == 97^^xsd:byte) :- rdf_assert(byte, p1, 97^^xsd:byte), rdf(byte, p1, L). test(byte, error(domain_error(T, 200))) :- rdf_equal(T, xsd:byte), rdf_assert(byte, p2, 200^^xsd:byte). test(boolean, L == true^^xsd:boolean) :- rdf_assert(boolean, p1, true), rdf(boolean, p1, L). test(boolean, L == false^^xsd:boolean) :- rdf_assert(boolean, p2, 0^^xsd:boolean), rdf(boolean, p2, L). test(boolean) :- rdf_assert(boolean, p3, true), rdf(boolean, p3, true). test(string, L == "hello world"^^xsd:string) :- rdf_assert(string, p1, "hello world"), rdf(string, p1, L). test(lang, L == "hello world"@nl) :- rdf_assert(string, p2, "hello world"@'NL'), rdf(string, p2, L). test(lang, L == "hello world"@nl) :- rdf_assert(string, p3, 'hello world'@'NL'), rdf(string, p3, L). test(date_time, L == date_time(YY,MM,DD,H,M,S,TZ)^^xsd:dateTime) :- get_time(Now), % time stamp handling stamp_date_time(Now, date(YY,MM,DD,H,M,SF,TZM,_TZName,_DST), local), S is floor(SF), TZ is -TZM, % Not very handy! rdf_assert(date_time, p1, Now^^xsd:dateTime), rdf(date_time, p1, L). test(date_time, L == date_time(2015,12,13,15,40,0,3600)^^xsd:dateTime) :- rdf_assert(date_time, p2, "2015-12-13T15:40:00+01:00"^^xsd:dateTime), rdf(date_time, p2, L). test(date_time, L == date_time(2015,12,13,15,40,0,0)^^xsd:dateTime) :- rdf_assert(date_time, p3, "2015-12-13T15:40:00Z"^^xsd:dateTime), rdf(date_time, p3, L). test(untyped, true) :- rdf_assert(untyped, p1, "y"^^y), \+ rdf(untyped, p1, "x"^^_Type). test(untyped, Type == y) :- rdf_assert(untyped, p1, "y"^^y), rdf(untyped, p1, "y"^^Type). test(int_string, fail) :- rdf_assert(int_string, p1, 1), rdf(int_string, p1, _^^xsd:string). test(untyped_int, true) :- rdf_assert(untyped, p1, "y"^^y), \+ rdf(untyped, p1, "10"^^_Type). test(untyped_int2, Type == xsd:integer) :- rdf_assert(untyped_int2, p1, "010"^^xsd:integer), rdf(untyped_int2, p1, 10^^Type). test(shared_so, fail) :- rdf_assert(s,p,o), rdf(X,_,X). :- end_tests(literal). /******************************* * ENUMERATION TESTS * *******************************/ graph(enumerate_1, [ rdf(a, p1, c), rdf(c, p2, 42), rdf(a, p3, N = [ rdf(N, p3, true), rdf(N, p4, "hello") ]) ]). :- begin_tests(enumerate, [ setup(assert_graph(enumerate_1, default)), cleanup(rdf_reset_db) ]). % Enumerate by role test(role, set(S == ['_:genid1', a,c])) :- rdf_subject(S). test(role, set(P == [p1,p2,p3,p4])) :- rdf_predicate(P). test(role, set(O == ['_:genid1', c, 42^^xsd:integer, true^^xsd:boolean, "hello"^^xsd:string])) :- rdf_object(O). test(role, set(N == ['_:genid1', a, c, 42^^xsd:integer, true^^xsd:boolean, "hello"^^xsd:string])) :- rdf_node(N). test(role, set(N == ['_:genid1', a, c, p1,p2,p3,p4, 42^^xsd:integer, true^^xsd:boolean, "hello"^^xsd:string])) :- rdf_term(N). % enumerate by type test(type, set(IRI == [a,c,p1,p2,p3,p4])) :- rdf_iri(IRI). test(type, set(BNode == ['_:genid1'])) :- rdf_bnode(BNode). test(type, set(Name == [a,c,p1,p2,p3,p4, 42^^xsd:integer, true^^xsd:boolean, "hello"^^xsd:string])) :- rdf_name(Name). test(type, set(Literal == [ 42^^xsd:integer, true^^xsd:boolean, "hello"^^xsd:string])) :- rdf_literal(Literal). test(type, fail) :- rdf_literal(c). % deterministic tests test(enum_det) :- rdf_name(true). test(enum_det) :- rdf_name(a). test(enum_det) :- rdf_iri(a). test(enum_det) :- rdf_subject(a). test(enum_det) :- rdf_object(c). test(enum_det) :- rdf_object(true). test(enum_det) :- rdf_object(42). test(enum_det) :- rdf_object(42^^xsd:integer). test(enum_det) :- rdf_object("42"^^xsd:integer). test(enum_det) :- rdf_object('42'^^xsd:integer). :- end_tests(enumerate). /******************************* * NUMERICAL QUERIES * *******************************/ graph(numerical_1, [ rdf(i, p, [-1, 0, 1]), rdf(b, p, [-1^^xsd:byte, 0^^xsd:byte, 1^^xsd:byte]), rdf(f, p, [-1.0, 0.0, 1.0]), rdf(f2, p, [-0.5, 0.5]), rdf(s, p, ["-1", "0", "1"]), rdf(l, p, ["-1"@en, "0"@en, "1"@en]) ]). :- begin_tests(query_numerical, [ setup(assert_graph(numerical_1, default)), cleanup(rdf_reset_db) ]). test(eq, set(X == [ 1^^xsd:byte, 1^^xsd:integer, 1.0^^xsd:double ])) :- { X == 1 }, rdf(_,_,X). test(eq_pre1, set(X == [ 0.5^^xsd:double ])) :- { X == 0.5 }, rdf(_,_,X). test(eq_pre2, set(X == [ 0.5^^xsd:double ])) :- { X == 0.5^^xsd:double }, rdf(_,_,X). test(eq_pre3, set(X == [ 0.5^^xsd:double ])) :- X = _^^_, { X == 0.5 }, rdf(_,_,X). test(eq_pre4, set(X == [ 1^^xsd:byte ])) :- { X == 1^^xsd:byte }, rdf(_,_,X). test(eq_post1, set(X == [ 0.5^^xsd:double ])) :- rdf(_,_,X), { X == 0.5 }. test(eq_post3, set(X == [ 0.5^^xsd:double ])) :- X = _^^_, rdf(_,_,X), { X == 0.5 }. test(gt, set(X == [ 0.5^^xsd:double, 1^^xsd:byte, 1^^xsd:integer, 1.0^^xsd:double])) :- { X >= 0.5 }, rdf(_,_,X). test(lt, set(X == [ -0.5^^xsd:double, -1^^xsd:byte, -1^^xsd:integer, -1.0^^xsd:double ])) :- { X < 0 }, rdf(_,_,X). test(between, set(X == [ -0.5^^xsd:double, % pure between 0.0^^xsd:double, 0^^xsd:byte, 0^^xsd:integer, 0.5^^xsd:double ])) :- { X >= -0.5, X =< 0.5 }, rdf(_,_,X). test(between, set(X == [ 0.0^^xsd:double, % between with one constraint 0^^xsd:byte, 0^^xsd:integer, 0.5^^xsd:double ])) :- { X > -0.3, X =< 0.5 }, rdf(_,_,X). test(between, set(X == [ 0.0^^xsd:double, % between with two constraints 0^^xsd:byte, 0^^xsd:integer ])) :- { X > -0.3, X < 0.5 }, rdf(_,_,X). test(between, set(X == [ 0.0^^xsd:double, % between with two constraints 0^^xsd:byte, 0^^xsd:integer ])) :- { X > -0.3, Y < 0.5 }, X = Y, rdf(_,_,X). test(between, set(X == [ 0.0^^xsd:double, % between with two constraints 0^^xsd:byte, 0^^xsd:integer ])) :- { X > -0.3, Y < 0.5 }, rdf(_,_,X), X = Y. :- end_tests(query_numerical). /******************************* * LEXICAL COMPARISON * *******************************/ graph(lexical_1, [ rdf(s, nl, ["aap"@nl, "noot"@nl, "lopen"@nl]), rdf(s, d, ["2015-05-23"^^xsd:date, "2016-02-01"^^xsd:date]), rdf(s, s, ["2000", "h2o", "zzz"]) ]). :- begin_tests(lexical_comparison, [ setup(assert_graph(lexical_1, default)), cleanup(rdf_reset_db) ]). test(date, set(D == [date(2016,2,1)^^xsd:date])) :- { D > "2016-01-01"^^xsd:date }, rdf(_,_,D). test(date, set(D == [date(2016,2,1)^^xsd:date])) :- rdf(_,_,D), { D > "2016-01-01"^^xsd:date }. test(lang, set(D == ["noot"@nl, "lopen"@nl])) :- { D > "aap"@nl }, rdf(_,_,D). test(lang, set(D == ["noot"@nl, "lopen"@nl])) :- rdf(_,_,D), { D > "aap"@nl }. test(lang, set(D == ["h2o"^^xsd:string, "zzz"^^xsd:string])) :- { D >= "h2o" }, rdf(_,_,D). test(lang, set(D == ["h2o"^^xsd:string, "zzz"^^xsd:string])) :- rdf(_,_,D), { D >= "h2o" }. :- end_tests(lexical_comparison). /******************************* * LANG QUERIES * *******************************/ graph(lang_1, [ rdf(s, nl, ["Aap"@nl, "Noot"@'NL-nl', "Lopen"@'NL-nl']), rdf(s, be, ['Lopen'@'NL-be']), rdf(s, en, ['Running'@en]), rdf(s, str, ["Aap"]) ]). :- begin_tests(query_lang, [ setup(assert_graph(lang_1, default)), cleanup(rdf_reset_db) ]). test(nl, set(T == [ "Aap" ])) :- rdf(_,_,T@nl). test(nl, set(L == [ "Aap"@nl, "Noot"@'nl-nl', "Lopen"@'nl-nl', "Lopen"@'nl-be' ])) :- { lang_matches(L, nl) }, rdf(_,_,L). test(pattern, set(L == [ "Running"@en ])) :- { lang_matches(L, en) }, rdf(_,_,L). test(pattern, set(L == [ "Running"@en ])) :- L = _@_, { lang_matches(L, en) }, rdf(_,_,L). test(pattern, set(L == [ "Running"@en ])) :- { lang_matches(L, en) }, L = _@_, rdf(_,_,L). test(pattern, set(T == [ "Running" ])) :- L = T@Lang, { lang_matches(Lang, en) }, rdf(_,_,L). test(pattern, set(T == [ "Running" ])) :- { lang_matches(Lang, en) }, L = T@Lang, rdf(_,_,L). test(pattern, set(T == [ "Running" ])) :- rdf(_,_,T@Lang), { lang_matches(Lang, en) }. :- end_tests(query_lang). /******************************* * TEXT SEARCH * *******************************/ graph(search_1, [ rdf(s, nl, ["Aap"@nl, "Noot"@'NL-nl', "Lopen"@'NL-nl']), rdf(s, be, ['Lopen'@'NL-be']), rdf(s, en, ['Running'@en, "realise"@'en-gb']), rdf(s, us, ["realize"@'en-us']), rdf(s, str, ["Aap", "h2o"]), rdf(s, sen, ["Zwarte zwanen zwemmen in de Zuiderzee"@nl]) ]). :- begin_tests(query_search, [ setup(assert_graph(search_1, default)), cleanup(rdf_reset_db) ]). test(prefix, set(L==["realise"@'en-gb',"realize"@'en-us'])) :- { prefix(L, "rea") }, rdf(_,_,L). test(prefix, set(L==["realise"@'en-gb',"realize"@'en-us'])) :- rdf(_,_,L), { prefix(L, "rea") }. test(prefix, set(L==["Aap"@nl,"Aap"^^xsd:string])) :- { prefix(L, "Aa") }, rdf(_,_,L). test(word, set(L==["Zwarte zwanen zwemmen in de Zuiderzee"@nl])) :- { word(L, "Zuiderzee") }, rdf(_,_,L). test(word, set(L==["Zwarte zwanen zwemmen in de Zuiderzee"@nl])) :- { word(L, "zuiderzee") }, rdf(_,_,L). test(substring, set(L==["h2o"^^xsd:string])) :- { substring(L, "2") }, rdf(_,_,L). test(substring, set(L==["h2o"^^xsd:string])) :- rdf(_,_,L), { substring(L, "2") }. :- end_tests(query_search). /******************************* * COMBINE CONDITIONS * *******************************/ graph(mixed_1, [ rdf(s, nl, ["Aap"@nl, "Noot"@'NL-nl', "Lopen"@'NL-nl']), rdf(s, be, ['Lopen'@'NL-be']), rdf(s, en, ['Running'@en, "realise"@'en-gb']), rdf(s, us, ["realize"@'en-us']), rdf(s, str, ["Aap"]) ]). :- begin_tests(query_mixed, [ setup(assert_graph(mixed_1, default)), cleanup(rdf_reset_db) ]). test(lang_prefix, set(L==["realize"@'en-us'])) :- { prefix(L, "rea"), lang_matches(L, 'en-us') }, rdf(_,_,L). test(lang_prefix, set(L==["realize"@'en-us'])) :- { lang_matches(L, 'en-us'), prefix(L, "rea") }, rdf(_,_,L). test(lang_prefix, set(L==["realize"@'en-us'])) :- { prefix(L, "rea") }, rdf(_,_,L), { lang_matches(L, 'en-us') }. test(lang_prefix, set(L==["realize"@'en-us'])) :- { lang_matches(L, 'en-us') }, rdf(_,_,L), { prefix(L, "rea") }. :- end_tests(query_mixed). /******************************* * PLAIN/FULL * *******************************/ graph(migrate_1, [ rdf(s, n, [ 10^^xsd:integer, 11.0^^xsd:double, 12^^xsd:byte ]), rdf(s, d, [ "2016-02-01"^^xsd:date ]), rdf(s, l, [ "hello"@en, "hallo"@nl ]) ]). :- begin_tests(migrate, [ setup(assert_graph(migrate_1, default)), cleanup(rdf_reset_db) ]). test(num, set(N == [11.0^^xsd:double, 12^^xsd:byte])) :- { N >= 11 }, rdf(_,_,N). test(num, set(N == [11.0, 12])) :- { N >= 11 }, rdf(_,_,N^^_T). test(num, set(N == [11.0, 12])) :- rdf(_,_,N^^_T), { N >= 11 }. test(lang, set(T == ["hallo"@nl])) :- { lang_matches(T, nl) }, rdf(_,_,T). test(lang, set(T == ["hallo"])) :- { lang_matches(L, nl) }, rdf(_,_,T@L). test(lang, set(T == ["hallo"])) :- rdf(_,_,T@L), { lang_matches(L, nl) }. :- end_tests(migrate). /******************************* * COLLECTIONS * *******************************/ assert_collections_graph(G) :- rdf_assert_list([a,b,c], _, G), rdf_assert_list([d,b,e], _, G). :- begin_tests(collections, [ setup(assert_collections_graph(default)), cleanup(rdf_reset_db) ]). test(rdf_length, all(Len =:= [3,3])) :- rdf_list(L), rdf_length(L, Len). test(rdf_member, set(X == [a,b,c,d,e])) :- rdf_member(X, _). test(rdf_nextto, set(X-Y == [a-b,b-c,b-e,d-b])) :- rdf_nextto(X, Y). test(rdf_nth0, set(I-X == [0-a,0-d,1-b,2-c,2-e])) :- rdf_list(L), rdf_nth0(I, L, X). test(rdf_nth1, set(I-X == [1-a,1-d,2-b,3-c,3-e])) :- rdf_list(L), rdf_nth1(I, L, X). test(rdf_last, set(X == [c,e])) :- rdf_list(L), rdf_last(L, X). :- end_tests(collections). /******************************* * TEST DATA * *******************************/ :- rdf_meta assert_graph(t, r). %! set_graph(+Name) is det. % % Set the indicated graph. set_graph(Name) :- rdf_reset_db, rdf_default_graph(Graph), assert_graph(Name, Graph). %! assert_graph(+Name, +Graph) % % Assert data from graph/2 into the RDF graph Graph. assert_graph(Name, Graph) :- atom(Name), !, ( graph(Name, Data0) -> rdf_global_term(Data0, Data), assert_graph(Data, Graph) ; existence_error(graph, Name) ). assert_graph(Data, Graph) :- term_variables(Data, BNodes), maplist(rdf_create_bnode, BNodes), maplist({Graph}/[Triple]>>assert_triple(Triple,Graph), Data). assert_triple(rdf(S,P,BNode=Triples), G) :- !, assertion(rdf_is_bnode(BNode)), rdf_assert(S,P,BNode), maplist({G}/[Triple]>>assert_triple(Triple, G), Triples). assert_triple(rdf(S,P,LO), G) :- is_list(LO), !, maplist({S,P,G}/[O]>>assert_triple(rdf(S,P,O), G), LO). assert_triple(rdf(S,P,O), G) :- rdf_assert(S,P,O,G).