@@ -122,19 +122,202 @@ describe("calculateMerkleProof", () => {
122122} ) ;
123123
124124describe ( "groupNquadsBySubject" , ( ) => {
125- it ( "should group quads by a single subject" , ( ) => {
125+ it ( "should group quads where the object is a resource" , ( ) => {
126+ /* JSON-LD
127+ {
128+ "@context ": "http://schema.org",
129+ "@id": "http://example.org/book1",
130+ "type": "Book",
131+ "author": {
132+ "@id ": "http://example.org/author1"
133+ }
134+ }
135+ */
126136 const quads = [
127- "<http://example.org/s1 > <http://example .org/p > <http://example.org/o > ." ,
128- ' <http://example.org/s1 > <http://example. org/p> "Literal" .' ,
137+ "<http://example.org/book1 > <http://schema .org/author > <http://example.org/author1 > ." ,
138+ " <http://example.org/book1 > <http://www.w3. org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> ." ,
129139 ] ;
140+
130141 const grouped = groupNquadsBySubject ( quads ) ;
131142 expect ( grouped ) . to . have . lengthOf ( 1 ) ;
132- expect ( grouped [ 0 ] ) . to . deep . include (
133- "<http://example.org/s1> <http://example.org/p> <http://example.org/o> ."
134- ) ;
135- expect ( grouped [ 0 ] ) . to . deep . include (
136- '<http://example.org/s1> <http://example.org/p> "Literal" .'
137- ) ;
143+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
144+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
145+ } ) ;
146+
147+ it ( "should group quads where the object is a literal" , ( ) => {
148+ /* JSON-LD
149+ {
150+ "@context ": "http://schema.org",
151+ "@id": "http://example.org/book1",
152+ "type": "Book",
153+ "title": "The Great Book"
154+ }
155+ */
156+ const quads = [
157+ '<http://example.org/book1> <http://schema.org/title> "The Great Book" .' ,
158+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
159+ ] ;
160+
161+ const grouped = groupNquadsBySubject ( quads ) ;
162+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
163+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
164+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
165+ } ) ;
166+
167+ it ( "should group quads where the object is a literal containing an escape character" , ( ) => {
168+ /* JSON-LD
169+ {
170+ "@context ": "http://schema.org",
171+ "@id": "http://example.org/book1",
172+ "type": "Book",
173+ "title": "The Great Book \n"
174+ }
175+ */
176+ const quads = [
177+ // \n is represented as \\n in code
178+ '<http://example.org/book1> <http://schema.org/title> "The Great Book \\n" .' ,
179+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
180+ ] ;
181+
182+ const grouped = groupNquadsBySubject ( quads ) ;
183+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
184+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
185+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
186+ } ) ;
187+
188+ it ( "should group quads where the object is a typed literal" , ( ) => {
189+ /* JSON-LD
190+ {
191+ "@context ": "http://schema.org",
192+ "@id": "http://example.org/book1",
193+ "type": "Book",
194+ "publicationDate": {
195+ "@value ": "2025-05-28",
196+ "@type": "http://www.w3.org/2001/XMLSchema#date"
197+ }
198+ }
199+ */
200+ const quads = [
201+ '<http://example.org/book1> <http://schema.org/publicationDate> "2025-05-28"^^<http://www.w3.org/2001/XMLSchema#date> .' ,
202+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
203+ ] ;
204+
205+ const grouped = groupNquadsBySubject ( quads ) ;
206+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
207+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
208+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
209+ } ) ;
210+
211+ it ( "should group quads where the object is a typed literal that includes an escape character" , ( ) => {
212+ /* JSON-LD
213+ {
214+ "@context ": "http://schema.org",
215+ "@id": "http://example.org/book1",
216+ "type": "Book",
217+ "publicationDate": {
218+ "@value ": "2025-05-28 \n",
219+ "@type": "http://www.w3.org/2001/XMLSchema#date"
220+ }
221+ }
222+ */
223+ const quads = [
224+ // \n is represented as \\n in code
225+ '<http://example.org/book1> <http://schema.org/publicationDate> "2025-05-28 \\n"^^<http://www.w3.org/2001/XMLSchema#date> .' ,
226+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
227+ ] ;
228+
229+ const grouped = groupNquadsBySubject ( quads ) ;
230+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
231+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
232+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
233+ } ) ;
234+
235+ it ( "should group quads where the object is a literal with language defined" , ( ) => {
236+ /* JSON-LD
237+ {
238+ "@context ": "http://schema.org",
239+ "@id": "http://example.org/book1",
240+ "type": "Book",
241+ "description": [
242+ {
243+ "@value ": "A thrilling adventure novel.",
244+ "@language": "en"
245+ },
246+ {
247+ "@value ": "Napeta pustolovska novela.",
248+ "@language": "sl"
249+ }
250+ ]
251+ }
252+ */
253+ const quads = [
254+ '<http://example.org/book1> <http://schema.org/description> "A thrilling adventure novel."@en .' ,
255+ '<http://example.org/book1> <http://schema.org/description> "Napeta pustolovska novela."@sl .' ,
256+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
257+ ] ;
258+
259+ const grouped = groupNquadsBySubject ( quads ) ;
260+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
261+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
262+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
263+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 2 ] ) ;
264+ } ) ;
265+
266+ it ( "should group quads where the object is a literal with language defined, containing an escape character" , ( ) => {
267+ /* JSON-LD
268+ {
269+ "@context ": "http://schema.org",
270+ "@id": "http://example.org/book1",
271+ "type": "Book",
272+ "description": [
273+ {
274+ "@value ": "A thrilling adventure novel. \n",
275+ "@language": "en"
276+ },
277+ {
278+ "@value ": "Napeta pustolovska novela. \n",
279+ "@language": "sl"
280+ }
281+ ]
282+ }
283+ */
284+ const quads = [
285+ // \n is represented as \\n in code
286+ '<http://example.org/book1> <http://schema.org/description> "A thrilling adventure novel. \\n"@en .' ,
287+ '<http://example.org/book1> <http://schema.org/description> "Napeta pustolovska novela. \\n"@sl .' ,
288+ '<http://example.org/book1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Book> .' ,
289+ ] ;
290+
291+ const grouped = groupNquadsBySubject ( quads ) ;
292+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
293+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
294+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 1 ] ) ;
295+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 2 ] ) ;
296+ } ) ;
297+
298+ it ( "should group quads where the object is a literal with language defined, while subject is a blank node" , ( ) => {
299+ /* JSON-LD
300+ {
301+ "@context ": {
302+ "predicate": "http://example.org/predicate"
303+ },
304+ "@graph": [
305+ {
306+ "predicate": {
307+ "@value ": "something",
308+ "@language": "en"
309+ }
310+ }
311+ ]
312+ }
313+ */
314+ const quads = [
315+ '<SOME-UUID> <http://example.org/predicate> "something"@en .' ,
316+ ] ;
317+
318+ const grouped = groupNquadsBySubject ( quads ) ;
319+ expect ( grouped ) . to . have . lengthOf ( 1 ) ;
320+ expect ( grouped [ 0 ] ) . to . deep . include ( quads [ 0 ] ) ;
138321 } ) ;
139322
140323 it ( "should group quads by multiple subjects" , ( ) => {
0 commit comments