|
| 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("That Seventies Show"@en, "en")', Literal(True)), |
| 61 | + ( |
| 62 | + r'langMatches("Cette Série des Années Soixante-dix"@fr, "en")', |
| 63 | + Literal(False), |
| 64 | + ), |
| 65 | + (r'langMatches("Cette Série des Années Septante"@fr-BE, "en")', Literal(False)), |
| 66 | + (r'langMatches("Il Buono, il Bruto, il Cattivo", "en")', Literal(False)), |
| 67 | + (r'langMatches("That Seventies Show"@en, "FR")', Literal(False)), |
| 68 | + (r'langMatches("Cette Série des Années Soixante-dix"@fr, "FR")', Literal(True)), |
| 69 | + (r'langMatches("Cette Série des Années Septante"@fr-BE, "FR")', Literal(True)), |
| 70 | + (r'langMatches("Il Buono, il Bruto, il Cattivo", "FR")', Literal(False)), |
| 71 | + (r'langMatches("That Seventies Show"@en, "*")', Literal(True)), |
| 72 | + (r'langMatches("Cette Série des Années Soixante-dix"@fr, "*")', Literal(True)), |
| 73 | + (r'langMatches("Cette Série des Années Septante"@fr-BE, "*")', Literal(True)), |
| 74 | + (r'langMatches("Il Buono, il Bruto, il Cattivo", "*")', Literal(False)), |
| 75 | + (r'regex("Alice", "^ali", "i")', Literal(True)), |
| 76 | + (r'regex("Bob", "^ali", "i")', Literal(False)), |
| 77 | + (r'replace("abcd", "b", "Z")', Literal("aZcd")), |
| 78 | + (r"abs(-1.5)", Literal("1.5", datatype=XSD.decimal)), |
| 79 | + (r"round(2.4999)", Literal("2", datatype=XSD.decimal)), |
| 80 | + (r"round(2.5)", Literal("3", datatype=XSD.decimal)), |
| 81 | + (r"round(-2.5)", Literal("-2", datatype=XSD.decimal)), |
| 82 | + (r"round(0.1)", Literal("0", datatype=XSD.decimal)), |
| 83 | + (r"round(-0.1)", Literal("0", datatype=XSD.decimal)), |
| 84 | + (r"RAND()", Literal), |
| 85 | + (r"now()", Literal), |
| 86 | + (r'month("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(1)), |
| 87 | + (r'day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(10)), |
| 88 | + (r'hours("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(14)), |
| 89 | + (r'minutes("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', Literal(45)), |
| 90 | + ( |
| 91 | + r'seconds("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', |
| 92 | + Literal(Decimal("13.815")), |
| 93 | + ), |
| 94 | + ( |
| 95 | + r'timezone("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime)', |
| 96 | + Literal("-PT5H", datatype=XSD.dayTimeDuration), |
| 97 | + ), |
| 98 | + ( |
| 99 | + r'timezone("2011-01-10T14:45:13.815Z"^^xsd:dateTime)', |
| 100 | + Literal("PT0S", datatype=XSD.dayTimeDuration), |
| 101 | + ), |
| 102 | + ( |
| 103 | + r'tz("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) ', |
| 104 | + Literal("-05:00"), |
| 105 | + ), |
| 106 | + ( |
| 107 | + r'tz("2011-01-10T14:45:13.815Z"^^xsd:dateTime) ', |
| 108 | + Literal("Z"), |
| 109 | + ), |
| 110 | + ( |
| 111 | + r'tz("2011-01-10T14:45:13.815"^^xsd:dateTime) ', |
| 112 | + Literal(""), |
| 113 | + ), |
| 114 | + (r'MD5("abc")', Literal("900150983cd24fb0d6963f7d28e17f72")), |
| 115 | + (r'SHA1("abc")', Literal("a9993e364706816aba3e25717850c26c9cd0d89d")), |
| 116 | + ( |
| 117 | + r'SHA256("abc")', |
| 118 | + Literal("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"), |
| 119 | + ), |
| 120 | + ( |
| 121 | + r'SHA384("abc")', |
| 122 | + Literal( |
| 123 | + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" |
| 124 | + ), |
| 125 | + ), |
| 126 | + ( |
| 127 | + r'SHA512("abc")', |
| 128 | + Literal( |
| 129 | + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" |
| 130 | + ), |
| 131 | + ), |
| 132 | + ], |
| 133 | +) |
| 134 | +def test_function(expression: str, expected_result: Identifier) -> None: |
| 135 | + graph = Graph() |
| 136 | + query_string = """ |
| 137 | + PREFIX eg: <https://example.com/> |
| 138 | + PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> |
| 139 | + CONSTRUCT { eg:subject eg:predicate ?o } |
| 140 | + WHERE { |
| 141 | + BIND(???EXPRESSION_PLACEHOLDER??? AS ?o) |
| 142 | + } |
| 143 | + """.replace( |
| 144 | + "???EXPRESSION_PLACEHOLDER???", expression |
| 145 | + ) |
| 146 | + result = graph.query(query_string) |
| 147 | + assert result.type == "CONSTRUCT" |
| 148 | + logging.debug("result = %s", list(result.graph.triples((None, None, None)))) |
| 149 | + actual_result = result.graph.value(EG.subject, EG.predicate, any=False) |
| 150 | + if isinstance(expected_result, type): |
| 151 | + assert isinstance(actual_result, expected_result) |
| 152 | + else: |
| 153 | + assert expected_result == actual_result |
| 154 | + |
| 155 | + |
| 156 | +@pytest.mark.parametrize( |
| 157 | + ["literal", "range", "expected_result"], |
| 158 | + [ |
| 159 | + (Literal("foo", lang="en"), Literal("en"), True), |
| 160 | + (Literal("foo", lang="en"), Literal("EN"), True), |
| 161 | + (Literal("foo", lang="EN"), Literal("en"), True), |
| 162 | + (Literal("foo", lang="EN"), Literal("EN"), True), |
| 163 | + (Literal("foo", lang="en"), Literal("en-US"), False), |
| 164 | + (Literal("foo", lang="en-US"), Literal("en-US"), True), |
| 165 | + ], |
| 166 | +) |
| 167 | +def test_lang_range_check( |
| 168 | + literal: Literal, range: Literal, expected_result: bool |
| 169 | +) -> None: |
| 170 | + actual_result = _lang_range_check(range, literal) |
| 171 | + assert expected_result == actual_result |
0 commit comments