|
| 1 | +import logging |
| 2 | +from decimal import Decimal |
| 3 | + |
| 4 | +import pytest |
| 5 | + |
| 6 | +from rdflib.graph import Graph |
| 7 | +from rdflib.namespace import XSD, Namespace |
| 8 | +from rdflib.plugins.sparql.operators import _lang_range_check |
| 9 | +from rdflib.term import BNode, Identifier, Literal, URIRef |
| 10 | + |
| 11 | +EG = Namespace("https://example.com/") |
| 12 | + |
| 13 | + |
| 14 | +@pytest.mark.parametrize( |
| 15 | + ["expression", "expected_result"], |
| 16 | + [ |
| 17 | + (r"isIRI('eg:IRI')", Literal(False)), |
| 18 | + (r"isIRI(eg:IRI)", Literal(True)), |
| 19 | + (r"isURI('eg:IRI')", Literal(False)), |
| 20 | + (r"isURI(eg:IRI)", Literal(True)), |
| 21 | + (r"isBLANK(eg:IRI)", Literal(False)), |
| 22 | + (r"isBLANK(BNODE())", Literal(True)), |
| 23 | + (r"isLITERAL(eg:IRI)", Literal(False)), |
| 24 | + (r"isLITERAL('eg:IRI')", Literal(True)), |
| 25 | + (r"isNumeric(eg:IRI)", Literal(False)), |
| 26 | + (r"isNumeric(1)", Literal(True)), |
| 27 | + (r"STR(eg:IRI)", Literal("https://example.com/IRI")), |
| 28 | + (r"STR(1)", Literal("1")), |
| 29 | + (r'LANG("Robert"@en)', Literal("en")), |
| 30 | + (r'LANG("Robert")', Literal("")), |
| 31 | + (r'DATATYPE("Robert")', XSD.string), |
| 32 | + (r'DATATYPE("42"^^xsd:integer)', XSD.integer), |
| 33 | + (r'IRI("http://example/")', URIRef("http://example/")), |
| 34 | + (r'BNODE("example")', BNode), |
| 35 | + (r'STRDT("123", xsd:integer)', Literal("123", datatype=XSD.integer)), |
| 36 | + (r'STRLANG("cats and dogs", "en")', Literal("cats and dogs", lang="en")), |
| 37 | + (r"UUID()", URIRef), |
| 38 | + (r"STRUUID()", Literal), |
| 39 | + (r'STRLEN("chat")', Literal(4)), |
| 40 | + (r'SUBSTR("foobar", 4)', Literal("bar")), |
| 41 | + (r'UCASE("foo")', Literal("FOO")), |
| 42 | + (r'LCASE("BAR")', Literal("bar")), |
| 43 | + (r'strStarts("foobar", "foo")', Literal(True)), |
| 44 | + (r'strStarts("foobar", "bar")', Literal(False)), |
| 45 | + (r'strEnds("foobar", "bar")', Literal(True)), |
| 46 | + (r'strEnds("foobar", "foo")', Literal(False)), |
| 47 | + (r'contains("foobar", "bar")', Literal(True)), |
| 48 | + (r'contains("foobar", "barfoo")', Literal(False)), |
| 49 | + (r'strbefore("abc","b")', Literal("a")), |
| 50 | + (r'strbefore("abc","xyz")', Literal("")), |
| 51 | + (r'strafter("abc","b")', Literal("c")), |
| 52 | + (r'strafter("abc","xyz")', Literal("")), |
| 53 | + (r"ENCODE_FOR_URI('this/is/a/test')", Literal("this%2Fis%2Fa%2Ftest")), |
| 54 | + (r"ENCODE_FOR_URI('this is a test')", Literal("this%20is%20a%20test")), |
| 55 | + ( |
| 56 | + r"ENCODE_FOR_URI('AAA~~0123456789~~---~~___~~...~~ZZZ')", |
| 57 | + Literal("AAA~~0123456789~~---~~___~~...~~ZZZ"), |
| 58 | + ), |
| 59 | + (r'CONCAT("foo", "bar")', Literal("foobar")), |
| 60 | + (r'langMatches(lang("That Seventies Show"@en), "en")', Literal(True)), |
| 61 | + ( |
| 62 | + r'langMatches(lang("Cette Série des Années Soixante-dix"@fr), "en")', |
| 63 | + Literal(False), |
| 64 | + ), |
| 65 | + ( |
| 66 | + r'langMatches(lang("Cette Série des Années Septante"@fr-BE), "en")', |
| 67 | + Literal(False), |
| 68 | + ), |
| 69 | + (r'langMatches(lang("Il Buono, il Bruto, il Cattivo"), "en")', Literal(False)), |
| 70 | + (r'langMatches(lang("That Seventies Show"@en), "FR")', Literal(False)), |
| 71 | + ( |
| 72 | + r'langMatches(lang("Cette Série des Années Soixante-dix"@fr), "FR")', |
| 73 | + Literal(True), |
| 74 | + ), |
| 75 | + ( |
| 76 | + r'langMatches(lang("Cette Série des Années Septante"@fr-BE), "FR")', |
| 77 | + Literal(True), |
| 78 | + ), |
| 79 | + (r'langMatches(lang("Il Buono, il Bruto, il Cattivo"), "FR")', Literal(False)), |
| 80 | + (r'langMatches(lang("That Seventies Show"@en), "*")', Literal(True)), |
| 81 | + ( |
| 82 | + r'langMatches(lang("Cette Série des Années Soixante-dix"@fr), "*")', |
| 83 | + Literal(True), |
| 84 | + ), |
| 85 | + ( |
| 86 | + r'langMatches(lang("Cette Série des Années Septante"@fr-BE), "*")', |
| 87 | + Literal(True), |
| 88 | + ), |
| 89 | + (r'langMatches(lang("Il Buono, il Bruto, il Cattivo"), "*")', Literal(False)), |
| 90 | + (r'langMatches(lang("abc"@en-gb), "en-GB")', Literal(True)), |
| 91 | + (r'regex("Alice", "^ali", "i")', Literal(True)), |
| 92 | + (r'regex("Bob", "^ali", "i")', Literal(False)), |
| 93 | + (r'replace("abcd", "b", "Z")', Literal("aZcd")), |
| 94 | + (r"abs(-1.5)", Literal("1.5", datatype=XSD.decimal)), |
| 95 | + (r"round(2.4999)", Literal("2", datatype=XSD.decimal)), |
| 96 | + (r"round(2.5)", Literal("3", datatype=XSD.decimal)), |
| 97 | + (r"round(-2.5)", Literal("-2", datatype=XSD.decimal)), |
| 98 | + (r"round(0.1)", Literal("0", datatype=XSD.decimal)), |
| 99 | + (r"round(-0.1)", Literal("0", datatype=XSD.decimal)), |
| 100 | + (r"RAND()", Literal), |
| 101 | + (r"now()", Literal), |
| 102 | + (r'month("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(1)), |
| 103 | + (r'day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(10)), |
| 104 | + (r'hours("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(14)), |
| 105 | + (r'minutes("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(45)), |
| 106 | + ( |
| 107 | + r'seconds("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', |
| 108 | + Literal(Decimal("13.815")), |
| 109 | + ), |
| 110 | + ( |
| 111 | + r'timezone("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', |
| 112 | + Literal("-PT5H", datatype=XSD.dayTimeDuration), |
| 113 | + ), |
| 114 | + ( |
| 115 | + r'timezone("2011-01-10T14:45:13.815Z"^^xsd:dateTime)', |
| 116 | + Literal("PT0S", datatype=XSD.dayTimeDuration), |
| 117 | + ), |
| 118 | + ( |
| 119 | + r'tz("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) ', |
| 120 | + Literal("-05:00"), |
| 121 | + ), |
| 122 | + ( |
| 123 | + r'tz("2011-01-10T14:45:13.815Z"^^xsd:dateTime) ', |
| 124 | + Literal("Z"), |
| 125 | + ), |
| 126 | + ( |
| 127 | + r'tz("2011-01-10T14:45:13.815"^^xsd:dateTime) ', |
| 128 | + Literal(""), |
| 129 | + ), |
| 130 | + (r'MD5("abc")', Literal("900150983cd24fb0d6963f7d28e17f72")), |
| 131 | + (r'SHA1("abc")', Literal("a9993e364706816aba3e25717850c26c9cd0d89d")), |
| 132 | + ( |
| 133 | + r'SHA256("abc")', |
| 134 | + Literal("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"), |
| 135 | + ), |
| 136 | + ( |
| 137 | + r'SHA384("abc")', |
| 138 | + Literal( |
| 139 | + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" |
| 140 | + ), |
| 141 | + ), |
| 142 | + ( |
| 143 | + r'SHA512("abc")', |
| 144 | + Literal( |
| 145 | + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" |
| 146 | + ), |
| 147 | + ), |
| 148 | + ], |
| 149 | +) |
| 150 | +def test_function(expression: str, expected_result: Identifier) -> None: |
| 151 | + graph = Graph() |
| 152 | + query_string = """ |
| 153 | + PREFIX eg: <https://example.com/> |
| 154 | + PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> |
| 155 | + CONSTRUCT { eg:subject eg:predicate ?o } |
| 156 | + WHERE { |
| 157 | + BIND(???EXPRESSION_PLACEHOLDER??? AS ?o) |
| 158 | + } |
| 159 | + """.replace( |
| 160 | + "???EXPRESSION_PLACEHOLDER???", expression |
| 161 | + ) |
| 162 | + result = graph.query(query_string) |
| 163 | + assert result.type == "CONSTRUCT" |
| 164 | + assert isinstance(result.graph, Graph) |
| 165 | + logging.debug("result = %s", list(result.graph.triples((None, None, None)))) |
| 166 | + actual_result = result.graph.value(EG.subject, EG.predicate, any=False) |
| 167 | + if isinstance(expected_result, type): |
| 168 | + assert isinstance(actual_result, expected_result) |
| 169 | + else: |
| 170 | + assert expected_result == actual_result |
| 171 | + |
| 172 | + |
| 173 | +@pytest.mark.parametrize( |
| 174 | + ["literal", "range", "expected_result"], |
| 175 | + [ |
| 176 | + (Literal("en"), Literal("en"), True), |
| 177 | + (Literal("en"), Literal("EN"), True), |
| 178 | + (Literal("EN"), Literal("en"), True), |
| 179 | + (Literal("EN"), Literal("EN"), True), |
| 180 | + (Literal("en"), Literal("en-US"), False), |
| 181 | + (Literal("en-US"), Literal("en-US"), True), |
| 182 | + (Literal("en-gb"), Literal("en-GB"), True), |
| 183 | + ], |
| 184 | +) |
| 185 | +def test_lang_range_check( |
| 186 | + literal: Literal, range: Literal, expected_result: bool |
| 187 | +) -> None: |
| 188 | + actual_result = _lang_range_check(range, literal) |
| 189 | + assert expected_result == actual_result |
0 commit comments