UNPKG

@inrupt/solid-client

Version:

Make your web apps work with Solid Pods.

1,786 lines (1,561 loc) • 55.4 kB
// Copyright Inrupt Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the // Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // import { describe, it, expect } from "@jest/globals"; import { DataFactory } from "n3"; import type { IriString, Thing } from "../interfaces"; import { setUrl, setBoolean, setDatetime, setDate, setTime, setDecimal, setInteger, setStringEnglish, setStringWithLocale, setStringNoLocale, setNamedNode, setLiteral, setTerm, } from "./set"; import { mockThingFrom } from "./mock"; import { ValidPropertyUrlExpectedError, ValidValueUrlExpectedError, } from "./thing"; import { localNodeSkolemPrefix } from "../rdf.internal"; function getMockThingWithLiteralFor( predicate: IriString, literalValue: string, literalType: | "string" | "integer" | "decimal" | "boolean" | "dateTime" | "time", ): Thing { return { type: "Subject", url: "https://arbitrary.vocab/subject", predicates: { [predicate]: { literals: { [`http://www.w3.org/2001/XMLSchema#${literalType}`]: [literalValue], }, }, }, }; } function getMockThingWithNamedNode( predicate: IriString, object: IriString, ): Thing { return { type: "Subject", url: "https://arbitrary.vocab/subject", predicates: { [predicate]: { namedNodes: [object], }, }, }; } describe("setIri", () => { it("replaces existing values with the given IRI for the given Predicate", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const updatedThing = setUrl( thing, "https://some.vocab/predicate", "https://some.pod/other-resource#object", ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("accepts values as Named Nodes", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const updatedThing = setUrl( thing, "https://some.vocab/predicate", DataFactory.namedNode("https://some.pod/other-resource#object"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("accepts values as ThingPersisteds", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const targetThing = mockThingFrom("https://some.pod/other-resource#object"); const updatedThing = setUrl( thing, "https://some.vocab/predicate", targetThing, ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("accepts values as ThingLocals", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const thingLocal = mockThingFrom("https://some.pod/other-resource#object"); (thingLocal.url as string) = `${localNodeSkolemPrefix}localObject`; const updatedThing = setUrl( thing, "https://some.vocab/predicate", thingLocal, ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual([`${localNodeSkolemPrefix}localObject`]); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const updatedThing = setUrl( thing, DataFactory.namedNode("https://some.vocab/predicate"), "https://some.pod/other-resource#object", ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("does not modify the input Thing", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://some.pod/resource#object", ); const updatedThing = setUrl( thing, "https://some.vocab/predicate", "https://some.pod/other-resource#object", ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/resource#object"]); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setUrl( thingLocal, "https://some.vocab/predicate", "https://some.pod/other-resource#object", ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://some.pod/resource#object", ); const updatedThing = setUrl( thing, "https://some.vocab/other-predicate", "https://some.pod/resource#object", ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/resource#object"]); }); it("throws an error when passed something other than a Thing", () => { expect(() => setUrl( null as unknown as Thing, "https://arbitrary.vocab/predicate", "https://arbitrary.url", ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setUrl( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "https://arbitrary.url", ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setUrl( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "https://arbitrary.url", ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); it("throws an error when passed an invalid URL value", () => { expect(() => setUrl( mockThingFrom("https://arbitrary.pod/resource#thing"), "https://arbitrary.vocab/predicate", "not-a-url", ), ).toThrow("Expected a valid URL value, but received: [not-a-url]."); }); it("throws an instance of ValidValueUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setUrl( mockThingFrom("https://arbitrary.pod/resource#thing"), "https://arbitrary.vocab/predicate", "not-a-url", ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidValueUrlExpectedError); }); }); describe("setBoolean", () => { it("replaces existing values with the given boolean for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setBoolean( thing, "https://some.vocab/predicate", true, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#boolean": ["true"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setBoolean( thing, DataFactory.namedNode("https://some.vocab/predicate"), false, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#boolean": ["false"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setBoolean( thing, DataFactory.namedNode("https://some.vocab/predicate"), true, ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setBoolean( thingLocal, "https://some.vocab/predicate", true, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#boolean": ["true"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://some.pod/resource#object", ); const updatedThing = setBoolean( thing, "https://some.vocab/other-predicate", true, ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/resource#object"]); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#boolean": ["true"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setBoolean( null as unknown as Thing, "https://arbitrary.vocab/predicate", true, ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setBoolean( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", true, ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setBoolean( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", true, ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setDatetime", () => { it("replaces existing values with the given datetime for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDatetime( thing, "https://some.vocab/predicate", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#dateTime": ["1990-11-12T13:37:42.000Z"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDatetime( thing, DataFactory.namedNode("https://some.vocab/predicate"), new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#dateTime": ["1990-11-12T13:37:42.000Z"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDatetime( thing, DataFactory.namedNode("https://some.vocab/predicate"), new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#dateTime": ["1990-11-12T13:37:42.000Z"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setDatetime( thingLocal, "https://some.vocab/predicate", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#dateTime": ["1990-11-12T13:37:42.000Z"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDatetime( thing, "https://some.vocab/other-predicate", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#dateTime": ["1990-11-12T13:37:42.000Z"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setDatetime( null as unknown as Thing, "https://arbitrary.vocab/predicate", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setDatetime( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setDatetime( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", new Date(Date.UTC(1990, 10, 12, 13, 37, 42, 0)), ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setDate", () => { it("replaces existing values with the given date for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDate( thing, "https://some.vocab/predicate", new Date(Date.UTC(1990, 10, 12)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#date": ["1990-11-12Z"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDate( thing, DataFactory.namedNode("https://some.vocab/predicate"), new Date(Date.UTC(1990, 10, 12)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#date": ["1990-11-12Z"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDate( thing, DataFactory.namedNode("https://some.vocab/predicate"), new Date(Date.UTC(1990, 10, 12)), ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#date": ["1990-11-12Z"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setDate( thingLocal, "https://some.vocab/predicate", new Date(Date.UTC(1990, 10, 12)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#date": ["1990-11-12Z"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDate( thing, "https://some.vocab/other-predicate", new Date(Date.UTC(1990, 10, 12)), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#date": ["1990-11-12Z"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setDate( null as unknown as Thing, "https://arbitrary.vocab/predicate", new Date(Date.UTC(1990, 10, 12)), ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setDate( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", new Date(Date.UTC(1990, 10, 12)), ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setDate( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", new Date(Date.UTC(1990, 10, 12)), ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setTime", () => { it("replaces existing values with the given time for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setTime(thing, "https://some.vocab/predicate", { hour: 13, minute: 37, second: 42, }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#time": ["13:37:42"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setTime( thing, DataFactory.namedNode("https://some.vocab/predicate"), { hour: 13, minute: 37, second: 42, }, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#time": ["13:37:42"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setTime( thing, DataFactory.namedNode("https://some.vocab/predicate"), { hour: 13, minute: 37, second: 42, }, ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#time": ["13:37:42"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setTime(thingLocal, "https://some.vocab/predicate", { hour: 13, minute: 37, second: 42, }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#time": ["13:37:42"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setTime(thing, "https://some.vocab/other-predicate", { hour: 13, minute: 37, second: 42, }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#time": ["13:37:42"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setTime(null as unknown as Thing, "https://arbitrary.vocab/predicate", { hour: 13, minute: 37, second: 42, }), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setTime( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", { hour: 13, minute: 37, second: 42, }, ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setTime( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", { hour: 13, minute: 37, second: 42, }, ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setDecimal", () => { it("replaces existing values with the given decimal for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDecimal( thing, "https://some.vocab/predicate", 13.37, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#decimal": ["13.37"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setDecimal( thing, DataFactory.namedNode("https://some.vocab/predicate"), 13.37, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#decimal": ["13.37"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDecimal( thing, DataFactory.namedNode("https://some.vocab/predicate"), 13.37, ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#decimal": ["13.37"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setDecimal( thingLocal, "https://some.vocab/predicate", 13.37, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#decimal": ["13.37"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setDecimal( thing, "https://some.vocab/other-predicate", 13.37, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#decimal": ["13.37"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setDecimal( null as unknown as Thing, "https://arbitrary.vocab/predicate", 13.37, ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setDecimal( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", 13.37, ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setDecimal( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", 13.37, ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setInteger", () => { it("replaces existing values with the given integer for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setInteger(thing, "https://some.vocab/predicate", 42); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#integer": ["42"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setInteger( thing, DataFactory.namedNode("https://some.vocab/predicate"), 42, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#integer": ["42"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setInteger( thing, DataFactory.namedNode("https://some.vocab/predicate"), 42, ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#integer": ["42"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setInteger( thingLocal, "https://some.vocab/predicate", 42, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#integer": ["42"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setInteger( thing, "https://some.vocab/other-predicate", 42, ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#integer": ["42"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setInteger( null as unknown as Thing, "https://arbitrary.vocab/predicate", 42, ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setInteger( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", 42, ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setInteger( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", 42, ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setStringEnglish", () => { it("replaces existing values with the given English string for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setStringEnglish( thing, "https://some.vocab/predicate", "Some string value", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toBeUndefined(); expect( updatedThing.predicates["https://some.vocab/predicate"].langStrings, ).toStrictEqual({ en: ["Some string value"], }); }); }); describe("setStringWithLocale", () => { it("replaces existing values with the given localised string for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setStringWithLocale( thing, "https://some.vocab/predicate", "Some string value", "en-GB", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toBeUndefined(); expect( updatedThing.predicates["https://some.vocab/predicate"].langStrings, ).toStrictEqual({ "en-gb": ["Some string value"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setStringWithLocale( thing, DataFactory.namedNode("https://some.vocab/predicate"), "Some string value", "en-GB", ); expect( updatedThing.predicates["https://some.vocab/predicate"].langStrings, ).toStrictEqual({ "en-gb": ["Some string value"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setStringWithLocale( thing, DataFactory.namedNode("https://some.vocab/predicate"), "Some string value", "en-GB", ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].langStrings, ).toStrictEqual({ "en-gb": ["Some string value"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setStringWithLocale( thingLocal, "https://some.vocab/predicate", "Some string value", "en-GB", ); expect( updatedThing.predicates["https://some.vocab/predicate"].langStrings, ).toStrictEqual({ "en-gb": ["Some string value"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setStringWithLocale( thing, "https://some.vocab/other-predicate", "Some string value", "en-GB", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].langStrings, ).toStrictEqual({ "en-gb": ["Some string value"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setStringWithLocale( null as unknown as Thing, "https://arbitrary.vocab/predicate", "Arbitrary string", "nl-NL", ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setStringWithLocale( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "Arbitrary string", "nl-NL", ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setStringWithLocale( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "Arbitrary string", "nl-NL", ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setStringNoLocale", () => { it("replaces existing values with the given unlocalised string for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setStringNoLocale( thing, "https://some.vocab/predicate", "Some string value", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setStringNoLocale( thing, DataFactory.namedNode("https://some.vocab/predicate"), "Some string value", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setStringNoLocale( thing, DataFactory.namedNode("https://some.vocab/predicate"), "Some other string value", ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some other string value"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setStringNoLocale( thingLocal, "https://some.vocab/predicate", "Some string value", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setStringNoLocale( thing, "https://some.vocab/other-predicate", "Some string value", ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setStringNoLocale( null as unknown as Thing, "https://arbitrary.vocab/predicate", "Arbitrary string", ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setStringNoLocale( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "Arbitrary string", ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setStringNoLocale( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", "Arbitrary string", ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setNamedNode", () => { it("replaces existing values with the given Named Node for the given Predicate", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const updatedThing = setNamedNode( thing, "https://some.vocab/predicate", DataFactory.namedNode("https://some.pod/other-resource#object"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://arbitrary.pod/resource#object", ); const updatedThing = setNamedNode( thing, DataFactory.namedNode("https://some.vocab/predicate"), DataFactory.namedNode("https://some.pod/other-resource#object"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("does not modify the input Thing", () => { const thing = getMockThingWithNamedNode( "https://some.vocab/predicate", "https://some.pod/resource#object", ); const updatedThing = setNamedNode( thing, "https://some.vocab/predicate", DataFactory.namedNode("https://some.pod/other-resource#object"), ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/resource#object"]); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setNamedNode( thingLocal, "https://some.vocab/predicate", DataFactory.namedNode("https://some.pod/other-resource#object"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].namedNodes, ).toStrictEqual(["https://some.pod/other-resource#object"]); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setNamedNode( thing, "https://some.vocab/other-predicate", DataFactory.namedNode("https://some.pod/resource#object"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].namedNodes, ).toStrictEqual(["https://some.pod/resource#object"]); }); it("throws an error when passed something other than a Thing", () => { expect(() => setNamedNode( null as unknown as Thing, "https://arbitrary.vocab/predicate", DataFactory.namedNode("https://arbitrary.pod/resource#object"), ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setNamedNode( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", DataFactory.namedNode("https://arbitrary.vocab/object"), ), ).toThrow( "Expected a valid URL to identify a property, but received: [not-a-url].", ); }); it("throws an instance of ValidPropertyUrlExpectedError when passed an invalid property URL", () => { let thrownError; try { setNamedNode( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", DataFactory.namedNode("https://arbitrary.vocab/object"), ); } catch (e) { thrownError = e; } expect(thrownError).toBeInstanceOf(ValidPropertyUrlExpectedError); }); }); describe("setLiteral", () => { it("replaces existing values with the given Literal for the given Predicate", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setLiteral( thing, "https://some.vocab/predicate", DataFactory.literal("Some string value"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("accepts Properties as Named Nodes", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Arbitrary string", "string", ); const updatedThing = setLiteral( thing, DataFactory.namedNode("https://some.vocab/predicate"), DataFactory.literal("Some string value"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("does not modify the input Thing", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setLiteral( thing, DataFactory.namedNode("https://some.vocab/predicate"), DataFactory.literal("Some string value"), ); expect(thing).not.toStrictEqual(updatedThing); expect( thing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("also works on ThingLocals", () => { const thingLocal = mockThingFrom( "https://arbitrary.pod/will-be-replaced-by-local-url", ); (thingLocal.url as string) = `${localNodeSkolemPrefix}localSubject`; const updatedThing = setLiteral( thingLocal, "https://some.vocab/predicate", DataFactory.literal("Some string value"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("preserves existing Quads with different Predicates", () => { const thing = getMockThingWithLiteralFor( "https://some.vocab/predicate", "Some string", "string", ); const updatedThing = setLiteral( thing, "https://some.vocab/other-predicate", DataFactory.literal("Some string value"), ); expect( updatedThing.predicates["https://some.vocab/predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string"], }); expect( updatedThing.predicates["https://some.vocab/other-predicate"].literals, ).toStrictEqual({ "http://www.w3.org/2001/XMLSchema#string": ["Some string value"], }); }); it("throws an error when passed something other than a Thing", () => { expect(() => setLiteral( null as unknown as Thing, "https://arbitrary.vocab/predicate", DataFactory.literal("Arbitrary string value"), ), ).toThrow("Expected a Thing, but received: [null]."); }); it("throws an error when passed an invalid property URL", () => { expect(() => setLiteral( mockThingFrom("https://arbitrary.pod/resource#thing"), "not-a-url", DataFactory.literal("Arbitrary string value"), ), ).toThrow(