-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for updating values of optional properties (#76)
- Loading branch information
1 parent
a664e21
commit a8c90a4
Showing
13 changed files
with
298 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { sparql, type SparqlValue } from "./sparql_tag.ts"; | ||
export { ASK, CONSTRUCT, DESCRIBE, SELECT } from "./sparql_query_builders.ts"; | ||
export { DELETE, INSERT, WITH } from "./sparql_update_builders.ts"; | ||
export { OPTIONAL } from "./sparql_expression_builders.ts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { bracesInline, SparqlBuilder } from "./sparql_shared_builders.ts"; | ||
|
||
import { type SparqlValue } from "./sparql_tag.ts"; | ||
|
||
type Builders<T extends keyof SparqlExpressionBuilder> = Pick< | ||
SparqlExpressionBuilder, | ||
T | ||
>; | ||
|
||
class SparqlExpressionBuilder extends SparqlBuilder { | ||
public OPTIONAL( | ||
strings: TemplateStringsArray, | ||
...values: SparqlValue[] | ||
): Builders<"build"> { | ||
return this.template(strings, values, "OPTIONAL", bracesInline); | ||
} | ||
} | ||
|
||
export const OPTIONAL = ( | ||
strings: TemplateStringsArray, | ||
...values: SparqlValue[] | ||
) => new SparqlExpressionBuilder().OPTIONAL(strings, ...values); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import { assert, Comunica } from "../test_deps.ts"; | ||
|
||
import { initStore, x } from "../test_utils.ts"; | ||
|
||
import { createLens } from "ldkit"; | ||
|
||
const engine = new Comunica(); | ||
|
||
const EntitySchema = { | ||
"@type": x.Entity, | ||
requiredString: { | ||
"@id": x.requiredString, | ||
}, | ||
optionalString: { | ||
"@id": x.optionalString, | ||
"@optional": true, | ||
}, | ||
optionalArray: { | ||
"@id": x.optionalArray, | ||
"@optional": true, | ||
"@array": true, | ||
}, | ||
} as const; | ||
|
||
const init = () => { | ||
const { context, assertStore } = initStore(); | ||
const Entities = createLens(EntitySchema, context, engine); | ||
return { Entities, assertStore }; | ||
}; | ||
|
||
Deno.test("E2E / Optional / Insert without optional properties", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" . | ||
`); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Insert with optional properties", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
optionalString: "test", | ||
optionalArray: ["testArray", "otherArray"], | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" ; | ||
x:optionalString "test" ; | ||
x:optionalArray "testArray", "otherArray" . | ||
`); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Unset optional existing property", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
optionalString: "test", | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" ; | ||
x:optionalString "test" . | ||
`); | ||
|
||
await Entities.update({ | ||
$id: x.Entity, | ||
requiredString: "different", | ||
optionalString: null, | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "different" . | ||
`); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Unset optional existing array property", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
optionalArray: ["test"], | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" ; | ||
x:optionalArray "test" . | ||
`); | ||
|
||
await Entities.update({ | ||
$id: x.Entity, | ||
requiredString: "different", | ||
optionalArray: [], | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "different" . | ||
`); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Unset optional non-existing property", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" . | ||
`); | ||
|
||
await Entities.update({ | ||
$id: x.Entity, | ||
requiredString: "different", | ||
optionalString: null, | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "different" . | ||
`); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Should return null for optional property without value", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" . | ||
`); | ||
|
||
const entity = await Entities.findByIri(x.Entity); | ||
|
||
assert(entity !== null); | ||
assert(entity.optionalString === null); | ||
}); | ||
|
||
Deno.test("E2E / Optional / Should return empty array for optional array property without value", async () => { | ||
const { Entities, assertStore } = init(); | ||
|
||
await Entities.insert({ | ||
$id: x.Entity, | ||
requiredString: "required", | ||
}); | ||
|
||
assertStore(` | ||
x:Entity | ||
a x:Entity ; | ||
x:requiredString "required" . | ||
`); | ||
|
||
const entity = await Entities.findByIri(x.Entity); | ||
|
||
assert(entity !== null); | ||
assert(Array.isArray(entity.optionalArray)); | ||
assert(entity.optionalArray.length === 0); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { assertEquals } from "./test_deps.ts"; | ||
|
||
import { DataFactory } from "../library/rdf.ts"; | ||
import { OPTIONAL } from "../library/sparql/sparql_expression_builders.ts"; | ||
import { DELETE } from "../library/sparql/sparql_update_builders.ts"; | ||
|
||
const df = new DataFactory(); | ||
const s = df.variable("s"); | ||
const p = df.variable("p"); | ||
const o = df.variable("o"); | ||
const spo = df.quad(s, p, o); | ||
|
||
Deno.test("SPARQL / Sparql builder OPTIONAL #1", () => { | ||
const expected = "OPTIONAL { ?s ?p ?o . }"; | ||
const query = OPTIONAL`${s} ${p} ${o} .`.build(); | ||
|
||
assertEquals(query, expected); | ||
}); | ||
|
||
Deno.test("SPARQL / Sparql builder OPTIONAL #2", () => { | ||
const expected = "OPTIONAL { ?s ?p ?o . }"; | ||
const query = OPTIONAL`${spo}`.build(); | ||
|
||
assertEquals(query, expected); | ||
}); | ||
|
||
Deno.test("SPARQL / Sparql builder OPTIONAL #3", () => { | ||
const expected = "OPTIONAL { ?s ?p ?o .\n?s ?p ?o . }"; | ||
const query = OPTIONAL`${[spo, spo]}`.build(); | ||
|
||
assertEquals(query, expected); | ||
}); | ||
|
||
Deno.test("SPARQL / Sparql builder OPTIONAL #4", () => { | ||
const expected = "DELETE WHERE {\nOPTIONAL { ?s ?p ?o .\n?s ?p ?o . }\n}\n"; | ||
const query = DELETE.WHERE`${OPTIONAL`${[spo, spo]}`}`.build(); | ||
|
||
assertEquals(query, expected); | ||
}); | ||
|
||
Deno.test("SPARQL / Sparql builder OPTIONAL #5", () => { | ||
const expected = | ||
"DELETE WHERE {\nOPTIONAL { ?s ?p ?o . }\nOPTIONAL { ?s ?p ?o . }\n}\n"; | ||
const query = DELETE.WHERE`${[OPTIONAL`${spo}`, OPTIONAL`${spo}`]}`.build(); | ||
|
||
assertEquals(query, expected); | ||
}); |
Oops, something went wrong.