json-ld 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AUTHORS +1 -1
- data/README.md +90 -53
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/jsonld +4 -4
- data/lib/json/ld.rb +27 -10
- data/lib/json/ld/api.rb +325 -96
- data/lib/json/ld/compact.rb +75 -27
- data/lib/json/ld/conneg.rb +188 -0
- data/lib/json/ld/context.rb +677 -292
- data/lib/json/ld/expand.rb +240 -75
- data/lib/json/ld/flatten.rb +5 -3
- data/lib/json/ld/format.rb +19 -19
- data/lib/json/ld/frame.rb +135 -85
- data/lib/json/ld/from_rdf.rb +44 -17
- data/lib/json/ld/html/nokogiri.rb +151 -0
- data/lib/json/ld/html/rexml.rb +186 -0
- data/lib/json/ld/reader.rb +25 -5
- data/lib/json/ld/resource.rb +2 -2
- data/lib/json/ld/streaming_writer.rb +3 -1
- data/lib/json/ld/to_rdf.rb +47 -17
- data/lib/json/ld/utils.rb +4 -2
- data/lib/json/ld/writer.rb +75 -14
- data/spec/api_spec.rb +13 -34
- data/spec/compact_spec.rb +968 -9
- data/spec/conneg_spec.rb +373 -0
- data/spec/context_spec.rb +447 -53
- data/spec/expand_spec.rb +1872 -416
- data/spec/flatten_spec.rb +434 -47
- data/spec/frame_spec.rb +979 -344
- data/spec/from_rdf_spec.rb +305 -5
- data/spec/spec_helper.rb +177 -0
- data/spec/streaming_writer_spec.rb +4 -4
- data/spec/suite_compact_spec.rb +2 -2
- data/spec/suite_expand_spec.rb +14 -2
- data/spec/suite_flatten_spec.rb +10 -2
- data/spec/suite_frame_spec.rb +3 -2
- data/spec/suite_from_rdf_spec.rb +2 -2
- data/spec/suite_helper.rb +55 -20
- data/spec/suite_html_spec.rb +22 -0
- data/spec/suite_http_spec.rb +35 -0
- data/spec/suite_remote_doc_spec.rb +2 -2
- data/spec/suite_to_rdf_spec.rb +14 -3
- data/spec/support/extensions.rb +5 -1
- data/spec/test-files/test-4-input.json +3 -3
- data/spec/test-files/test-5-input.json +2 -2
- data/spec/test-files/test-8-framed.json +14 -18
- data/spec/to_rdf_spec.rb +606 -16
- data/spec/writer_spec.rb +5 -5
- metadata +144 -88
data/spec/expand_spec.rb
CHANGED
@@ -162,6 +162,21 @@ describe JSON::LD::API do
|
|
162
162
|
"http://example.com/foo": [{"@id": "http://example.org/bar"}]
|
163
163
|
}])
|
164
164
|
},
|
165
|
+
"json-ld-syntax#66": {
|
166
|
+
input: %({
|
167
|
+
"@context": {
|
168
|
+
"@base": "https://ex.org/",
|
169
|
+
"u": {"@id": "urn:u:", "@type": "@id"}
|
170
|
+
},
|
171
|
+
"u": ["#Test", "#Test:2"]
|
172
|
+
}),
|
173
|
+
output: %([{
|
174
|
+
"urn:u:": [
|
175
|
+
{"@id": "https://ex.org/#Test"},
|
176
|
+
{"@id": "https://ex.org/#Test:2"}
|
177
|
+
]
|
178
|
+
}])
|
179
|
+
}
|
165
180
|
}.each do |title, params|
|
166
181
|
it(title) {run_expand params.merge(base: "http://example.org/")}
|
167
182
|
end
|
@@ -300,6 +315,65 @@ describe JSON::LD::API do
|
|
300
315
|
it(title) {run_expand params.merge(base: "http://example.org/")}
|
301
316
|
end
|
302
317
|
end
|
318
|
+
|
319
|
+
context "with @vocab: '/relative#'" do
|
320
|
+
{
|
321
|
+
"base": {
|
322
|
+
input: %({
|
323
|
+
"@context": {"@vocab": "/relative#"},
|
324
|
+
"http://a/b": "foo"
|
325
|
+
}),
|
326
|
+
output: %([{
|
327
|
+
"http://a/b": [{"@value": "foo"}]
|
328
|
+
}])
|
329
|
+
},
|
330
|
+
"relative": {
|
331
|
+
input: %({
|
332
|
+
"@context": {"@vocab": "/relative#"},
|
333
|
+
"a/b": "foo"
|
334
|
+
}),
|
335
|
+
output: %([{
|
336
|
+
"http://example.org/relative#a/b": [{"@value": "foo"}]
|
337
|
+
}])
|
338
|
+
},
|
339
|
+
"hash": {
|
340
|
+
input: %({
|
341
|
+
"@context": {"@vocab": "/relative#"},
|
342
|
+
"#a": "foo"
|
343
|
+
}),
|
344
|
+
output: %([{
|
345
|
+
"http://example.org/relative##a": [{"@value": "foo"}]
|
346
|
+
}])
|
347
|
+
},
|
348
|
+
"dotseg": {
|
349
|
+
input: %({
|
350
|
+
"@context": {"@vocab": "/relative#"},
|
351
|
+
"../a": "foo"
|
352
|
+
}),
|
353
|
+
output: %([{
|
354
|
+
"http://example.org/relative#../a": [{"@value": "foo"}]
|
355
|
+
}])
|
356
|
+
},
|
357
|
+
"example": {
|
358
|
+
input: %({
|
359
|
+
"@context": {
|
360
|
+
"@base": "http://example/document",
|
361
|
+
"@vocab": "/relative#"
|
362
|
+
},
|
363
|
+
"@id": "http://example.org/places#BrewEats",
|
364
|
+
"@type": "Restaurant",
|
365
|
+
"name": "Brew Eats"
|
366
|
+
}),
|
367
|
+
output: %([{
|
368
|
+
"@id": "http://example.org/places#BrewEats",
|
369
|
+
"@type": ["http://example/relative#Restaurant"],
|
370
|
+
"http://example/relative#name": [{"@value": "Brew Eats"}]
|
371
|
+
}])
|
372
|
+
}
|
373
|
+
}.each do |title, params|
|
374
|
+
it(title) {run_expand params.merge(base: "http://example.org/")}
|
375
|
+
end
|
376
|
+
end
|
303
377
|
end
|
304
378
|
|
305
379
|
context "keyword aliasing" do
|
@@ -409,6 +483,58 @@ describe JSON::LD::API do
|
|
409
483
|
it(title) {run_expand params}
|
410
484
|
end
|
411
485
|
|
486
|
+
context "with @type: @none" do
|
487
|
+
{
|
488
|
+
"true": {
|
489
|
+
input: %({
|
490
|
+
"@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}},
|
491
|
+
"e": true
|
492
|
+
}),
|
493
|
+
output:%( [{
|
494
|
+
"http://example.org/vocab#bool": [{"@value": true}]
|
495
|
+
}])
|
496
|
+
},
|
497
|
+
"false": {
|
498
|
+
input: %({
|
499
|
+
"@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}},
|
500
|
+
"e": false
|
501
|
+
}),
|
502
|
+
output: %([{
|
503
|
+
"http://example.org/vocab#bool": [{"@value": false}]
|
504
|
+
}])
|
505
|
+
},
|
506
|
+
"double": {
|
507
|
+
input: %({
|
508
|
+
"@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}},
|
509
|
+
"e": 1.23
|
510
|
+
}),
|
511
|
+
output: %([{
|
512
|
+
"http://example.org/vocab#double": [{"@value": 1.23}]
|
513
|
+
}])
|
514
|
+
},
|
515
|
+
"double-zero": {
|
516
|
+
input: %({
|
517
|
+
"@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}},
|
518
|
+
"e": 0.0e0
|
519
|
+
}),
|
520
|
+
output: %([{
|
521
|
+
"http://example.org/vocab#double": [{"@value": 0.0e0}]
|
522
|
+
}])
|
523
|
+
},
|
524
|
+
"integer": {
|
525
|
+
input: %({
|
526
|
+
"@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@none"}},
|
527
|
+
"e": 123
|
528
|
+
}),
|
529
|
+
output: %([{
|
530
|
+
"http://example.org/vocab#integer": [{"@value": 123}]
|
531
|
+
}])
|
532
|
+
},
|
533
|
+
}.each do |title, params|
|
534
|
+
it(title) {run_expand(processingMode: "json-ld-1.1", **params)}
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
412
538
|
context "with @type: @id" do
|
413
539
|
{
|
414
540
|
"true": {
|
@@ -514,25 +640,176 @@ describe JSON::LD::API do
|
|
514
640
|
end
|
515
641
|
end
|
516
642
|
|
643
|
+
context "with @type: @json" do
|
644
|
+
{
|
645
|
+
"true": {
|
646
|
+
input: %({
|
647
|
+
"@context": {
|
648
|
+
"@version": 1.1,
|
649
|
+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
|
650
|
+
},
|
651
|
+
"e": true
|
652
|
+
}),
|
653
|
+
output:%( [{
|
654
|
+
"http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}]
|
655
|
+
}])
|
656
|
+
},
|
657
|
+
"false": {
|
658
|
+
input: %({
|
659
|
+
"@context": {
|
660
|
+
"@version": 1.1,
|
661
|
+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
|
662
|
+
},
|
663
|
+
"e": false
|
664
|
+
}),
|
665
|
+
output: %([{
|
666
|
+
"http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}]
|
667
|
+
}])
|
668
|
+
},
|
669
|
+
"double": {
|
670
|
+
input: %({
|
671
|
+
"@context": {
|
672
|
+
"@version": 1.1,
|
673
|
+
"e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
|
674
|
+
},
|
675
|
+
"e": 1.23
|
676
|
+
}),
|
677
|
+
output: %([{
|
678
|
+
"http://example.org/vocab#double": [{"@value": 1.23, "@type": "@json"}]
|
679
|
+
}])
|
680
|
+
},
|
681
|
+
"double-zero": {
|
682
|
+
input: %({
|
683
|
+
"@context": {
|
684
|
+
"@version": 1.1,
|
685
|
+
"e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
|
686
|
+
},
|
687
|
+
"e": 0.0e0
|
688
|
+
}),
|
689
|
+
output: %([{
|
690
|
+
"http://example.org/vocab#double": [{"@value": 0.0e0, "@type": "@json"}]
|
691
|
+
}])
|
692
|
+
},
|
693
|
+
"integer": {
|
694
|
+
input: %({
|
695
|
+
"@context": {
|
696
|
+
"@version": 1.1,
|
697
|
+
"e": {"@id": "http://example.org/vocab#integer", "@type": "@json"}
|
698
|
+
},
|
699
|
+
"e": 123
|
700
|
+
}),
|
701
|
+
output: %([{
|
702
|
+
"http://example.org/vocab#integer": [{"@value": 123, "@type": "@json"}]
|
703
|
+
}])
|
704
|
+
},
|
705
|
+
"string": {
|
706
|
+
input: %({
|
707
|
+
"@context": {
|
708
|
+
"@version": 1.1,
|
709
|
+
"e": {"@id": "http://example.org/vocab#string", "@type": "@json"}
|
710
|
+
},
|
711
|
+
"e": "string"
|
712
|
+
}),
|
713
|
+
output: %([{
|
714
|
+
"http://example.org/vocab#string": [{
|
715
|
+
"@value": "string",
|
716
|
+
"@type": "@json"
|
717
|
+
}]
|
718
|
+
}])
|
719
|
+
},
|
720
|
+
"null": {
|
721
|
+
input: %({
|
722
|
+
"@context": {
|
723
|
+
"@version": 1.1,
|
724
|
+
"e": {"@id": "http://example.org/vocab#null", "@type": "@json"}
|
725
|
+
},
|
726
|
+
"e": null
|
727
|
+
}),
|
728
|
+
output: %([{
|
729
|
+
"http://example.org/vocab#null": [{
|
730
|
+
"@value": null,
|
731
|
+
"@type": "@json"
|
732
|
+
}]
|
733
|
+
}])
|
734
|
+
},
|
735
|
+
"object": {
|
736
|
+
input: %({
|
737
|
+
"@context": {
|
738
|
+
"@version": 1.1,
|
739
|
+
"e": {"@id": "http://example.org/vocab#object", "@type": "@json"}
|
740
|
+
},
|
741
|
+
"e": {"foo": "bar"}
|
742
|
+
}),
|
743
|
+
output: %([{
|
744
|
+
"http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
|
745
|
+
}])
|
746
|
+
},
|
747
|
+
"array": {
|
748
|
+
input: %({
|
749
|
+
"@context": {
|
750
|
+
"@version": 1.1,
|
751
|
+
"e": {"@id": "http://example.org/vocab#array", "@type": "@json"}
|
752
|
+
},
|
753
|
+
"e": [{"foo": "bar"}]
|
754
|
+
}),
|
755
|
+
output: %([{
|
756
|
+
"http://example.org/vocab#array": [{"@value": [{"foo": "bar"}], "@type": "@json"}]
|
757
|
+
}])
|
758
|
+
},
|
759
|
+
"Does not expand terms inside json": {
|
760
|
+
input: %({
|
761
|
+
"@context": {
|
762
|
+
"@version": 1.1,
|
763
|
+
"e": {"@id": "http://example.org/vocab#array", "@type": "@json"}
|
764
|
+
},
|
765
|
+
"e": [{"e": "bar"}]
|
766
|
+
}),
|
767
|
+
output: %([{
|
768
|
+
"http://example.org/vocab#array": [{"@value": [{"e": "bar"}], "@type": "@json"}]
|
769
|
+
}])
|
770
|
+
},
|
771
|
+
"Already expanded object": {
|
772
|
+
input: %({
|
773
|
+
"http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
|
774
|
+
}),
|
775
|
+
output: %([{
|
776
|
+
"http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
|
777
|
+
}]),
|
778
|
+
processingMode: 'json-ld-1.1'
|
779
|
+
},
|
780
|
+
"Already expanded object with aliased keys": {
|
781
|
+
input: %({
|
782
|
+
"@context": {"@version": 1.1, "value": "@value", "type": "@type", "json": "@json"},
|
783
|
+
"http://example.org/vocab#object": [{"value": {"foo": "bar"}, "type": "json"}]
|
784
|
+
}),
|
785
|
+
output: %([{
|
786
|
+
"http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
|
787
|
+
}])
|
788
|
+
},
|
789
|
+
}.each do |title, params|
|
790
|
+
it(title) {run_expand params}
|
791
|
+
end
|
792
|
+
end
|
793
|
+
|
517
794
|
context "coerced typed values" do
|
518
795
|
{
|
519
|
-
"boolean"
|
520
|
-
input: {
|
521
|
-
"@context"
|
522
|
-
"foo"
|
523
|
-
},
|
524
|
-
output: [{
|
525
|
-
"http://example.org/foo"
|
526
|
-
}]
|
796
|
+
"boolean": {
|
797
|
+
input: %({
|
798
|
+
"@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}},
|
799
|
+
"foo": "true"
|
800
|
+
}),
|
801
|
+
output: %([{
|
802
|
+
"http://example.org/foo": [{"@value": "true", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}]
|
803
|
+
}])
|
527
804
|
},
|
528
|
-
"date"
|
529
|
-
input: {
|
530
|
-
"@context"
|
531
|
-
"foo"
|
532
|
-
},
|
533
|
-
output: [{
|
534
|
-
"http://example.org/foo"
|
535
|
-
}]
|
805
|
+
"date": {
|
806
|
+
input: %({
|
807
|
+
"@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#date"}},
|
808
|
+
"foo": "2011-03-26"
|
809
|
+
}),
|
810
|
+
output: %([{
|
811
|
+
"http://example.org/foo": [{"@value": "2011-03-26", "@type": "http://www.w3.org/2001/XMLSchema#date"}]
|
812
|
+
}])
|
536
813
|
},
|
537
814
|
}.each do |title, params|
|
538
815
|
it(title) {run_expand params}
|
@@ -541,127 +818,196 @@ describe JSON::LD::API do
|
|
541
818
|
|
542
819
|
context "null" do
|
543
820
|
{
|
544
|
-
"value"
|
545
|
-
input: {"http://example.com/foo"
|
821
|
+
"value": {
|
822
|
+
input: %({"http://example.com/foo": null}),
|
546
823
|
output: []
|
547
824
|
},
|
548
|
-
"@value"
|
549
|
-
input: {"http://example.com/foo"
|
825
|
+
"@value": {
|
826
|
+
input: %({"http://example.com/foo": {"@value": null}}),
|
550
827
|
output: []
|
551
828
|
},
|
552
|
-
"@value and non-null @type"
|
553
|
-
input: {"http://example.com/foo"
|
829
|
+
"@value and non-null @type": {
|
830
|
+
input: %({"http://example.com/foo": {"@value": null, "@type": "http://type"}}),
|
554
831
|
output: []
|
555
832
|
},
|
556
|
-
"@value and non-null @language"
|
557
|
-
input: {"http://example.com/foo"
|
833
|
+
"@value and non-null @language": {
|
834
|
+
input: %({"http://example.com/foo": {"@value": null, "@language": "en"}}),
|
558
835
|
output: []
|
559
836
|
},
|
560
|
-
"array with null elements"
|
561
|
-
input: {
|
562
|
-
|
563
|
-
},
|
564
|
-
output: [{
|
565
|
-
"http://example.com/foo" => []
|
566
|
-
}]
|
837
|
+
"array with null elements": {
|
838
|
+
input: %({"http://example.com/foo": [null]}),
|
839
|
+
output: %([{"http://example.com/foo": []}])
|
567
840
|
},
|
568
|
-
"@set with null @value"
|
569
|
-
input: {
|
570
|
-
"http://example.com/foo"
|
571
|
-
{"@value"
|
841
|
+
"@set with null @value": {
|
842
|
+
input: %({
|
843
|
+
"http://example.com/foo": [
|
844
|
+
{"@value": null, "@type": "http://example.org/Type"}
|
572
845
|
]
|
573
|
-
},
|
574
|
-
output: [{
|
575
|
-
"http://example.com/foo"
|
576
|
-
}]
|
846
|
+
}),
|
847
|
+
output: %([{
|
848
|
+
"http://example.com/foo": []
|
849
|
+
}])
|
577
850
|
}
|
578
851
|
}.each do |title, params|
|
579
852
|
it(title) {run_expand params}
|
580
853
|
end
|
581
854
|
end
|
582
855
|
|
856
|
+
context "@direction" do
|
857
|
+
{
|
858
|
+
"value with coerced null direction": {
|
859
|
+
input: %({
|
860
|
+
"@context": {
|
861
|
+
"@direction": "rtl",
|
862
|
+
"ex": "http://example.org/vocab#",
|
863
|
+
"ex:ltr": { "@direction": "ltr" },
|
864
|
+
"ex:none": { "@direction": null }
|
865
|
+
},
|
866
|
+
"ex:rtl": "rtl",
|
867
|
+
"ex:ltr": "ltr",
|
868
|
+
"ex:none": "no direction"
|
869
|
+
}),
|
870
|
+
output: %([
|
871
|
+
{
|
872
|
+
"http://example.org/vocab#rtl": [{"@value": "rtl", "@direction": "rtl"}],
|
873
|
+
"http://example.org/vocab#ltr": [{"@value": "ltr", "@direction": "ltr"}],
|
874
|
+
"http://example.org/vocab#none": [{"@value": "no direction"}]
|
875
|
+
}
|
876
|
+
])
|
877
|
+
}
|
878
|
+
}.each_pair do |title, params|
|
879
|
+
it(title) {run_expand params}
|
880
|
+
end
|
881
|
+
end
|
882
|
+
|
583
883
|
context "default language" do
|
584
884
|
{
|
585
|
-
"value with coerced null language"
|
586
|
-
input: {
|
587
|
-
"@context"
|
588
|
-
"@language"
|
589
|
-
"ex"
|
590
|
-
"ex:german"
|
591
|
-
"ex:nolang"
|
592
|
-
},
|
593
|
-
"ex:german"
|
594
|
-
"ex:nolang"
|
595
|
-
},
|
596
|
-
output: [
|
885
|
+
"value with coerced null language": {
|
886
|
+
input: %({
|
887
|
+
"@context": {
|
888
|
+
"@language": "en",
|
889
|
+
"ex": "http://example.org/vocab#",
|
890
|
+
"ex:german": { "@language": "de" },
|
891
|
+
"ex:nolang": { "@language": null }
|
892
|
+
},
|
893
|
+
"ex:german": "german",
|
894
|
+
"ex:nolang": "no language"
|
895
|
+
}),
|
896
|
+
output: %([
|
597
897
|
{
|
598
|
-
"http://example.org/vocab#german"
|
599
|
-
"http://example.org/vocab#nolang"
|
898
|
+
"http://example.org/vocab#german": [{"@value": "german", "@language": "de"}],
|
899
|
+
"http://example.org/vocab#nolang": [{"@value": "no language"}]
|
600
900
|
}
|
601
|
-
]
|
901
|
+
])
|
602
902
|
},
|
603
903
|
}.each do |title, params|
|
604
904
|
it(title) {run_expand params}
|
605
905
|
end
|
906
|
+
|
907
|
+
context "and default direction" do
|
908
|
+
{
|
909
|
+
"value with coerced null direction": {
|
910
|
+
input: %({
|
911
|
+
"@context": {
|
912
|
+
"@language": "en",
|
913
|
+
"@direction": "rtl",
|
914
|
+
"ex": "http://example.org/vocab#",
|
915
|
+
"ex:ltr": { "@direction": "ltr" },
|
916
|
+
"ex:none": { "@direction": null },
|
917
|
+
"ex:german": { "@language": "de" },
|
918
|
+
"ex:nolang": { "@language": null },
|
919
|
+
"ex:german_ltr": { "@language": "de", "@direction": "ltr" },
|
920
|
+
"ex:nolang_ltr": { "@language": null, "@direction": "ltr" },
|
921
|
+
"ex:none_none": { "@language": null, "@direction": null },
|
922
|
+
"ex:german_none": { "@language": "de", "@direction": null }
|
923
|
+
},
|
924
|
+
"ex:rtl": "rtl en",
|
925
|
+
"ex:ltr": "ltr en",
|
926
|
+
"ex:none": "no direction en",
|
927
|
+
"ex:german": "german rtl",
|
928
|
+
"ex:nolang": "no language rtl",
|
929
|
+
"ex:german_ltr": "german ltr",
|
930
|
+
"ex:nolang_ltr": "no language ltr",
|
931
|
+
"ex:none_none": "no language or direction",
|
932
|
+
"ex:german_none": "german no direction"
|
933
|
+
}),
|
934
|
+
output: %([
|
935
|
+
{
|
936
|
+
"http://example.org/vocab#rtl": [{"@value": "rtl en", "@language": "en", "@direction": "rtl"}],
|
937
|
+
"http://example.org/vocab#ltr": [{"@value": "ltr en", "@language": "en", "@direction": "ltr"}],
|
938
|
+
"http://example.org/vocab#none": [{"@value": "no direction en", "@language": "en"}],
|
939
|
+
"http://example.org/vocab#german": [{"@value": "german rtl", "@language": "de", "@direction": "rtl"}],
|
940
|
+
"http://example.org/vocab#nolang": [{"@value": "no language rtl", "@direction": "rtl"}],
|
941
|
+
"http://example.org/vocab#german_ltr": [{"@value": "german ltr", "@language": "de", "@direction": "ltr"}],
|
942
|
+
"http://example.org/vocab#nolang_ltr": [{"@value": "no language ltr", "@direction": "ltr"}],
|
943
|
+
"http://example.org/vocab#none_none": [{"@value": "no language or direction"}],
|
944
|
+
"http://example.org/vocab#german_none": [{"@value": "german no direction", "@language": "de"}]
|
945
|
+
}
|
946
|
+
])
|
947
|
+
}
|
948
|
+
}.each_pair do |title, params|
|
949
|
+
it(title) {run_expand params}
|
950
|
+
end
|
951
|
+
end
|
606
952
|
end
|
607
953
|
|
608
954
|
context "default vocabulary" do
|
609
955
|
{
|
610
|
-
"property"
|
611
|
-
input: {
|
612
|
-
"@context"
|
613
|
-
"verb"
|
614
|
-
},
|
615
|
-
output: [{
|
616
|
-
"http://example.com/verb"
|
617
|
-
}]
|
956
|
+
"property": {
|
957
|
+
input: %({
|
958
|
+
"@context": {"@vocab": "http://example.com/"},
|
959
|
+
"verb": {"@value": "foo"}
|
960
|
+
}),
|
961
|
+
output: %([{
|
962
|
+
"http://example.com/verb": [{"@value": "foo"}]
|
963
|
+
}])
|
618
964
|
},
|
619
|
-
"datatype"
|
620
|
-
input: {
|
621
|
-
"@context"
|
622
|
-
"http://example.org/verb"
|
623
|
-
},
|
624
|
-
output: [
|
625
|
-
"http://example.org/verb"
|
626
|
-
]
|
965
|
+
"datatype": {
|
966
|
+
input: %({
|
967
|
+
"@context": {"@vocab": "http://example.com/"},
|
968
|
+
"http://example.org/verb": {"@value": "foo", "@type": "string"}
|
969
|
+
}),
|
970
|
+
output: %([{
|
971
|
+
"http://example.org/verb": [{"@value": "foo", "@type": "http://example.com/string"}]
|
972
|
+
}])
|
627
973
|
},
|
628
|
-
"expand-0028"
|
629
|
-
input: {
|
630
|
-
"@context"
|
631
|
-
"@vocab"
|
632
|
-
"date"
|
974
|
+
"expand-0028": {
|
975
|
+
input: %({
|
976
|
+
"@context": {
|
977
|
+
"@vocab": "http://example.org/vocab#",
|
978
|
+
"date": { "@type": "dateTime" }
|
633
979
|
},
|
634
|
-
"@id"
|
635
|
-
"@type"
|
636
|
-
"date"
|
637
|
-
"embed"
|
638
|
-
"@id"
|
639
|
-
"expandedDate"
|
980
|
+
"@id": "example1",
|
981
|
+
"@type": "test",
|
982
|
+
"date": "2011-01-25T00:00:00Z",
|
983
|
+
"embed": {
|
984
|
+
"@id": "example2",
|
985
|
+
"expandedDate": { "@value": "2012-08-01T00:00:00Z", "@type": "dateTime" }
|
640
986
|
}
|
641
|
-
},
|
642
|
-
output: [
|
987
|
+
}),
|
988
|
+
output: %([
|
643
989
|
{
|
644
|
-
"@id"
|
645
|
-
"@type"
|
646
|
-
"http://example.org/vocab#date"
|
990
|
+
"@id": "http://foo/bar/example1",
|
991
|
+
"@type": ["http://example.org/vocab#test"],
|
992
|
+
"http://example.org/vocab#date": [
|
647
993
|
{
|
648
|
-
"@value"
|
649
|
-
"@type"
|
994
|
+
"@value": "2011-01-25T00:00:00Z",
|
995
|
+
"@type": "http://example.org/vocab#dateTime"
|
650
996
|
}
|
651
997
|
],
|
652
|
-
"http://example.org/vocab#embed"
|
998
|
+
"http://example.org/vocab#embed": [
|
653
999
|
{
|
654
|
-
"@id"
|
655
|
-
"http://example.org/vocab#expandedDate"
|
1000
|
+
"@id": "http://foo/bar/example2",
|
1001
|
+
"http://example.org/vocab#expandedDate": [
|
656
1002
|
{
|
657
|
-
"@value"
|
658
|
-
"@type"
|
1003
|
+
"@value": "2012-08-01T00:00:00Z",
|
1004
|
+
"@type": "http://example.org/vocab#dateTime"
|
659
1005
|
}
|
660
1006
|
]
|
661
1007
|
}
|
662
1008
|
]
|
663
1009
|
}
|
664
|
-
]
|
1010
|
+
])
|
665
1011
|
}
|
666
1012
|
}.each do |title, params|
|
667
1013
|
it(title) {run_expand params.merge(base: "http://foo/bar/")}
|
@@ -670,51 +1016,47 @@ describe JSON::LD::API do
|
|
670
1016
|
|
671
1017
|
context "unmapped properties" do
|
672
1018
|
{
|
673
|
-
"unmapped key"
|
674
|
-
input: {
|
675
|
-
"foo" => "bar"
|
676
|
-
},
|
1019
|
+
"unmapped key": {
|
1020
|
+
input: %({"foo": "bar"}),
|
677
1021
|
output: []
|
678
1022
|
},
|
679
|
-
"unmapped @type as datatype"
|
680
|
-
input: {
|
681
|
-
"http://example.com/foo"
|
682
|
-
},
|
683
|
-
output: [{
|
684
|
-
"http://example.com/foo"
|
685
|
-
}]
|
1023
|
+
"unmapped @type as datatype": {
|
1024
|
+
input: %({
|
1025
|
+
"http://example.com/foo": {"@value": "bar", "@type": "baz"}
|
1026
|
+
}),
|
1027
|
+
output: %([{
|
1028
|
+
"http://example.com/foo": [{"@value": "bar", "@type": "http://example/baz"}]
|
1029
|
+
}])
|
686
1030
|
},
|
687
|
-
"unknown keyword"
|
688
|
-
input: {
|
689
|
-
"@foo" => "bar"
|
690
|
-
},
|
1031
|
+
"unknown keyword": {
|
1032
|
+
input: %({"@foo": "bar"}),
|
691
1033
|
output: []
|
692
1034
|
},
|
693
|
-
"value"
|
694
|
-
input: {
|
695
|
-
"@context"
|
696
|
-
"@id"
|
697
|
-
"idrange"
|
698
|
-
},
|
1035
|
+
"value": {
|
1036
|
+
input: %({
|
1037
|
+
"@context": {"ex": {"@id": "http://example.org/idrange", "@type": "@id"}},
|
1038
|
+
"@id": "http://example.org/Subj",
|
1039
|
+
"idrange": "unmapped"
|
1040
|
+
}),
|
699
1041
|
output: []
|
700
1042
|
},
|
701
|
-
"context reset"
|
702
|
-
input: {
|
703
|
-
"@context"
|
704
|
-
"@id"
|
705
|
-
"prop"
|
706
|
-
"ex:chain"
|
707
|
-
"@context"
|
708
|
-
"@id"
|
709
|
-
"prop"
|
1043
|
+
"context reset": {
|
1044
|
+
input: %({
|
1045
|
+
"@context": {"ex": "http://example.org/", "prop": "ex:prop"},
|
1046
|
+
"@id": "http://example.org/id1",
|
1047
|
+
"prop": "prop",
|
1048
|
+
"ex:chain": {
|
1049
|
+
"@context": null,
|
1050
|
+
"@id": "http://example.org/id2",
|
1051
|
+
"prop": "prop"
|
710
1052
|
}
|
711
|
-
},
|
712
|
-
output: [{
|
713
|
-
"@id"
|
714
|
-
"http://example.org/prop"
|
715
|
-
"http://example.org/chain"
|
716
|
-
}
|
717
|
-
|
1053
|
+
}),
|
1054
|
+
output: %([{
|
1055
|
+
"@id": "http://example.org/id1",
|
1056
|
+
"http://example.org/prop": [{"@value": "prop"}],
|
1057
|
+
"http://example.org/chain": [{"@id": "http://example.org/id2"}]
|
1058
|
+
}])
|
1059
|
+
}
|
718
1060
|
}.each do |title, params|
|
719
1061
|
it(title) {run_expand params.merge(base: "http://example/")}
|
720
1062
|
end
|
@@ -722,92 +1064,311 @@ describe JSON::LD::API do
|
|
722
1064
|
|
723
1065
|
context "@container: @index" do
|
724
1066
|
{
|
725
|
-
"string annotation"
|
726
|
-
input: {
|
727
|
-
"@context"
|
728
|
-
"container"
|
729
|
-
"@id"
|
730
|
-
"@container"
|
1067
|
+
"string annotation": {
|
1068
|
+
input: %({
|
1069
|
+
"@context": {
|
1070
|
+
"container": {
|
1071
|
+
"@id": "http://example.com/container",
|
1072
|
+
"@container": "@index"
|
731
1073
|
}
|
732
1074
|
},
|
733
|
-
"@id"
|
734
|
-
"container"
|
735
|
-
"en"
|
736
|
-
"de"
|
737
|
-
}
|
738
|
-
},
|
739
|
-
output: [
|
740
|
-
{
|
741
|
-
"@id" => "http://example.com/annotationsTest",
|
742
|
-
"http://example.com/container" => [
|
743
|
-
{"@value" => "Die Königin", "@index" => "de"},
|
744
|
-
{"@value" => "Ihre Majestät", "@index" => "de"},
|
745
|
-
{"@value" => "The Queen", "@index" => "en"}
|
746
|
-
]
|
1075
|
+
"@id": "http://example.com/annotationsTest",
|
1076
|
+
"container": {
|
1077
|
+
"en": "The Queen",
|
1078
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
747
1079
|
}
|
748
|
-
|
1080
|
+
}),
|
1081
|
+
output: %([{
|
1082
|
+
"@id": "http://example.com/annotationsTest",
|
1083
|
+
"http://example.com/container": [
|
1084
|
+
{"@value": "Die Königin", "@index": "de"},
|
1085
|
+
{"@value": "Ihre Majestät", "@index": "de"},
|
1086
|
+
{"@value": "The Queen", "@index": "en"}
|
1087
|
+
]
|
1088
|
+
}])
|
749
1089
|
},
|
750
1090
|
}.each do |title, params|
|
751
1091
|
it(title) {run_expand params}
|
752
1092
|
end
|
1093
|
+
|
1094
|
+
context "@index: property" do
|
1095
|
+
{
|
1096
|
+
"error if @version is json-ld-1.0": {
|
1097
|
+
input: %({
|
1098
|
+
"@context": {
|
1099
|
+
"@vocab": "http://example.com/",
|
1100
|
+
"container": {"@container": "@index", "@index": "prop"}
|
1101
|
+
},
|
1102
|
+
"@id": "http://example.com/annotationsTest",
|
1103
|
+
"container": {
|
1104
|
+
"en": "The Queen",
|
1105
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1106
|
+
}
|
1107
|
+
}),
|
1108
|
+
exception: JSON::LD::JsonLdError::InvalidTermDefinition,
|
1109
|
+
processingMode: 'json-ld-1.0'
|
1110
|
+
},
|
1111
|
+
"error if @container does not include @index": {
|
1112
|
+
input: %({
|
1113
|
+
"@context": {
|
1114
|
+
"@version": 1.1,
|
1115
|
+
"@vocab": "http://example.com/",
|
1116
|
+
"container": {"@index": "prop"}
|
1117
|
+
},
|
1118
|
+
"@id": "http://example.com/annotationsTest",
|
1119
|
+
"container": {
|
1120
|
+
"en": "The Queen",
|
1121
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1122
|
+
}
|
1123
|
+
}),
|
1124
|
+
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
1125
|
+
},
|
1126
|
+
"error if @index is a keyword": {
|
1127
|
+
input: %({
|
1128
|
+
"@context": {
|
1129
|
+
"@version": 1.1,
|
1130
|
+
"@vocab": "http://example.com/",
|
1131
|
+
"container": {
|
1132
|
+
"@id": "http://example.com/container",
|
1133
|
+
"@container": "@index",
|
1134
|
+
"@index": "@index"
|
1135
|
+
}
|
1136
|
+
},
|
1137
|
+
"@id": "http://example.com/annotationsTest",
|
1138
|
+
"container": {
|
1139
|
+
"en": "The Queen",
|
1140
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1141
|
+
}
|
1142
|
+
}),
|
1143
|
+
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
1144
|
+
},
|
1145
|
+
"error if @index is not a string": {
|
1146
|
+
input: %({
|
1147
|
+
"@context": {
|
1148
|
+
"@version": 1.1,
|
1149
|
+
"@vocab": "http://example.com/",
|
1150
|
+
"container": {
|
1151
|
+
"@id": "http://example.com/container",
|
1152
|
+
"@container": "@index",
|
1153
|
+
"@index": true
|
1154
|
+
}
|
1155
|
+
},
|
1156
|
+
"@id": "http://example.com/annotationsTest",
|
1157
|
+
"container": {
|
1158
|
+
"en": "The Queen",
|
1159
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1160
|
+
}
|
1161
|
+
}),
|
1162
|
+
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
1163
|
+
},
|
1164
|
+
"error if attempting to add property to value object": {
|
1165
|
+
input: %({
|
1166
|
+
"@context": {
|
1167
|
+
"@version": 1.1,
|
1168
|
+
"@vocab": "http://example.com/",
|
1169
|
+
"container": {
|
1170
|
+
"@id": "http://example.com/container",
|
1171
|
+
"@container": "@index",
|
1172
|
+
"@index": "prop"
|
1173
|
+
}
|
1174
|
+
},
|
1175
|
+
"@id": "http://example.com/annotationsTest",
|
1176
|
+
"container": {
|
1177
|
+
"en": "The Queen",
|
1178
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1179
|
+
}
|
1180
|
+
}),
|
1181
|
+
exception: JSON::LD::JsonLdError::InvalidValueObject
|
1182
|
+
},
|
1183
|
+
"property-valued index expands to property value, instead of @index (value)": {
|
1184
|
+
input: %({
|
1185
|
+
"@context": {
|
1186
|
+
"@version": 1.1,
|
1187
|
+
"@base": "http://example.com/",
|
1188
|
+
"@vocab": "http://example.com/",
|
1189
|
+
"author": {"@type": "@id", "@container": "@index", "@index": "prop"}
|
1190
|
+
},
|
1191
|
+
"@id": "article",
|
1192
|
+
"author": {
|
1193
|
+
"regular": "person/1",
|
1194
|
+
"guest": ["person/2", "person/3"]
|
1195
|
+
}
|
1196
|
+
}),
|
1197
|
+
output: %([{
|
1198
|
+
"@id": "http://example.com/article",
|
1199
|
+
"http://example.com/author": [
|
1200
|
+
{"@id": "http://example.com/person/1", "http://example.com/prop": [{"@value": "regular"}]},
|
1201
|
+
{"@id": "http://example.com/person/2", "http://example.com/prop": [{"@value": "guest"}]},
|
1202
|
+
{"@id": "http://example.com/person/3", "http://example.com/prop": [{"@value": "guest"}]}
|
1203
|
+
]
|
1204
|
+
}])
|
1205
|
+
},
|
1206
|
+
"property-valued index appends to property value, instead of @index (value)": {
|
1207
|
+
input: %({
|
1208
|
+
"@context": {
|
1209
|
+
"@version": 1.1,
|
1210
|
+
"@base": "http://example.com/",
|
1211
|
+
"@vocab": "http://example.com/",
|
1212
|
+
"author": {"@type": "@id", "@container": "@index", "@index": "prop"}
|
1213
|
+
},
|
1214
|
+
"@id": "article",
|
1215
|
+
"author": {
|
1216
|
+
"regular": {"@id": "person/1", "http://example.com/prop": "foo"},
|
1217
|
+
"guest": [
|
1218
|
+
{"@id": "person/2", "prop": "foo"},
|
1219
|
+
{"@id": "person/3", "prop": "foo"}
|
1220
|
+
]
|
1221
|
+
}
|
1222
|
+
}),
|
1223
|
+
output: %([{
|
1224
|
+
"@id": "http://example.com/article",
|
1225
|
+
"http://example.com/author": [
|
1226
|
+
{"@id": "http://example.com/person/1", "http://example.com/prop": [{"@value": "regular"}, {"@value": "foo"}]},
|
1227
|
+
{"@id": "http://example.com/person/2", "http://example.com/prop": [{"@value": "guest"}, {"@value": "foo"}]},
|
1228
|
+
{"@id": "http://example.com/person/3", "http://example.com/prop": [{"@value": "guest"}, {"@value": "foo"}]}
|
1229
|
+
]
|
1230
|
+
}])
|
1231
|
+
},
|
1232
|
+
"property-valued index expands to property value, instead of @index (node)": {
|
1233
|
+
input: %({
|
1234
|
+
"@context": {
|
1235
|
+
"@version": 1.1,
|
1236
|
+
"@base": "http://example.com/",
|
1237
|
+
"@vocab": "http://example.com/",
|
1238
|
+
"author": {"@type": "@id", "@container": "@index", "@index": "prop"},
|
1239
|
+
"prop": {"@type": "@vocab"}
|
1240
|
+
},
|
1241
|
+
"@id": "http://example.com/article",
|
1242
|
+
"author": {
|
1243
|
+
"regular": "person/1",
|
1244
|
+
"guest": ["person/2", "person/3"]
|
1245
|
+
}
|
1246
|
+
}),
|
1247
|
+
output: %([{
|
1248
|
+
"@id": "http://example.com/article",
|
1249
|
+
"http://example.com/author": [
|
1250
|
+
{"@id": "http://example.com/person/1", "http://example.com/prop": [{"@id": "http://example.com/regular"}]},
|
1251
|
+
{"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}]},
|
1252
|
+
{"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}]}
|
1253
|
+
]
|
1254
|
+
}])
|
1255
|
+
},
|
1256
|
+
"property-valued index appends to property value, instead of @index (node)": {
|
1257
|
+
input: %({
|
1258
|
+
"@context": {
|
1259
|
+
"@version": 1.1,
|
1260
|
+
"@base": "http://example.com/",
|
1261
|
+
"@vocab": "http://example.com/",
|
1262
|
+
"author": {"@type": "@id", "@container": "@index", "@index": "prop"},
|
1263
|
+
"prop": {"@type": "@vocab"}
|
1264
|
+
},
|
1265
|
+
"@id": "http://example.com/article",
|
1266
|
+
"author": {
|
1267
|
+
"regular": {"@id": "person/1", "prop": "foo"},
|
1268
|
+
"guest": [
|
1269
|
+
{"@id": "person/2", "prop": "foo"},
|
1270
|
+
{"@id": "person/3", "prop": "foo"}
|
1271
|
+
]
|
1272
|
+
}
|
1273
|
+
}),
|
1274
|
+
output: %([{
|
1275
|
+
"@id": "http://example.com/article",
|
1276
|
+
"http://example.com/author": [
|
1277
|
+
{"@id": "http://example.com/person/1", "http://example.com/prop": [{"@id": "http://example.com/regular"}, {"@id": "http://example.com/foo"}]},
|
1278
|
+
{"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}, {"@id": "http://example.com/foo"}]},
|
1279
|
+
{"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}, {"@id": "http://example.com/foo"}]}
|
1280
|
+
]
|
1281
|
+
}])
|
1282
|
+
},
|
1283
|
+
"property-valued index does not output property for @none": {
|
1284
|
+
input: %({
|
1285
|
+
"@context": {
|
1286
|
+
"@version": 1.1,
|
1287
|
+
"@base": "http://example.com/",
|
1288
|
+
"@vocab": "http://example.com/",
|
1289
|
+
"author": {"@type": "@id", "@container": "@index", "@index": "prop"},
|
1290
|
+
"prop": {"@type": "@vocab"}
|
1291
|
+
},
|
1292
|
+
"@id": "http://example.com/article",
|
1293
|
+
"author": {
|
1294
|
+
"@none": {"@id": "person/1"},
|
1295
|
+
"guest": [
|
1296
|
+
{"@id": "person/2"},
|
1297
|
+
{"@id": "person/3"}
|
1298
|
+
]
|
1299
|
+
}
|
1300
|
+
}),
|
1301
|
+
output: %([{
|
1302
|
+
"@id": "http://example.com/article",
|
1303
|
+
"http://example.com/author": [
|
1304
|
+
{"@id": "http://example.com/person/1"},
|
1305
|
+
{"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}]},
|
1306
|
+
{"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}]}
|
1307
|
+
]
|
1308
|
+
}])
|
1309
|
+
},
|
1310
|
+
}.each do |title, params|
|
1311
|
+
it(title) {run_expand(validate: true, **params)}
|
1312
|
+
end
|
1313
|
+
end
|
753
1314
|
end
|
754
1315
|
|
755
1316
|
context "@container: @list" do
|
756
1317
|
{
|
757
|
-
"empty"
|
758
|
-
input: {"http://example.com/foo"
|
759
|
-
output: [{"http://example.com/foo"
|
760
|
-
},
|
761
|
-
"coerced empty" => {
|
762
|
-
input: {
|
763
|
-
"@context" => {"http://example.com/foo" => {"@container" => "@list"}},
|
764
|
-
"http://example.com/foo" => []
|
765
|
-
},
|
766
|
-
output: [{"http://example.com/foo" => [{"@list" => []}]}]
|
1318
|
+
"empty": {
|
1319
|
+
input: %({"http://example.com/foo": {"@list": []}}),
|
1320
|
+
output: %([{"http://example.com/foo": [{"@list": []}]}])
|
767
1321
|
},
|
768
|
-
"coerced
|
769
|
-
input: {
|
770
|
-
"@context"
|
771
|
-
"http://example.com/foo"
|
772
|
-
},
|
773
|
-
output: [{"http://example.com/foo"
|
1322
|
+
"coerced empty": {
|
1323
|
+
input: %({
|
1324
|
+
"@context": {"http://example.com/foo": {"@container": "@list"}},
|
1325
|
+
"http://example.com/foo": []
|
1326
|
+
}),
|
1327
|
+
output: %([{"http://example.com/foo": [{"@list": []}]}])
|
774
1328
|
},
|
775
|
-
"coerced
|
776
|
-
input: {
|
777
|
-
"@context"
|
778
|
-
"http://example.com/foo"
|
779
|
-
},
|
780
|
-
output: [{
|
781
|
-
"http://example.com/foo" => [{"@list" => [ {"@value" => "foo"}, {"@value" => "bar"} ]}]
|
782
|
-
}]
|
1329
|
+
"coerced single element": {
|
1330
|
+
input: %({
|
1331
|
+
"@context": {"http://example.com/foo": {"@container": "@list"}},
|
1332
|
+
"http://example.com/foo": [ "foo" ]
|
1333
|
+
}),
|
1334
|
+
output: %([{"http://example.com/foo": [{"@list": [{"@value": "foo"}]}]}])
|
783
1335
|
},
|
784
|
-
"
|
785
|
-
input: {
|
786
|
-
"http://example.com/foo"
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
1336
|
+
"coerced multiple elements": {
|
1337
|
+
input: %({
|
1338
|
+
"@context": {"http://example.com/foo": {"@container": "@list"}},
|
1339
|
+
"http://example.com/foo": [ "foo", "bar" ]
|
1340
|
+
}),
|
1341
|
+
output: %([{
|
1342
|
+
"http://example.com/foo": [{"@list": [ {"@value": "foo"}, {"@value": "bar"} ]}]
|
1343
|
+
}])
|
791
1344
|
},
|
792
|
-
"
|
793
|
-
input: {
|
794
|
-
"
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
}]
|
1345
|
+
"native values in list": {
|
1346
|
+
input: %({
|
1347
|
+
"http://example.com/foo": {"@list": [1, 2]}
|
1348
|
+
}),
|
1349
|
+
output: %([{
|
1350
|
+
"http://example.com/foo": [{"@list": [{"@value": 1}, {"@value": 2}]}]
|
1351
|
+
}])
|
800
1352
|
},
|
801
|
-
"explicit list with coerced
|
802
|
-
input: {
|
803
|
-
"@context"
|
804
|
-
"http://example.com/foo"
|
805
|
-
},
|
806
|
-
output: [{
|
807
|
-
"http://example.com/foo"
|
808
|
-
}]
|
1353
|
+
"explicit list with coerced @id values": {
|
1354
|
+
input: %({
|
1355
|
+
"@context": {"http://example.com/foo": {"@type": "@id"}},
|
1356
|
+
"http://example.com/foo": {"@list": ["http://foo", "http://bar"]}
|
1357
|
+
}),
|
1358
|
+
output: %([{
|
1359
|
+
"http://example.com/foo": [{"@list": [{"@id": "http://foo"}, {"@id": "http://bar"}]}]
|
1360
|
+
}])
|
1361
|
+
},
|
1362
|
+
"explicit list with coerced datatype values": {
|
1363
|
+
input: %({
|
1364
|
+
"@context": {"http://example.com/foo": {"@type": "http://www.w3.org/2001/XMLSchema#date"}},
|
1365
|
+
"http://example.com/foo": {"@list": ["2012-04-12"]}
|
1366
|
+
}),
|
1367
|
+
output: %([{
|
1368
|
+
"http://example.com/foo": [{"@list": [{"@value": "2012-04-12", "@type": "http://www.w3.org/2001/XMLSchema#date"}]}]
|
1369
|
+
}])
|
809
1370
|
},
|
810
|
-
"expand-0004"
|
1371
|
+
"expand-0004": {
|
811
1372
|
input: %({
|
812
1373
|
"@context": {
|
813
1374
|
"mylist1": {"@id": "http://example.com/mylist1", "@container": "@list"},
|
@@ -831,7 +1392,7 @@ describe JSON::LD::API do
|
|
831
1392
|
}
|
832
1393
|
])
|
833
1394
|
},
|
834
|
-
"@list containing @list"
|
1395
|
+
"@list containing @list": {
|
835
1396
|
input: %({
|
836
1397
|
"http://example.com/foo": {"@list": [{"@list": ["baz"]}]}
|
837
1398
|
}),
|
@@ -839,7 +1400,7 @@ describe JSON::LD::API do
|
|
839
1400
|
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
840
1401
|
}])
|
841
1402
|
},
|
842
|
-
"@list containing empty @list"
|
1403
|
+
"@list containing empty @list": {
|
843
1404
|
input: %({
|
844
1405
|
"http://example.com/foo": {"@list": [{"@list": []}]}
|
845
1406
|
}),
|
@@ -847,7 +1408,7 @@ describe JSON::LD::API do
|
|
847
1408
|
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
848
1409
|
}])
|
849
1410
|
},
|
850
|
-
"@list containing @list (with coercion)"
|
1411
|
+
"@list containing @list (with coercion)": {
|
851
1412
|
input: %({
|
852
1413
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
853
1414
|
"foo": [{"@list": ["baz"]}]
|
@@ -856,7 +1417,7 @@ describe JSON::LD::API do
|
|
856
1417
|
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
857
1418
|
}])
|
858
1419
|
},
|
859
|
-
"@list containing empty @list (with coercion)"
|
1420
|
+
"@list containing empty @list (with coercion)": {
|
860
1421
|
input: %({
|
861
1422
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
862
1423
|
"foo": [{"@list": []}]
|
@@ -865,7 +1426,7 @@ describe JSON::LD::API do
|
|
865
1426
|
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
866
1427
|
}])
|
867
1428
|
},
|
868
|
-
"coerced @list containing an array"
|
1429
|
+
"coerced @list containing an array": {
|
869
1430
|
input: %({
|
870
1431
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
871
1432
|
"foo": [["baz"]]
|
@@ -874,7 +1435,7 @@ describe JSON::LD::API do
|
|
874
1435
|
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
875
1436
|
}])
|
876
1437
|
},
|
877
|
-
"coerced @list containing an empty array"
|
1438
|
+
"coerced @list containing an empty array": {
|
878
1439
|
input: %({
|
879
1440
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
880
1441
|
"foo": [[]]
|
@@ -883,7 +1444,7 @@ describe JSON::LD::API do
|
|
883
1444
|
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
884
1445
|
}])
|
885
1446
|
},
|
886
|
-
"coerced @list containing deep arrays"
|
1447
|
+
"coerced @list containing deep arrays": {
|
887
1448
|
input: %({
|
888
1449
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
889
1450
|
"foo": [[["baz"]]]
|
@@ -892,7 +1453,7 @@ describe JSON::LD::API do
|
|
892
1453
|
"http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
|
893
1454
|
}])
|
894
1455
|
},
|
895
|
-
"coerced @list containing deep empty arrays"
|
1456
|
+
"coerced @list containing deep empty arrays": {
|
896
1457
|
input: %({
|
897
1458
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
898
1459
|
"foo": [[[]]]
|
@@ -901,7 +1462,7 @@ describe JSON::LD::API do
|
|
901
1462
|
"http://example.com/foo": [{"@list": [{"@list": [{"@list": []}]}]}]
|
902
1463
|
}]),
|
903
1464
|
},
|
904
|
-
"coerced @list containing multiple lists"
|
1465
|
+
"coerced @list containing multiple lists": {
|
905
1466
|
input: %({
|
906
1467
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
907
1468
|
"foo": [["a"], ["b"]]
|
@@ -913,7 +1474,7 @@ describe JSON::LD::API do
|
|
913
1474
|
]}]
|
914
1475
|
}])
|
915
1476
|
},
|
916
|
-
"coerced @list containing mixed list values"
|
1477
|
+
"coerced @list containing mixed list values": {
|
917
1478
|
input: %({
|
918
1479
|
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
919
1480
|
"foo": [["a"], "b"]
|
@@ -932,50 +1493,46 @@ describe JSON::LD::API do
|
|
932
1493
|
|
933
1494
|
context "@container: @set" do
|
934
1495
|
{
|
935
|
-
"empty"
|
936
|
-
input: {
|
937
|
-
|
938
|
-
},
|
939
|
-
output: [{
|
940
|
-
"http://example.com/foo" => []
|
941
|
-
}]
|
1496
|
+
"empty": {
|
1497
|
+
input: %({"http://example.com/foo": {"@set": []}}),
|
1498
|
+
output: %([{"http://example.com/foo": []}])
|
942
1499
|
},
|
943
|
-
"coerced empty"
|
944
|
-
input: {
|
945
|
-
"@context"
|
946
|
-
"http://example.com/foo"
|
947
|
-
},
|
948
|
-
output: [{
|
949
|
-
"http://example.com/foo"
|
950
|
-
}]
|
1500
|
+
"coerced empty": {
|
1501
|
+
input: %({
|
1502
|
+
"@context": {"http://example.com/foo": {"@container": "@set"}},
|
1503
|
+
"http://example.com/foo": []
|
1504
|
+
}),
|
1505
|
+
output: %([{
|
1506
|
+
"http://example.com/foo": []
|
1507
|
+
}])
|
951
1508
|
},
|
952
|
-
"coerced single element"
|
953
|
-
input: {
|
954
|
-
"@context"
|
955
|
-
"http://example.com/foo"
|
956
|
-
},
|
957
|
-
output: [{
|
958
|
-
"http://example.com/foo"
|
959
|
-
}]
|
1509
|
+
"coerced single element": {
|
1510
|
+
input: %({
|
1511
|
+
"@context": {"http://example.com/foo": {"@container": "@set"}},
|
1512
|
+
"http://example.com/foo": [ "foo" ]
|
1513
|
+
}),
|
1514
|
+
output: %([{
|
1515
|
+
"http://example.com/foo": [ {"@value": "foo"} ]
|
1516
|
+
}])
|
960
1517
|
},
|
961
|
-
"coerced multiple elements"
|
962
|
-
input: {
|
963
|
-
"@context"
|
964
|
-
"http://example.com/foo"
|
965
|
-
},
|
966
|
-
output: [{
|
967
|
-
"http://example.com/foo"
|
968
|
-
}]
|
1518
|
+
"coerced multiple elements": {
|
1519
|
+
input: %({
|
1520
|
+
"@context": {"http://example.com/foo": {"@container": "@set"}},
|
1521
|
+
"http://example.com/foo": [ "foo", "bar" ]
|
1522
|
+
}),
|
1523
|
+
output: %([{
|
1524
|
+
"http://example.com/foo": [ {"@value": "foo"}, {"@value": "bar"} ]
|
1525
|
+
}])
|
969
1526
|
},
|
970
|
-
"array containing set"
|
971
|
-
input: {
|
972
|
-
"http://example.com/foo"
|
973
|
-
},
|
974
|
-
output: [{
|
975
|
-
"http://example.com/foo"
|
976
|
-
}]
|
1527
|
+
"array containing set": {
|
1528
|
+
input: %({
|
1529
|
+
"http://example.com/foo": [{"@set": []}]
|
1530
|
+
}),
|
1531
|
+
output: %([{
|
1532
|
+
"http://example.com/foo": []
|
1533
|
+
}])
|
977
1534
|
},
|
978
|
-
"Free-floating values in sets"
|
1535
|
+
"Free-floating values in sets": {
|
979
1536
|
input: %({
|
980
1537
|
"@context": {"property": "http://example.com/property"},
|
981
1538
|
"@graph": [{
|
@@ -1005,120 +1562,230 @@ describe JSON::LD::API do
|
|
1005
1562
|
|
1006
1563
|
context "@container: @language" do
|
1007
1564
|
{
|
1008
|
-
"simple map"
|
1009
|
-
input: {
|
1010
|
-
"@context"
|
1011
|
-
"vocab"
|
1012
|
-
"label"
|
1013
|
-
"@id"
|
1014
|
-
"@container"
|
1565
|
+
"simple map": {
|
1566
|
+
input: %({
|
1567
|
+
"@context": {
|
1568
|
+
"vocab": "http://example.com/vocab/",
|
1569
|
+
"label": {
|
1570
|
+
"@id": "vocab:label",
|
1571
|
+
"@container": "@language"
|
1015
1572
|
}
|
1016
1573
|
},
|
1017
|
-
"@id"
|
1018
|
-
"label"
|
1019
|
-
"en"
|
1020
|
-
"de"
|
1574
|
+
"@id": "http://example.com/queen",
|
1575
|
+
"label": {
|
1576
|
+
"en": "The Queen",
|
1577
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1021
1578
|
}
|
1022
|
-
},
|
1023
|
-
output: [
|
1579
|
+
}),
|
1580
|
+
output: %([
|
1024
1581
|
{
|
1025
|
-
"@id"
|
1026
|
-
"http://example.com/vocab/label"
|
1027
|
-
{"@value"
|
1028
|
-
{"@value"
|
1029
|
-
{"@value"
|
1582
|
+
"@id": "http://example.com/queen",
|
1583
|
+
"http://example.com/vocab/label": [
|
1584
|
+
{"@value": "Die Königin", "@language": "de"},
|
1585
|
+
{"@value": "Ihre Majestät", "@language": "de"},
|
1586
|
+
{"@value": "The Queen", "@language": "en"}
|
1030
1587
|
]
|
1031
1588
|
}
|
1032
|
-
]
|
1589
|
+
])
|
1033
1590
|
},
|
1034
|
-
"simple map with @none"
|
1035
|
-
input: {
|
1036
|
-
"@context"
|
1037
|
-
"vocab"
|
1038
|
-
"label"
|
1039
|
-
"@id"
|
1040
|
-
"@container"
|
1591
|
+
"simple map with @none": {
|
1592
|
+
input: %({
|
1593
|
+
"@context": {
|
1594
|
+
"vocab": "http://example.com/vocab/",
|
1595
|
+
"label": {
|
1596
|
+
"@id": "vocab:label",
|
1597
|
+
"@container": "@language"
|
1041
1598
|
}
|
1042
1599
|
},
|
1043
|
-
"@id"
|
1044
|
-
"label"
|
1045
|
-
"en"
|
1046
|
-
"de"
|
1047
|
-
"@none"
|
1600
|
+
"@id": "http://example.com/queen",
|
1601
|
+
"label": {
|
1602
|
+
"en": "The Queen",
|
1603
|
+
"de": [ "Die Königin", "Ihre Majestät" ],
|
1604
|
+
"@none": "The Queen"
|
1048
1605
|
}
|
1049
|
-
},
|
1050
|
-
output: [
|
1606
|
+
}),
|
1607
|
+
output: %([
|
1051
1608
|
{
|
1052
|
-
"@id"
|
1053
|
-
"http://example.com/vocab/label"
|
1054
|
-
{"@value"
|
1055
|
-
{"@value"
|
1056
|
-
{"@value"
|
1057
|
-
{"@value"
|
1609
|
+
"@id": "http://example.com/queen",
|
1610
|
+
"http://example.com/vocab/label": [
|
1611
|
+
{"@value": "The Queen"},
|
1612
|
+
{"@value": "Die Königin", "@language": "de"},
|
1613
|
+
{"@value": "Ihre Majestät", "@language": "de"},
|
1614
|
+
{"@value": "The Queen", "@language": "en"}
|
1058
1615
|
]
|
1059
1616
|
}
|
1060
|
-
]
|
1617
|
+
])
|
1061
1618
|
},
|
1062
|
-
"simple map with alias of @none"
|
1063
|
-
input: {
|
1064
|
-
"@context"
|
1065
|
-
"vocab"
|
1066
|
-
"label"
|
1067
|
-
"@id"
|
1068
|
-
"@container"
|
1619
|
+
"simple map with alias of @none": {
|
1620
|
+
input: %({
|
1621
|
+
"@context": {
|
1622
|
+
"vocab": "http://example.com/vocab/",
|
1623
|
+
"label": {
|
1624
|
+
"@id": "vocab:label",
|
1625
|
+
"@container": "@language"
|
1069
1626
|
},
|
1070
|
-
"none"
|
1627
|
+
"none": "@none"
|
1628
|
+
},
|
1629
|
+
"@id": "http://example.com/queen",
|
1630
|
+
"label": {
|
1631
|
+
"en": "The Queen",
|
1632
|
+
"de": [ "Die Königin", "Ihre Majestät" ],
|
1633
|
+
"none": "The Queen"
|
1634
|
+
}
|
1635
|
+
}),
|
1636
|
+
output: %([
|
1637
|
+
{
|
1638
|
+
"@id": "http://example.com/queen",
|
1639
|
+
"http://example.com/vocab/label": [
|
1640
|
+
{"@value": "Die Königin", "@language": "de"},
|
1641
|
+
{"@value": "Ihre Majestät", "@language": "de"},
|
1642
|
+
{"@value": "The Queen", "@language": "en"},
|
1643
|
+
{"@value": "The Queen"}
|
1644
|
+
]
|
1645
|
+
}
|
1646
|
+
])
|
1647
|
+
},
|
1648
|
+
"simple map with default direction": {
|
1649
|
+
input: %({
|
1650
|
+
"@context": {
|
1651
|
+
"@direction": "ltr",
|
1652
|
+
"vocab": "http://example.com/vocab/",
|
1653
|
+
"label": {
|
1654
|
+
"@id": "vocab:label",
|
1655
|
+
"@container": "@language"
|
1656
|
+
}
|
1657
|
+
},
|
1658
|
+
"@id": "http://example.com/queen",
|
1659
|
+
"label": {
|
1660
|
+
"en": "The Queen",
|
1661
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1662
|
+
}
|
1663
|
+
}),
|
1664
|
+
output: %([
|
1665
|
+
{
|
1666
|
+
"@id": "http://example.com/queen",
|
1667
|
+
"http://example.com/vocab/label": [
|
1668
|
+
{"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
|
1669
|
+
{"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
|
1670
|
+
{"@value": "The Queen", "@language": "en", "@direction": "ltr"}
|
1671
|
+
]
|
1672
|
+
}
|
1673
|
+
])
|
1674
|
+
},
|
1675
|
+
"simple map with term direction": {
|
1676
|
+
input: %({
|
1677
|
+
"@context": {
|
1678
|
+
"vocab": "http://example.com/vocab/",
|
1679
|
+
"label": {
|
1680
|
+
"@id": "vocab:label",
|
1681
|
+
"@direction": "ltr",
|
1682
|
+
"@container": "@language"
|
1683
|
+
}
|
1684
|
+
},
|
1685
|
+
"@id": "http://example.com/queen",
|
1686
|
+
"label": {
|
1687
|
+
"en": "The Queen",
|
1688
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1689
|
+
}
|
1690
|
+
}),
|
1691
|
+
output: %([
|
1692
|
+
{
|
1693
|
+
"@id": "http://example.com/queen",
|
1694
|
+
"http://example.com/vocab/label": [
|
1695
|
+
{"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
|
1696
|
+
{"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
|
1697
|
+
{"@value": "The Queen", "@language": "en", "@direction": "ltr"}
|
1698
|
+
]
|
1699
|
+
}
|
1700
|
+
])
|
1701
|
+
},
|
1702
|
+
"simple map with overriding term direction": {
|
1703
|
+
input: %({
|
1704
|
+
"@context": {
|
1705
|
+
"vocab": "http://example.com/vocab/",
|
1706
|
+
"@direction": "rtl",
|
1707
|
+
"label": {
|
1708
|
+
"@id": "vocab:label",
|
1709
|
+
"@direction": "ltr",
|
1710
|
+
"@container": "@language"
|
1711
|
+
}
|
1712
|
+
},
|
1713
|
+
"@id": "http://example.com/queen",
|
1714
|
+
"label": {
|
1715
|
+
"en": "The Queen",
|
1716
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1717
|
+
}
|
1718
|
+
}),
|
1719
|
+
output: %([
|
1720
|
+
{
|
1721
|
+
"@id": "http://example.com/queen",
|
1722
|
+
"http://example.com/vocab/label": [
|
1723
|
+
{"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
|
1724
|
+
{"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
|
1725
|
+
{"@value": "The Queen", "@language": "en", "@direction": "ltr"}
|
1726
|
+
]
|
1727
|
+
}
|
1728
|
+
])
|
1729
|
+
},
|
1730
|
+
"simple map with overriding null direction": {
|
1731
|
+
input: %({
|
1732
|
+
"@context": {
|
1733
|
+
"vocab": "http://example.com/vocab/",
|
1734
|
+
"@direction": "rtl",
|
1735
|
+
"label": {
|
1736
|
+
"@id": "vocab:label",
|
1737
|
+
"@direction": null,
|
1738
|
+
"@container": "@language"
|
1739
|
+
}
|
1071
1740
|
},
|
1072
|
-
"@id"
|
1073
|
-
"label"
|
1074
|
-
"en"
|
1075
|
-
"de"
|
1076
|
-
"none" => "The Queen"
|
1741
|
+
"@id": "http://example.com/queen",
|
1742
|
+
"label": {
|
1743
|
+
"en": "The Queen",
|
1744
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1077
1745
|
}
|
1078
|
-
},
|
1079
|
-
output: [
|
1746
|
+
}),
|
1747
|
+
output: %([
|
1080
1748
|
{
|
1081
|
-
"@id"
|
1082
|
-
"http://example.com/vocab/label"
|
1083
|
-
{"@value"
|
1084
|
-
{"@value"
|
1085
|
-
{"@value"
|
1086
|
-
{"@value" => "The Queen"},
|
1749
|
+
"@id": "http://example.com/queen",
|
1750
|
+
"http://example.com/vocab/label": [
|
1751
|
+
{"@value": "Die Königin", "@language": "de"},
|
1752
|
+
{"@value": "Ihre Majestät", "@language": "de"},
|
1753
|
+
{"@value": "The Queen", "@language": "en"}
|
1087
1754
|
]
|
1088
1755
|
}
|
1089
|
-
]
|
1756
|
+
])
|
1090
1757
|
},
|
1091
|
-
"expand-0035"
|
1092
|
-
input: {
|
1093
|
-
"@context"
|
1094
|
-
"@vocab"
|
1095
|
-
"@language"
|
1096
|
-
"label"
|
1097
|
-
"@container"
|
1758
|
+
"expand-0035": {
|
1759
|
+
input: %({
|
1760
|
+
"@context": {
|
1761
|
+
"@vocab": "http://example.com/vocab/",
|
1762
|
+
"@language": "it",
|
1763
|
+
"label": {
|
1764
|
+
"@container": "@language"
|
1098
1765
|
}
|
1099
1766
|
},
|
1100
|
-
"@id"
|
1101
|
-
"label"
|
1102
|
-
"en"
|
1103
|
-
"de"
|
1767
|
+
"@id": "http://example.com/queen",
|
1768
|
+
"label": {
|
1769
|
+
"en": "The Queen",
|
1770
|
+
"de": [ "Die Königin", "Ihre Majestät" ]
|
1104
1771
|
},
|
1105
|
-
"http://example.com/vocab/label"
|
1772
|
+
"http://example.com/vocab/label": [
|
1106
1773
|
"Il re",
|
1107
|
-
{ "@value"
|
1774
|
+
{ "@value": "The king", "@language": "en" }
|
1108
1775
|
]
|
1109
|
-
},
|
1110
|
-
output: [
|
1776
|
+
}),
|
1777
|
+
output: %([
|
1111
1778
|
{
|
1112
|
-
"@id"
|
1113
|
-
"http://example.com/vocab/label"
|
1114
|
-
{"@value"
|
1115
|
-
{"@value"
|
1116
|
-
{"@value"
|
1117
|
-
{"@value"
|
1118
|
-
{"@value"
|
1779
|
+
"@id": "http://example.com/queen",
|
1780
|
+
"http://example.com/vocab/label": [
|
1781
|
+
{"@value": "Il re", "@language": "it"},
|
1782
|
+
{"@value": "The king", "@language": "en"},
|
1783
|
+
{"@value": "Die Königin", "@language": "de"},
|
1784
|
+
{"@value": "Ihre Majestät", "@language": "de"},
|
1785
|
+
{"@value": "The Queen", "@language": "en"}
|
1119
1786
|
]
|
1120
1787
|
}
|
1121
|
-
]
|
1788
|
+
])
|
1122
1789
|
}
|
1123
1790
|
}.each do |title, params|
|
1124
1791
|
it(title) {run_expand params}
|
@@ -1127,7 +1794,7 @@ describe JSON::LD::API do
|
|
1127
1794
|
|
1128
1795
|
context "@container: @id" do
|
1129
1796
|
{
|
1130
|
-
"Adds @id to object not having an @id"
|
1797
|
+
"Adds @id to object not having an @id": {
|
1131
1798
|
input: %({
|
1132
1799
|
"@context": {
|
1133
1800
|
"@vocab": "http://example/",
|
@@ -1145,7 +1812,7 @@ describe JSON::LD::API do
|
|
1145
1812
|
]
|
1146
1813
|
}])
|
1147
1814
|
},
|
1148
|
-
"Retains @id in object already having an @id"
|
1815
|
+
"Retains @id in object already having an @id": {
|
1149
1816
|
input: %({
|
1150
1817
|
"@context": {
|
1151
1818
|
"@vocab": "http://example/",
|
@@ -1163,7 +1830,7 @@ describe JSON::LD::API do
|
|
1163
1830
|
]
|
1164
1831
|
}])
|
1165
1832
|
},
|
1166
|
-
"Adds expanded @id to object"
|
1833
|
+
"Adds expanded @id to object": {
|
1167
1834
|
input: %({
|
1168
1835
|
"@context": {
|
1169
1836
|
"@vocab": "http://example/",
|
@@ -1180,7 +1847,7 @@ describe JSON::LD::API do
|
|
1180
1847
|
}]),
|
1181
1848
|
base: "http://example.org/"
|
1182
1849
|
},
|
1183
|
-
"Raises InvalidContainerMapping if processingMode is
|
1850
|
+
"Raises InvalidContainerMapping if processingMode is 1.0": {
|
1184
1851
|
input: %({
|
1185
1852
|
"@context": {
|
1186
1853
|
"@vocab": "http://example/",
|
@@ -1191,7 +1858,7 @@ describe JSON::LD::API do
|
|
1191
1858
|
"_:bar": {"label": "Object with @id _:bar"}
|
1192
1859
|
}
|
1193
1860
|
}),
|
1194
|
-
processingMode:
|
1861
|
+
processingMode: 'json-ld-1.0',
|
1195
1862
|
exception: JSON::LD::JsonLdError::InvalidContainerMapping
|
1196
1863
|
},
|
1197
1864
|
"Does not add @id if it is @none, or expands to @none": {
|
@@ -1220,7 +1887,7 @@ describe JSON::LD::API do
|
|
1220
1887
|
|
1221
1888
|
context "@container: @type" do
|
1222
1889
|
{
|
1223
|
-
"Adds @type to object not having an @type"
|
1890
|
+
"Adds @type to object not having an @type": {
|
1224
1891
|
input: %({
|
1225
1892
|
"@context": {
|
1226
1893
|
"@vocab": "http://example/",
|
@@ -1238,7 +1905,7 @@ describe JSON::LD::API do
|
|
1238
1905
|
]
|
1239
1906
|
}])
|
1240
1907
|
},
|
1241
|
-
"Prepends @type in object already having an @type"
|
1908
|
+
"Prepends @type in object already having an @type": {
|
1242
1909
|
input: %({
|
1243
1910
|
"@context": {
|
1244
1911
|
"@vocab": "http://example/",
|
@@ -1262,7 +1929,7 @@ describe JSON::LD::API do
|
|
1262
1929
|
]
|
1263
1930
|
}])
|
1264
1931
|
},
|
1265
|
-
"Adds vocabulary expanded @type to object"
|
1932
|
+
"Adds vocabulary expanded @type to object": {
|
1266
1933
|
input: %({
|
1267
1934
|
"@context": {
|
1268
1935
|
"@vocab": "http://example/",
|
@@ -1278,7 +1945,7 @@ describe JSON::LD::API do
|
|
1278
1945
|
]
|
1279
1946
|
}])
|
1280
1947
|
},
|
1281
|
-
"Adds document expanded @type to object"
|
1948
|
+
"Adds document expanded @type to object": {
|
1282
1949
|
input: %({
|
1283
1950
|
"@context": {
|
1284
1951
|
"@vocab": "http://example/",
|
@@ -1314,7 +1981,7 @@ describe JSON::LD::API do
|
|
1314
1981
|
]
|
1315
1982
|
}])
|
1316
1983
|
},
|
1317
|
-
"Raises InvalidContainerMapping if processingMode is
|
1984
|
+
"Raises InvalidContainerMapping if processingMode is 1.0": {
|
1318
1985
|
input: %({
|
1319
1986
|
"@context": {
|
1320
1987
|
"@vocab": "http://example/",
|
@@ -1325,7 +1992,7 @@ describe JSON::LD::API do
|
|
1325
1992
|
"_:bar": {"label": "Object with @type _:bar"}
|
1326
1993
|
}
|
1327
1994
|
}),
|
1328
|
-
processingMode:
|
1995
|
+
processingMode: 'json-ld-1.0',
|
1329
1996
|
exception: JSON::LD::JsonLdError::InvalidContainerMapping
|
1330
1997
|
},
|
1331
1998
|
}.each do |title, params|
|
@@ -1335,7 +2002,7 @@ describe JSON::LD::API do
|
|
1335
2002
|
|
1336
2003
|
context "@container: @graph" do
|
1337
2004
|
{
|
1338
|
-
"Creates a graph object given a value"
|
2005
|
+
"Creates a graph object given a value": {
|
1339
2006
|
input: %({
|
1340
2007
|
"@context": {
|
1341
2008
|
"@vocab": "http://example.org/",
|
@@ -1353,7 +2020,7 @@ describe JSON::LD::API do
|
|
1353
2020
|
}]
|
1354
2021
|
}])
|
1355
2022
|
},
|
1356
|
-
"Creates a graph object within an array given a value"
|
2023
|
+
"Creates a graph object within an array given a value": {
|
1357
2024
|
input: %({
|
1358
2025
|
"@context": {
|
1359
2026
|
"@vocab": "http://example.org/",
|
@@ -1371,7 +2038,7 @@ describe JSON::LD::API do
|
|
1371
2038
|
}]
|
1372
2039
|
}])
|
1373
2040
|
},
|
1374
|
-
"
|
2041
|
+
"Creates an graph object if value is a graph": {
|
1375
2042
|
input: %({
|
1376
2043
|
"@context": {
|
1377
2044
|
"@vocab": "http://example.org/",
|
@@ -1386,7 +2053,9 @@ describe JSON::LD::API do
|
|
1386
2053
|
output: %([{
|
1387
2054
|
"http://example.org/input": [{
|
1388
2055
|
"@graph": [{
|
1389
|
-
"
|
2056
|
+
"@graph": [{
|
2057
|
+
"http://example.org/value": [{"@value": "x"}]
|
2058
|
+
}]
|
1390
2059
|
}]
|
1391
2060
|
}]
|
1392
2061
|
}])
|
@@ -1397,7 +2066,7 @@ describe JSON::LD::API do
|
|
1397
2066
|
|
1398
2067
|
context "+ @index" do
|
1399
2068
|
{
|
1400
|
-
"Creates a graph object given an indexed value"
|
2069
|
+
"Creates a graph object given an indexed value": {
|
1401
2070
|
input: %({
|
1402
2071
|
"@context": {
|
1403
2072
|
"@vocab": "http://example.org/",
|
@@ -1416,7 +2085,7 @@ describe JSON::LD::API do
|
|
1416
2085
|
}]
|
1417
2086
|
}])
|
1418
2087
|
},
|
1419
|
-
"Creates a graph object given an indexed value with index @none"
|
2088
|
+
"Creates a graph object given an indexed value with index @none": {
|
1420
2089
|
input: %({
|
1421
2090
|
"@context": {
|
1422
2091
|
"@vocab": "http://example.org/",
|
@@ -1434,7 +2103,7 @@ describe JSON::LD::API do
|
|
1434
2103
|
}]
|
1435
2104
|
}])
|
1436
2105
|
},
|
1437
|
-
"Creates a graph object given an indexed value with index alias of @none"
|
2106
|
+
"Creates a graph object given an indexed value with index alias of @none": {
|
1438
2107
|
input: %({
|
1439
2108
|
"@context": {
|
1440
2109
|
"@vocab": "http://example.org/",
|
@@ -1453,7 +2122,7 @@ describe JSON::LD::API do
|
|
1453
2122
|
}]
|
1454
2123
|
}])
|
1455
2124
|
},
|
1456
|
-
"Creates a graph object given an indexed value with @set"
|
2125
|
+
"Creates a graph object given an indexed value with @set": {
|
1457
2126
|
input: %({
|
1458
2127
|
"@context": {
|
1459
2128
|
"@vocab": "http://example.org/",
|
@@ -1472,7 +2141,7 @@ describe JSON::LD::API do
|
|
1472
2141
|
}]
|
1473
2142
|
}])
|
1474
2143
|
},
|
1475
|
-
"Does not create a new graph object if indexed value is already a graph object"
|
2144
|
+
"Does not create a new graph object if indexed value is already a graph object": {
|
1476
2145
|
input: %({
|
1477
2146
|
"@context": {
|
1478
2147
|
"@vocab": "http://example.org/",
|
@@ -1498,11 +2167,38 @@ describe JSON::LD::API do
|
|
1498
2167
|
}.each do |title, params|
|
1499
2168
|
it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
|
1500
2169
|
end
|
2170
|
+
|
2171
|
+
context "@index: property" do
|
2172
|
+
{
|
2173
|
+
"it expands to property value, instead of @index": {
|
2174
|
+
input: %({
|
2175
|
+
"@context": {
|
2176
|
+
"@version": 1.1,
|
2177
|
+
"@vocab": "http://example.org/",
|
2178
|
+
"input": {"@container": ["@graph", "@index"], "@index": "prop"}
|
2179
|
+
},
|
2180
|
+
"input": {
|
2181
|
+
"g1": {"value": "x"}
|
2182
|
+
}
|
2183
|
+
}),
|
2184
|
+
output: %([{
|
2185
|
+
"http://example.org/input": [{
|
2186
|
+
"http://example.org/prop": [{"@value": "g1"}],
|
2187
|
+
"@graph": [{
|
2188
|
+
"http://example.org/value": [{"@value": "x"}]
|
2189
|
+
}]
|
2190
|
+
}]
|
2191
|
+
}])
|
2192
|
+
},
|
2193
|
+
}.each do |title, params|
|
2194
|
+
it(title) {run_expand(validate: true, **params)}
|
2195
|
+
end
|
2196
|
+
end
|
1501
2197
|
end
|
1502
2198
|
|
1503
2199
|
context "+ @id" do
|
1504
2200
|
{
|
1505
|
-
"Creates a graph object given an indexed value"
|
2201
|
+
"Creates a graph object given an indexed value": {
|
1506
2202
|
input: %({
|
1507
2203
|
"@context": {
|
1508
2204
|
"@vocab": "http://example.org/",
|
@@ -1521,7 +2217,7 @@ describe JSON::LD::API do
|
|
1521
2217
|
}]
|
1522
2218
|
}])
|
1523
2219
|
},
|
1524
|
-
"Creates a graph object given an indexed value of @none"
|
2220
|
+
"Creates a graph object given an indexed value of @none": {
|
1525
2221
|
input: %({
|
1526
2222
|
"@context": {
|
1527
2223
|
"@vocab": "http://example.org/",
|
@@ -1539,7 +2235,7 @@ describe JSON::LD::API do
|
|
1539
2235
|
}]
|
1540
2236
|
}])
|
1541
2237
|
},
|
1542
|
-
"Creates a graph object given an indexed value of alias of @none"
|
2238
|
+
"Creates a graph object given an indexed value of alias of @none": {
|
1543
2239
|
input: %({
|
1544
2240
|
"@context": {
|
1545
2241
|
"@vocab": "http://example.org/",
|
@@ -1558,7 +2254,7 @@ describe JSON::LD::API do
|
|
1558
2254
|
}]
|
1559
2255
|
}])
|
1560
2256
|
},
|
1561
|
-
"Creates a graph object given an indexed value with @set"
|
2257
|
+
"Creates a graph object given an indexed value with @set": {
|
1562
2258
|
input: %({
|
1563
2259
|
"@context": {
|
1564
2260
|
"@vocab": "http://example.org/",
|
@@ -1577,7 +2273,7 @@ describe JSON::LD::API do
|
|
1577
2273
|
}]
|
1578
2274
|
}])
|
1579
2275
|
},
|
1580
|
-
"Does not create a new graph object if indexed value is already a graph object"
|
2276
|
+
"Does not create a new graph object if indexed value is already a graph object": {
|
1581
2277
|
input: %({
|
1582
2278
|
"@context": {
|
1583
2279
|
"@vocab": "http://example.org/",
|
@@ -1606,9 +2302,280 @@ describe JSON::LD::API do
|
|
1606
2302
|
end
|
1607
2303
|
end
|
1608
2304
|
|
2305
|
+
context "@included" do
|
2306
|
+
{
|
2307
|
+
"Basic Included array": {
|
2308
|
+
input: %({
|
2309
|
+
"@context": {
|
2310
|
+
"@version": 1.1,
|
2311
|
+
"@vocab": "http://example.org/"
|
2312
|
+
},
|
2313
|
+
"prop": "value",
|
2314
|
+
"@included": [{
|
2315
|
+
"prop": "value2"
|
2316
|
+
}]
|
2317
|
+
}),
|
2318
|
+
output: %([{
|
2319
|
+
"http://example.org/prop": [{"@value": "value"}],
|
2320
|
+
"@included": [{
|
2321
|
+
"http://example.org/prop": [{"@value": "value2"}]
|
2322
|
+
}]
|
2323
|
+
}])
|
2324
|
+
},
|
2325
|
+
"Basic Included object": {
|
2326
|
+
input: %({
|
2327
|
+
"@context": {
|
2328
|
+
"@version": 1.1,
|
2329
|
+
"@vocab": "http://example.org/"
|
2330
|
+
},
|
2331
|
+
"prop": "value",
|
2332
|
+
"@included": {
|
2333
|
+
"prop": "value2"
|
2334
|
+
}
|
2335
|
+
}),
|
2336
|
+
output: %([{
|
2337
|
+
"http://example.org/prop": [{"@value": "value"}],
|
2338
|
+
"@included": [{
|
2339
|
+
"http://example.org/prop": [{"@value": "value2"}]
|
2340
|
+
}]
|
2341
|
+
}])
|
2342
|
+
},
|
2343
|
+
"Multiple properties mapping to @included are folded together": {
|
2344
|
+
input: %({
|
2345
|
+
"@context": {
|
2346
|
+
"@version": 1.1,
|
2347
|
+
"@vocab": "http://example.org/",
|
2348
|
+
"included1": "@included",
|
2349
|
+
"included2": "@included"
|
2350
|
+
},
|
2351
|
+
"included1": {"prop": "value1"},
|
2352
|
+
"included2": {"prop": "value2"}
|
2353
|
+
}),
|
2354
|
+
output: %([{
|
2355
|
+
"@included": [
|
2356
|
+
{"http://example.org/prop": [{"@value": "value1"}]},
|
2357
|
+
{"http://example.org/prop": [{"@value": "value2"}]}
|
2358
|
+
]
|
2359
|
+
}])
|
2360
|
+
},
|
2361
|
+
"Included containing @included": {
|
2362
|
+
input: %({
|
2363
|
+
"@context": {
|
2364
|
+
"@version": 1.1,
|
2365
|
+
"@vocab": "http://example.org/"
|
2366
|
+
},
|
2367
|
+
"prop": "value",
|
2368
|
+
"@included": {
|
2369
|
+
"prop": "value2",
|
2370
|
+
"@included": {
|
2371
|
+
"prop": "value3"
|
2372
|
+
}
|
2373
|
+
}
|
2374
|
+
}),
|
2375
|
+
output: %([{
|
2376
|
+
"http://example.org/prop": [{"@value": "value"}],
|
2377
|
+
"@included": [{
|
2378
|
+
"http://example.org/prop": [{"@value": "value2"}],
|
2379
|
+
"@included": [{
|
2380
|
+
"http://example.org/prop": [{"@value": "value3"}]
|
2381
|
+
}]
|
2382
|
+
}]
|
2383
|
+
}])
|
2384
|
+
},
|
2385
|
+
"Property value with @included": {
|
2386
|
+
input: %({
|
2387
|
+
"@context": {
|
2388
|
+
"@version": 1.1,
|
2389
|
+
"@vocab": "http://example.org/"
|
2390
|
+
},
|
2391
|
+
"prop": {
|
2392
|
+
"@type": "Foo",
|
2393
|
+
"@included": {
|
2394
|
+
"@type": "Bar"
|
2395
|
+
}
|
2396
|
+
}
|
2397
|
+
}),
|
2398
|
+
output: %([{
|
2399
|
+
"http://example.org/prop": [{
|
2400
|
+
"@type": ["http://example.org/Foo"],
|
2401
|
+
"@included": [{
|
2402
|
+
"@type": ["http://example.org/Bar"]
|
2403
|
+
}]
|
2404
|
+
}]
|
2405
|
+
}])
|
2406
|
+
},
|
2407
|
+
"json.api example": {
|
2408
|
+
input: %({
|
2409
|
+
"@context": {
|
2410
|
+
"@version": 1.1,
|
2411
|
+
"@vocab": "http://example.org/vocab#",
|
2412
|
+
"@base": "http://example.org/base/",
|
2413
|
+
"id": "@id",
|
2414
|
+
"type": "@type",
|
2415
|
+
"data": "@nest",
|
2416
|
+
"attributes": "@nest",
|
2417
|
+
"links": "@nest",
|
2418
|
+
"relationships": "@nest",
|
2419
|
+
"included": "@included",
|
2420
|
+
"self": {"@type": "@id"},
|
2421
|
+
"related": {"@type": "@id"},
|
2422
|
+
"comments": {
|
2423
|
+
"@context": {
|
2424
|
+
"data": null
|
2425
|
+
}
|
2426
|
+
}
|
2427
|
+
},
|
2428
|
+
"data": [{
|
2429
|
+
"type": "articles",
|
2430
|
+
"id": "1",
|
2431
|
+
"attributes": {
|
2432
|
+
"title": "JSON:API paints my bikeshed!"
|
2433
|
+
},
|
2434
|
+
"links": {
|
2435
|
+
"self": "http://example.com/articles/1"
|
2436
|
+
},
|
2437
|
+
"relationships": {
|
2438
|
+
"author": {
|
2439
|
+
"links": {
|
2440
|
+
"self": "http://example.com/articles/1/relationships/author",
|
2441
|
+
"related": "http://example.com/articles/1/author"
|
2442
|
+
},
|
2443
|
+
"data": { "type": "people", "id": "9" }
|
2444
|
+
},
|
2445
|
+
"comments": {
|
2446
|
+
"links": {
|
2447
|
+
"self": "http://example.com/articles/1/relationships/comments",
|
2448
|
+
"related": "http://example.com/articles/1/comments"
|
2449
|
+
},
|
2450
|
+
"data": [
|
2451
|
+
{ "type": "comments", "id": "5" },
|
2452
|
+
{ "type": "comments", "id": "12" }
|
2453
|
+
]
|
2454
|
+
}
|
2455
|
+
}
|
2456
|
+
}],
|
2457
|
+
"included": [{
|
2458
|
+
"type": "people",
|
2459
|
+
"id": "9",
|
2460
|
+
"attributes": {
|
2461
|
+
"first-name": "Dan",
|
2462
|
+
"last-name": "Gebhardt",
|
2463
|
+
"twitter": "dgeb"
|
2464
|
+
},
|
2465
|
+
"links": {
|
2466
|
+
"self": "http://example.com/people/9"
|
2467
|
+
}
|
2468
|
+
}, {
|
2469
|
+
"type": "comments",
|
2470
|
+
"id": "5",
|
2471
|
+
"attributes": {
|
2472
|
+
"body": "First!"
|
2473
|
+
},
|
2474
|
+
"relationships": {
|
2475
|
+
"author": {
|
2476
|
+
"data": { "type": "people", "id": "2" }
|
2477
|
+
}
|
2478
|
+
},
|
2479
|
+
"links": {
|
2480
|
+
"self": "http://example.com/comments/5"
|
2481
|
+
}
|
2482
|
+
}, {
|
2483
|
+
"type": "comments",
|
2484
|
+
"id": "12",
|
2485
|
+
"attributes": {
|
2486
|
+
"body": "I like XML better"
|
2487
|
+
},
|
2488
|
+
"relationships": {
|
2489
|
+
"author": {
|
2490
|
+
"data": { "type": "people", "id": "9" }
|
2491
|
+
}
|
2492
|
+
},
|
2493
|
+
"links": {
|
2494
|
+
"self": "http://example.com/comments/12"
|
2495
|
+
}
|
2496
|
+
}]
|
2497
|
+
}),
|
2498
|
+
output: %([{
|
2499
|
+
"@id": "http://example.org/base/1",
|
2500
|
+
"@type": ["http://example.org/vocab#articles"],
|
2501
|
+
"http://example.org/vocab#title": [{"@value": "JSON:API paints my bikeshed!"}],
|
2502
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/articles/1"}],
|
2503
|
+
"http://example.org/vocab#author": [{
|
2504
|
+
"@id": "http://example.org/base/9",
|
2505
|
+
"@type": ["http://example.org/vocab#people"],
|
2506
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/author"}],
|
2507
|
+
"http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/author"}]
|
2508
|
+
}],
|
2509
|
+
"http://example.org/vocab#comments": [{
|
2510
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/comments"}],
|
2511
|
+
"http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/comments"}]
|
2512
|
+
}],
|
2513
|
+
"@included": [{
|
2514
|
+
"@id": "http://example.org/base/9",
|
2515
|
+
"@type": ["http://example.org/vocab#people"],
|
2516
|
+
"http://example.org/vocab#first-name": [{"@value": "Dan"}],
|
2517
|
+
"http://example.org/vocab#last-name": [{"@value": "Gebhardt"}],
|
2518
|
+
"http://example.org/vocab#twitter": [{"@value": "dgeb"}],
|
2519
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/people/9"}]
|
2520
|
+
}, {
|
2521
|
+
"@id": "http://example.org/base/5",
|
2522
|
+
"@type": ["http://example.org/vocab#comments"],
|
2523
|
+
"http://example.org/vocab#body": [{"@value": "First!"}],
|
2524
|
+
"http://example.org/vocab#author": [{
|
2525
|
+
"@id": "http://example.org/base/2",
|
2526
|
+
"@type": ["http://example.org/vocab#people"]
|
2527
|
+
}],
|
2528
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/comments/5"}]
|
2529
|
+
}, {
|
2530
|
+
"@id": "http://example.org/base/12",
|
2531
|
+
"@type": ["http://example.org/vocab#comments"],
|
2532
|
+
"http://example.org/vocab#body": [{"@value": "I like XML better"}],
|
2533
|
+
"http://example.org/vocab#author": [{
|
2534
|
+
"@id": "http://example.org/base/9",
|
2535
|
+
"@type": ["http://example.org/vocab#people"]
|
2536
|
+
}],
|
2537
|
+
"http://example.org/vocab#self": [{"@id": "http://example.com/comments/12"}]
|
2538
|
+
}]
|
2539
|
+
}])
|
2540
|
+
},
|
2541
|
+
"Error if @included value is a string": {
|
2542
|
+
input: %({
|
2543
|
+
"@context": {
|
2544
|
+
"@version": 1.1,
|
2545
|
+
"@vocab": "http://example.org/"
|
2546
|
+
},
|
2547
|
+
"@included": "string"
|
2548
|
+
}),
|
2549
|
+
exception: JSON::LD::JsonLdError::InvalidIncludedValue
|
2550
|
+
},
|
2551
|
+
"Error if @included value is a value object": {
|
2552
|
+
input: %({
|
2553
|
+
"@context": {
|
2554
|
+
"@version": 1.1,
|
2555
|
+
"@vocab": "http://example.org/"
|
2556
|
+
},
|
2557
|
+
"@included": {"@value": "value"}
|
2558
|
+
}),
|
2559
|
+
exception: JSON::LD::JsonLdError::InvalidIncludedValue
|
2560
|
+
},
|
2561
|
+
"Error if @included value is a list object": {
|
2562
|
+
input: %({
|
2563
|
+
"@context": {
|
2564
|
+
"@version": 1.1,
|
2565
|
+
"@vocab": "http://example.org/"
|
2566
|
+
},
|
2567
|
+
"@included": {"@list": ["value"]}
|
2568
|
+
}),
|
2569
|
+
exception: JSON::LD::JsonLdError::InvalidIncludedValue
|
2570
|
+
},
|
2571
|
+
}.each do |title, params|
|
2572
|
+
it(title) {run_expand(params)}
|
2573
|
+
end
|
2574
|
+
end
|
2575
|
+
|
1609
2576
|
context "@nest" do
|
1610
2577
|
{
|
1611
|
-
"Expands input using @nest"
|
2578
|
+
"Expands input using @nest": {
|
1612
2579
|
input: %({
|
1613
2580
|
"@context": {"@vocab": "http://example.org/"},
|
1614
2581
|
"p1": "v1",
|
@@ -1621,7 +2588,7 @@ describe JSON::LD::API do
|
|
1621
2588
|
"http://example.org/p2": [{"@value": "v2"}]
|
1622
2589
|
}])
|
1623
2590
|
},
|
1624
|
-
"Expands input using aliased @nest"
|
2591
|
+
"Expands input using aliased @nest": {
|
1625
2592
|
input: %({
|
1626
2593
|
"@context": {
|
1627
2594
|
"@vocab": "http://example.org/",
|
@@ -1637,7 +2604,7 @@ describe JSON::LD::API do
|
|
1637
2604
|
"http://example.org/p2": [{"@value": "v2"}]
|
1638
2605
|
}])
|
1639
2606
|
},
|
1640
|
-
"Appends nested values when property at base and nested"
|
2607
|
+
"Appends nested values when property at base and nested": {
|
1641
2608
|
input: %({
|
1642
2609
|
"@context": {
|
1643
2610
|
"@vocab": "http://example.org/",
|
@@ -1657,7 +2624,7 @@ describe JSON::LD::API do
|
|
1657
2624
|
]
|
1658
2625
|
}])
|
1659
2626
|
},
|
1660
|
-
"Appends nested values from all @nest aliases in term order"
|
2627
|
+
"Appends nested values from all @nest aliases in term order": {
|
1661
2628
|
input: %({
|
1662
2629
|
"@context": {
|
1663
2630
|
"@vocab": "http://example.org/",
|
@@ -1682,7 +2649,7 @@ describe JSON::LD::API do
|
|
1682
2649
|
]
|
1683
2650
|
}])
|
1684
2651
|
},
|
1685
|
-
"Nested nested containers"
|
2652
|
+
"Nested nested containers": {
|
1686
2653
|
input: %({
|
1687
2654
|
"@context": {
|
1688
2655
|
"@vocab": "http://example.org/"
|
@@ -1705,7 +2672,7 @@ describe JSON::LD::API do
|
|
1705
2672
|
]
|
1706
2673
|
}])
|
1707
2674
|
},
|
1708
|
-
"Arrays of nested values"
|
2675
|
+
"Arrays of nested values": {
|
1709
2676
|
input: %({
|
1710
2677
|
"@context": {
|
1711
2678
|
"@vocab": "http://example.org/",
|
@@ -1727,7 +2694,7 @@ describe JSON::LD::API do
|
|
1727
2694
|
]
|
1728
2695
|
}])
|
1729
2696
|
},
|
1730
|
-
"A nest of arrays"
|
2697
|
+
"A nest of arrays": {
|
1731
2698
|
input: %({
|
1732
2699
|
"@context": {
|
1733
2700
|
"@vocab": "http://example.org/",
|
@@ -1751,35 +2718,35 @@ describe JSON::LD::API do
|
|
1751
2718
|
]
|
1752
2719
|
}])
|
1753
2720
|
},
|
1754
|
-
"@nest MUST NOT have a string value"
|
2721
|
+
"@nest MUST NOT have a string value": {
|
1755
2722
|
input: %({
|
1756
2723
|
"@context": {"@vocab": "http://example.org/"},
|
1757
2724
|
"@nest": "This should generate an error"
|
1758
2725
|
}),
|
1759
2726
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1760
2727
|
},
|
1761
|
-
"@nest MUST NOT have a boolen value"
|
2728
|
+
"@nest MUST NOT have a boolen value": {
|
1762
2729
|
input: %({
|
1763
2730
|
"@context": {"@vocab": "http://example.org/"},
|
1764
2731
|
"@nest": true
|
1765
2732
|
}),
|
1766
2733
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1767
2734
|
},
|
1768
|
-
"@nest MUST NOT have a numeric value"
|
2735
|
+
"@nest MUST NOT have a numeric value": {
|
1769
2736
|
input: %({
|
1770
2737
|
"@context": {"@vocab": "http://example.org/"},
|
1771
2738
|
"@nest": 1
|
1772
2739
|
}),
|
1773
2740
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1774
2741
|
},
|
1775
|
-
"@nest MUST NOT have a value object value"
|
2742
|
+
"@nest MUST NOT have a value object value": {
|
1776
2743
|
input: %({
|
1777
2744
|
"@context": {"@vocab": "http://example.org/"},
|
1778
2745
|
"@nest": {"@value": "This should generate an error"}
|
1779
2746
|
}),
|
1780
2747
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1781
2748
|
},
|
1782
|
-
"@nest in term definition MUST NOT be a non-@nest keyword"
|
2749
|
+
"@nest in term definition MUST NOT be a non-@nest keyword": {
|
1783
2750
|
input: %({
|
1784
2751
|
"@context": {
|
1785
2752
|
"@vocab": "http://example.org/",
|
@@ -1789,7 +2756,7 @@ describe JSON::LD::API do
|
|
1789
2756
|
}),
|
1790
2757
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1791
2758
|
},
|
1792
|
-
"@nest in term definition MUST NOT have a boolen value"
|
2759
|
+
"@nest in term definition MUST NOT have a boolen value": {
|
1793
2760
|
input: %({
|
1794
2761
|
"@context": {
|
1795
2762
|
"@vocab": "http://example.org/",
|
@@ -1799,7 +2766,7 @@ describe JSON::LD::API do
|
|
1799
2766
|
}),
|
1800
2767
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1801
2768
|
},
|
1802
|
-
"@nest in term definition MUST NOT have a numeric value"
|
2769
|
+
"@nest in term definition MUST NOT have a numeric value": {
|
1803
2770
|
input: %({
|
1804
2771
|
"@context": {
|
1805
2772
|
"@vocab": "http://example.org/",
|
@@ -1809,7 +2776,7 @@ describe JSON::LD::API do
|
|
1809
2776
|
}),
|
1810
2777
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1811
2778
|
},
|
1812
|
-
"Nested @container: @list"
|
2779
|
+
"Nested @container: @list": {
|
1813
2780
|
input: %({
|
1814
2781
|
"@context": {
|
1815
2782
|
"@vocab": "http://example.org/",
|
@@ -1827,7 +2794,7 @@ describe JSON::LD::API do
|
|
1827
2794
|
]}]
|
1828
2795
|
}])
|
1829
2796
|
},
|
1830
|
-
"Nested @container: @index"
|
2797
|
+
"Nested @container: @index": {
|
1831
2798
|
input: %({
|
1832
2799
|
"@context": {
|
1833
2800
|
"@vocab": "http://example.org/",
|
@@ -1848,7 +2815,7 @@ describe JSON::LD::API do
|
|
1848
2815
|
]
|
1849
2816
|
}])
|
1850
2817
|
},
|
1851
|
-
"Nested @container: @language"
|
2818
|
+
"Nested @container: @language": {
|
1852
2819
|
input: %({
|
1853
2820
|
"@context": {
|
1854
2821
|
"@vocab": "http://example.org/",
|
@@ -1869,7 +2836,7 @@ describe JSON::LD::API do
|
|
1869
2836
|
]
|
1870
2837
|
}])
|
1871
2838
|
},
|
1872
|
-
"Nested @container: @type"
|
2839
|
+
"Nested @container: @type": {
|
1873
2840
|
input: %({
|
1874
2841
|
"@context": {
|
1875
2842
|
"@vocab": "http://example/",
|
@@ -1890,7 +2857,7 @@ describe JSON::LD::API do
|
|
1890
2857
|
]
|
1891
2858
|
}])
|
1892
2859
|
},
|
1893
|
-
"Nested @container: @id"
|
2860
|
+
"Nested @container: @id": {
|
1894
2861
|
input: %({
|
1895
2862
|
"@context": {
|
1896
2863
|
"@vocab": "http://example/",
|
@@ -1911,7 +2878,7 @@ describe JSON::LD::API do
|
|
1911
2878
|
]
|
1912
2879
|
}])
|
1913
2880
|
},
|
1914
|
-
"Nest term an invalid keyword"
|
2881
|
+
"Nest term an invalid keyword": {
|
1915
2882
|
input: %({
|
1916
2883
|
"@context": {
|
1917
2884
|
"term": {"@id": "http://example/term", "@nest": "@id"}
|
@@ -1919,7 +2886,7 @@ describe JSON::LD::API do
|
|
1919
2886
|
}),
|
1920
2887
|
exception: JSON::LD::JsonLdError::InvalidNestValue
|
1921
2888
|
},
|
1922
|
-
"Nest in @reverse"
|
2889
|
+
"Nest in @reverse": {
|
1923
2890
|
input: %({
|
1924
2891
|
"@context": {
|
1925
2892
|
"term": {"@reverse": "http://example/term", "@nest": "@nest"}
|
@@ -1927,7 +2894,7 @@ describe JSON::LD::API do
|
|
1927
2894
|
}),
|
1928
2895
|
exception: JSON::LD::JsonLdError::InvalidReverseProperty
|
1929
2896
|
},
|
1930
|
-
"Raises InvalidTermDefinition if processingMode is
|
2897
|
+
"Raises InvalidTermDefinition if processingMode is 1.0": {
|
1931
2898
|
input: %({
|
1932
2899
|
"@context": {
|
1933
2900
|
"@vocab": "http://example.org/",
|
@@ -1938,7 +2905,7 @@ describe JSON::LD::API do
|
|
1938
2905
|
"list": ["a", "b"]
|
1939
2906
|
}
|
1940
2907
|
}),
|
1941
|
-
processingMode:
|
2908
|
+
processingMode: 'json-ld-1.0',
|
1942
2909
|
validate: true,
|
1943
2910
|
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
1944
2911
|
},
|
@@ -1949,7 +2916,7 @@ describe JSON::LD::API do
|
|
1949
2916
|
|
1950
2917
|
context "scoped context" do
|
1951
2918
|
{
|
1952
|
-
"adding new term"
|
2919
|
+
"adding new term": {
|
1953
2920
|
input: %({
|
1954
2921
|
"@context": {
|
1955
2922
|
"@vocab": "http://example/",
|
@@ -1965,7 +2932,7 @@ describe JSON::LD::API do
|
|
1965
2932
|
}
|
1966
2933
|
])
|
1967
2934
|
},
|
1968
|
-
"overriding a term"
|
2935
|
+
"overriding a term": {
|
1969
2936
|
input: %({
|
1970
2937
|
"@context": {
|
1971
2938
|
"@vocab": "http://example/",
|
@@ -1982,7 +2949,7 @@ describe JSON::LD::API do
|
|
1982
2949
|
}
|
1983
2950
|
])
|
1984
2951
|
},
|
1985
|
-
"property and value with different terms mapping to the same expanded property"
|
2952
|
+
"property and value with different terms mapping to the same expanded property": {
|
1986
2953
|
input: %({
|
1987
2954
|
"@context": {
|
1988
2955
|
"@vocab": "http://example/",
|
@@ -2002,7 +2969,7 @@ describe JSON::LD::API do
|
|
2002
2969
|
}
|
2003
2970
|
])
|
2004
2971
|
},
|
2005
|
-
"deep @context affects nested nodes"
|
2972
|
+
"deep @context affects nested nodes": {
|
2006
2973
|
input: %({
|
2007
2974
|
"@context": {
|
2008
2975
|
"@vocab": "http://example/",
|
@@ -2024,7 +2991,7 @@ describe JSON::LD::API do
|
|
2024
2991
|
}
|
2025
2992
|
])
|
2026
2993
|
},
|
2027
|
-
"scoped context layers on intemediate contexts"
|
2994
|
+
"scoped context layers on intemediate contexts": {
|
2028
2995
|
input: %({
|
2029
2996
|
"@context": {
|
2030
2997
|
"@vocab": "http://example/",
|
@@ -2051,7 +3018,7 @@ describe JSON::LD::API do
|
|
2051
3018
|
"http://example/c": [{"@value": "C in example"}]
|
2052
3019
|
}])
|
2053
3020
|
},
|
2054
|
-
"Raises InvalidTermDefinition if processingMode is
|
3021
|
+
"Raises InvalidTermDefinition if processingMode is 1.0": {
|
2055
3022
|
input: %({
|
2056
3023
|
"@context": {
|
2057
3024
|
"@vocab": "http://example/",
|
@@ -2061,10 +3028,59 @@ describe JSON::LD::API do
|
|
2061
3028
|
"bar": "baz"
|
2062
3029
|
}
|
2063
3030
|
}),
|
2064
|
-
processingMode:
|
3031
|
+
processingMode: 'json-ld-1.0',
|
2065
3032
|
validate: true,
|
2066
3033
|
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
2067
3034
|
},
|
3035
|
+
"Scoped on id map": {
|
3036
|
+
input: %({
|
3037
|
+
"@context": {
|
3038
|
+
"@version": 1.1,
|
3039
|
+
"schema": "http://schema.org/",
|
3040
|
+
"name": "schema:name",
|
3041
|
+
"body": "schema:articleBody",
|
3042
|
+
"words": "schema:wordCount",
|
3043
|
+
"post": {
|
3044
|
+
"@id": "schema:blogPost",
|
3045
|
+
"@container": "@id",
|
3046
|
+
"@context": {
|
3047
|
+
"@base": "http://example.com/posts/"
|
3048
|
+
}
|
3049
|
+
}
|
3050
|
+
},
|
3051
|
+
"@id": "http://example.com/",
|
3052
|
+
"@type": "schema:Blog",
|
3053
|
+
"name": "World Financial News",
|
3054
|
+
"post": {
|
3055
|
+
"1/en": {
|
3056
|
+
"body": "World commodities were up today with heavy trading of crude oil...",
|
3057
|
+
"words": 1539
|
3058
|
+
},
|
3059
|
+
"1/de": {
|
3060
|
+
"body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...",
|
3061
|
+
"words": 1204
|
3062
|
+
}
|
3063
|
+
}
|
3064
|
+
}),
|
3065
|
+
output: %([{
|
3066
|
+
"@id": "http://example.com/",
|
3067
|
+
"@type": ["http://schema.org/Blog"],
|
3068
|
+
"http://schema.org/name": [{"@value": "World Financial News"}],
|
3069
|
+
"http://schema.org/blogPost": [{
|
3070
|
+
"@id": "http://example.com/posts/1/en",
|
3071
|
+
"http://schema.org/articleBody": [
|
3072
|
+
{"@value": "World commodities were up today with heavy trading of crude oil..."}
|
3073
|
+
],
|
3074
|
+
"http://schema.org/wordCount": [{"@value": 1539}]
|
3075
|
+
}, {
|
3076
|
+
"@id": "http://example.com/posts/1/de",
|
3077
|
+
"http://schema.org/articleBody": [
|
3078
|
+
{"@value": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl..."}
|
3079
|
+
],
|
3080
|
+
"http://schema.org/wordCount": [{"@value": 1204}]
|
3081
|
+
}]
|
3082
|
+
}])
|
3083
|
+
}
|
2068
3084
|
}.each do |title, params|
|
2069
3085
|
it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
|
2070
3086
|
end
|
@@ -2072,7 +3088,7 @@ describe JSON::LD::API do
|
|
2072
3088
|
|
2073
3089
|
context "scoped context on @type" do
|
2074
3090
|
{
|
2075
|
-
"adding new term"
|
3091
|
+
"adding new term": {
|
2076
3092
|
input: %({
|
2077
3093
|
"@context": {
|
2078
3094
|
"@vocab": "http://example/",
|
@@ -2089,7 +3105,7 @@ describe JSON::LD::API do
|
|
2089
3105
|
}
|
2090
3106
|
])
|
2091
3107
|
},
|
2092
|
-
"overriding a term"
|
3108
|
+
"overriding a term": {
|
2093
3109
|
input: %({
|
2094
3110
|
"@context": {
|
2095
3111
|
"@vocab": "http://example/",
|
@@ -2107,7 +3123,7 @@ describe JSON::LD::API do
|
|
2107
3123
|
}
|
2108
3124
|
])
|
2109
3125
|
},
|
2110
|
-
"alias of @type"
|
3126
|
+
"alias of @type": {
|
2111
3127
|
input: %({
|
2112
3128
|
"@context": {
|
2113
3129
|
"@vocab": "http://example/",
|
@@ -2125,7 +3141,7 @@ describe JSON::LD::API do
|
|
2125
3141
|
}
|
2126
3142
|
])
|
2127
3143
|
},
|
2128
|
-
"deep @context
|
3144
|
+
"deep @context does not affect nested nodes": {
|
2129
3145
|
input: %({
|
2130
3146
|
"@context": {
|
2131
3147
|
"@vocab": "http://example/",
|
@@ -2138,12 +3154,12 @@ describe JSON::LD::API do
|
|
2138
3154
|
{
|
2139
3155
|
"@type": ["http://example/Foo"],
|
2140
3156
|
"http://example/bar": [{
|
2141
|
-
"http://example/baz": [{"@
|
3157
|
+
"http://example/baz": [{"@value": "buzz"}]
|
2142
3158
|
}]
|
2143
3159
|
}
|
2144
3160
|
])
|
2145
3161
|
},
|
2146
|
-
"scoped context layers on intemediate contexts"
|
3162
|
+
"scoped context layers on intemediate contexts": {
|
2147
3163
|
input: %({
|
2148
3164
|
"@context": {
|
2149
3165
|
"@vocab": "http://example/",
|
@@ -2166,7 +3182,7 @@ describe JSON::LD::API do
|
|
2166
3182
|
"http://example/c": [{"@value": "C in example"}]
|
2167
3183
|
}])
|
2168
3184
|
},
|
2169
|
-
"with @container: @type"
|
3185
|
+
"with @container: @type": {
|
2170
3186
|
input: %({
|
2171
3187
|
"@context": {
|
2172
3188
|
"@vocab": "http://example/",
|
@@ -2183,7 +3199,7 @@ describe JSON::LD::API do
|
|
2183
3199
|
]
|
2184
3200
|
}])
|
2185
3201
|
},
|
2186
|
-
"orders lexicographically"
|
3202
|
+
"orders lexicographically": {
|
2187
3203
|
input: %({
|
2188
3204
|
"@context": {
|
2189
3205
|
"@vocab": "http://example/",
|
@@ -2200,7 +3216,7 @@ describe JSON::LD::API do
|
|
2200
3216
|
]
|
2201
3217
|
}])
|
2202
3218
|
},
|
2203
|
-
"Raises InvalidTermDefinition if processingMode is
|
3219
|
+
"Raises InvalidTermDefinition if processingMode is 1.0": {
|
2204
3220
|
input: %({
|
2205
3221
|
"@context": {
|
2206
3222
|
"@vocab": "http://example/",
|
@@ -2208,7 +3224,7 @@ describe JSON::LD::API do
|
|
2208
3224
|
},
|
2209
3225
|
"a": {"@type": "Foo", "bar": "baz"}
|
2210
3226
|
}),
|
2211
|
-
processingMode:
|
3227
|
+
processingMode: 'json-ld-1.0',
|
2212
3228
|
validate: true,
|
2213
3229
|
exception: JSON::LD::JsonLdError::InvalidTermDefinition
|
2214
3230
|
},
|
@@ -2219,7 +3235,7 @@ describe JSON::LD::API do
|
|
2219
3235
|
|
2220
3236
|
context "@reverse" do
|
2221
3237
|
{
|
2222
|
-
"@container: @reverse"
|
3238
|
+
"@container: @reverse": {
|
2223
3239
|
input: %({
|
2224
3240
|
"@context": {
|
2225
3241
|
"@vocab": "http://example/",
|
@@ -2239,7 +3255,7 @@ describe JSON::LD::API do
|
|
2239
3255
|
}
|
2240
3256
|
}])
|
2241
3257
|
},
|
2242
|
-
"expand-0037"
|
3258
|
+
"expand-0037": {
|
2243
3259
|
input: %({
|
2244
3260
|
"@context": {
|
2245
3261
|
"name": "http://xmlns.com/foaf/0.1/name"
|
@@ -2276,7 +3292,7 @@ describe JSON::LD::API do
|
|
2276
3292
|
}
|
2277
3293
|
])
|
2278
3294
|
},
|
2279
|
-
"expand-0043"
|
3295
|
+
"expand-0043": {
|
2280
3296
|
input: %({
|
2281
3297
|
"@context": {
|
2282
3298
|
"name": "http://xmlns.com/foaf/0.1/name",
|
@@ -2326,7 +3342,7 @@ describe JSON::LD::API do
|
|
2326
3342
|
}
|
2327
3343
|
])
|
2328
3344
|
},
|
2329
|
-
"@reverse object with an @id property"
|
3345
|
+
"@reverse object with an @id property": {
|
2330
3346
|
input: %({
|
2331
3347
|
"@id": "http://example/foo",
|
2332
3348
|
"@reverse": {
|
@@ -2340,24 +3356,417 @@ describe JSON::LD::API do
|
|
2340
3356
|
end
|
2341
3357
|
end
|
2342
3358
|
|
3359
|
+
begin
|
3360
|
+
require 'nokogiri'
|
3361
|
+
rescue LoadError
|
3362
|
+
end
|
3363
|
+
require 'rexml/document'
|
3364
|
+
|
3365
|
+
context "html" do
|
3366
|
+
%w(Nokogiri REXML).each do |impl|
|
3367
|
+
next unless Module.constants.map(&:to_s).include?(impl)
|
3368
|
+
context impl do
|
3369
|
+
before(:all) {@library = impl.downcase.to_s.to_sym}
|
3370
|
+
|
3371
|
+
{
|
3372
|
+
"Expands embedded JSON-LD script element": {
|
3373
|
+
input: %(
|
3374
|
+
<html>
|
3375
|
+
<head>
|
3376
|
+
<script type="application/ld+json">
|
3377
|
+
{
|
3378
|
+
"@context": {
|
3379
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3380
|
+
},
|
3381
|
+
"foo": [{"@value": "bar"}]
|
3382
|
+
}
|
3383
|
+
</script>
|
3384
|
+
</head>
|
3385
|
+
</html>),
|
3386
|
+
output: %([{
|
3387
|
+
"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
|
3388
|
+
}])
|
3389
|
+
},
|
3390
|
+
"Expands first script element": {
|
3391
|
+
input: %(
|
3392
|
+
<html>
|
3393
|
+
<head>
|
3394
|
+
<script type="application/ld+json">
|
3395
|
+
{
|
3396
|
+
"@context": {
|
3397
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3398
|
+
},
|
3399
|
+
"foo": [{"@value": "bar"}]
|
3400
|
+
}
|
3401
|
+
</script>
|
3402
|
+
<script type="application/ld+json">
|
3403
|
+
{
|
3404
|
+
"@context": {"ex": "http://example.com/"},
|
3405
|
+
"@graph": [
|
3406
|
+
{"ex:foo": {"@value": "foo"}},
|
3407
|
+
{"ex:bar": {"@value": "bar"}}
|
3408
|
+
]
|
3409
|
+
}
|
3410
|
+
</script>
|
3411
|
+
</head>
|
3412
|
+
</html>),
|
3413
|
+
output: %([{
|
3414
|
+
"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
|
3415
|
+
}])
|
3416
|
+
},
|
3417
|
+
"Expands targeted script element": {
|
3418
|
+
input: %(
|
3419
|
+
<html>
|
3420
|
+
<head>
|
3421
|
+
<script id="first" type="application/ld+json">
|
3422
|
+
{
|
3423
|
+
"@context": {
|
3424
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3425
|
+
},
|
3426
|
+
"foo": [{"@value": "bar"}]
|
3427
|
+
}
|
3428
|
+
</script>
|
3429
|
+
<script id="second" type="application/ld+json">
|
3430
|
+
{
|
3431
|
+
"@context": {"ex": "http://example.com/"},
|
3432
|
+
"@graph": [
|
3433
|
+
{"ex:foo": {"@value": "foo"}},
|
3434
|
+
{"ex:bar": {"@value": "bar"}}
|
3435
|
+
]
|
3436
|
+
}
|
3437
|
+
</script>
|
3438
|
+
</head>
|
3439
|
+
</html>),
|
3440
|
+
output: %([
|
3441
|
+
{"http://example.com/foo": [{"@value": "foo"}]},
|
3442
|
+
{"http://example.com/bar": [{"@value": "bar"}]}
|
3443
|
+
]),
|
3444
|
+
base: "http://example.org/doc#second"
|
3445
|
+
},
|
3446
|
+
"Expands all script elements with extractAllScripts option": {
|
3447
|
+
input: %(
|
3448
|
+
<html>
|
3449
|
+
<head>
|
3450
|
+
<script type="application/ld+json">
|
3451
|
+
{
|
3452
|
+
"@context": {
|
3453
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3454
|
+
},
|
3455
|
+
"foo": [{"@value": "bar"}]
|
3456
|
+
}
|
3457
|
+
</script>
|
3458
|
+
<script type="application/ld+json">
|
3459
|
+
{
|
3460
|
+
"@context": {"ex": "http://example.com/"},
|
3461
|
+
"@graph": [
|
3462
|
+
{"ex:foo": {"@value": "foo"}},
|
3463
|
+
{"ex:bar": {"@value": "bar"}}
|
3464
|
+
]
|
3465
|
+
}
|
3466
|
+
</script>
|
3467
|
+
</head>
|
3468
|
+
</html>),
|
3469
|
+
output: %([
|
3470
|
+
{"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]},
|
3471
|
+
{
|
3472
|
+
"@graph": [{
|
3473
|
+
"http://example.com/foo": [{"@value": "foo"}]
|
3474
|
+
}, {
|
3475
|
+
"http://example.com/bar": [{"@value": "bar"}]
|
3476
|
+
}]
|
3477
|
+
}
|
3478
|
+
]),
|
3479
|
+
extractAllScripts: true
|
3480
|
+
},
|
3481
|
+
"Expands multiple scripts where one is an array": {
|
3482
|
+
input: %(
|
3483
|
+
<html>
|
3484
|
+
<head>
|
3485
|
+
<script type="application/ld+json">
|
3486
|
+
{
|
3487
|
+
"@context": {
|
3488
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3489
|
+
},
|
3490
|
+
"foo": [{"@value": "bar"}]
|
3491
|
+
}
|
3492
|
+
</script>
|
3493
|
+
<script type="application/ld+json">
|
3494
|
+
[
|
3495
|
+
{"@context": {"ex": "http://example.com/"}, "ex:foo": {"@value": "foo"}},
|
3496
|
+
{"@context": {"ex": "http://example.com/"}, "ex:bar": {"@value": "bar"}}
|
3497
|
+
]
|
3498
|
+
</script>
|
3499
|
+
</head>
|
3500
|
+
</html>),
|
3501
|
+
output: %([
|
3502
|
+
{"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]},
|
3503
|
+
{"http://example.com/foo": [{"@value": "foo"}]},
|
3504
|
+
{"http://example.com/bar": [{"@value": "bar"}]}
|
3505
|
+
]),
|
3506
|
+
extractAllScripts: true
|
3507
|
+
},
|
3508
|
+
"Expands as empty with no script element": {
|
3509
|
+
input: %(<html><head></head></html>),
|
3510
|
+
output: %([])
|
3511
|
+
},
|
3512
|
+
"Expands as empty with no script element and extractAllScripts": {
|
3513
|
+
input: %(<html><head></head></html>),
|
3514
|
+
output: %([]),
|
3515
|
+
extractAllScripts: true
|
3516
|
+
},
|
3517
|
+
"Expands script element with HTML character references": {
|
3518
|
+
input: %(
|
3519
|
+
<html>
|
3520
|
+
<head>
|
3521
|
+
<script type="application/ld+json">
|
3522
|
+
{
|
3523
|
+
"@context": {"@vocab": "http://example/"},
|
3524
|
+
"foo": "<&>"
|
3525
|
+
}
|
3526
|
+
</script>
|
3527
|
+
</head>
|
3528
|
+
</html>),
|
3529
|
+
output: %([{
|
3530
|
+
"http://example/foo": [{"@value": "<&>"}]
|
3531
|
+
}])
|
3532
|
+
},
|
3533
|
+
"Expands embedded JSON-LD script element relative to document base": {
|
3534
|
+
input: %(
|
3535
|
+
<html>
|
3536
|
+
<head>
|
3537
|
+
<script type="application/ld+json">
|
3538
|
+
{
|
3539
|
+
"@context": {
|
3540
|
+
"foo": {"@id": "http://example.com/foo"}
|
3541
|
+
},
|
3542
|
+
"@id": "",
|
3543
|
+
"foo": [{"@value": "bar"}]
|
3544
|
+
}
|
3545
|
+
</script>
|
3546
|
+
</head>
|
3547
|
+
</html>),
|
3548
|
+
output: %([{
|
3549
|
+
"@id": "http://example.org/doc",
|
3550
|
+
"http://example.com/foo": [{"@value": "bar"}]
|
3551
|
+
}]),
|
3552
|
+
base: "http://example.org/doc"
|
3553
|
+
},
|
3554
|
+
"Expands embedded JSON-LD script element relative to HTML base": {
|
3555
|
+
input: %(
|
3556
|
+
<html>
|
3557
|
+
<head>
|
3558
|
+
<base href="http://example.org/base" />
|
3559
|
+
<script type="application/ld+json">
|
3560
|
+
{
|
3561
|
+
"@context": {
|
3562
|
+
"foo": {"@id": "http://example.com/foo"}
|
3563
|
+
},
|
3564
|
+
"@id": "",
|
3565
|
+
"foo": [{"@value": "bar"}]
|
3566
|
+
}
|
3567
|
+
</script>
|
3568
|
+
</head>
|
3569
|
+
</html>),
|
3570
|
+
output: %([{
|
3571
|
+
"@id": "http://example.org/base",
|
3572
|
+
"http://example.com/foo": [{"@value": "bar"}]
|
3573
|
+
}]),
|
3574
|
+
base: "http://example.org/doc"
|
3575
|
+
},
|
3576
|
+
"Expands embedded JSON-LD script element relative to relative HTML base": {
|
3577
|
+
input: %(
|
3578
|
+
<html>
|
3579
|
+
<head>
|
3580
|
+
<base href="base" />
|
3581
|
+
<script type="application/ld+json">
|
3582
|
+
{
|
3583
|
+
"@context": {
|
3584
|
+
"foo": {"@id": "http://example.com/foo"}
|
3585
|
+
},
|
3586
|
+
"@id": "",
|
3587
|
+
"foo": [{"@value": "bar"}]
|
3588
|
+
}
|
3589
|
+
</script>
|
3590
|
+
</head>
|
3591
|
+
</html>),
|
3592
|
+
output: %([{
|
3593
|
+
"@id": "http://example.org/base",
|
3594
|
+
"http://example.com/foo": [{"@value": "bar"}]
|
3595
|
+
}]),
|
3596
|
+
base: "http://example.org/doc"
|
3597
|
+
},
|
3598
|
+
"Errors if no element found at target": {
|
3599
|
+
input: %(
|
3600
|
+
<html>
|
3601
|
+
<head>
|
3602
|
+
<script id="first" type="application/ld+json">
|
3603
|
+
{
|
3604
|
+
"@context": {
|
3605
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3606
|
+
},
|
3607
|
+
"foo": [{"@value": "bar"}]
|
3608
|
+
}
|
3609
|
+
</script>
|
3610
|
+
<script id="second" type="application/ld+json">
|
3611
|
+
{
|
3612
|
+
"@context": {"ex": "http://example.com/"},
|
3613
|
+
"@graph": [
|
3614
|
+
{"ex:foo": {"@value": "foo"}},
|
3615
|
+
{"ex:bar": {"@value": "bar"}}
|
3616
|
+
]
|
3617
|
+
}
|
3618
|
+
</script>
|
3619
|
+
</head>
|
3620
|
+
</html>),
|
3621
|
+
base: "http://example.org/doc#third",
|
3622
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement
|
3623
|
+
},
|
3624
|
+
"Errors if targeted element is not a script element": {
|
3625
|
+
input: %(
|
3626
|
+
<html>
|
3627
|
+
<head>
|
3628
|
+
<pre id="first" type="application/ld+json">
|
3629
|
+
{
|
3630
|
+
"@context": {
|
3631
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3632
|
+
},
|
3633
|
+
"foo": [{"@value": "bar"}]
|
3634
|
+
}
|
3635
|
+
</pre>
|
3636
|
+
</head>
|
3637
|
+
</html>),
|
3638
|
+
base: "http://example.org/doc#first",
|
3639
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement
|
3640
|
+
},
|
3641
|
+
"Errors if targeted element does not have type application/ld+json": {
|
3642
|
+
input: %(
|
3643
|
+
<html>
|
3644
|
+
<head>
|
3645
|
+
<script id="first" type="application/json">
|
3646
|
+
{
|
3647
|
+
"@context": {
|
3648
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3649
|
+
},
|
3650
|
+
"foo": [{"@value": "bar"}]
|
3651
|
+
}
|
3652
|
+
</script>
|
3653
|
+
</head>
|
3654
|
+
</html>),
|
3655
|
+
base: "http://example.org/doc#first",
|
3656
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement
|
3657
|
+
},
|
3658
|
+
"Errors if uncommented script text contains comment": {
|
3659
|
+
input: %(
|
3660
|
+
<html>
|
3661
|
+
<head>
|
3662
|
+
<script type="application/ld+json">
|
3663
|
+
<!--
|
3664
|
+
{
|
3665
|
+
"@context": {
|
3666
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3667
|
+
},
|
3668
|
+
"foo": [{"@value": "<!-- -->"}]
|
3669
|
+
}
|
3670
|
+
-->
|
3671
|
+
</script>
|
3672
|
+
</head>
|
3673
|
+
</html>),
|
3674
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement,
|
3675
|
+
not: :rexml
|
3676
|
+
},
|
3677
|
+
"Errors if end comment missing": {
|
3678
|
+
input: %(
|
3679
|
+
<html>
|
3680
|
+
<head>
|
3681
|
+
<script type="application/ld+json">
|
3682
|
+
<!--
|
3683
|
+
{
|
3684
|
+
"@context": {
|
3685
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3686
|
+
},
|
3687
|
+
"foo": [{"@value": "bar"}]
|
3688
|
+
}
|
3689
|
+
</script>
|
3690
|
+
</head>
|
3691
|
+
</html>),
|
3692
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement,
|
3693
|
+
not: :rexml
|
3694
|
+
},
|
3695
|
+
"Errors if start comment missing": {
|
3696
|
+
input: %(
|
3697
|
+
<html>
|
3698
|
+
<head>
|
3699
|
+
<script type="application/ld+json">
|
3700
|
+
{
|
3701
|
+
"@context": {
|
3702
|
+
"foo": {"@id": "http://example.com/foo", "@container": "@list"}
|
3703
|
+
},
|
3704
|
+
"foo": [{"@value": "bar"}]
|
3705
|
+
}
|
3706
|
+
-->
|
3707
|
+
</script>
|
3708
|
+
</head>
|
3709
|
+
</html>),
|
3710
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement
|
3711
|
+
},
|
3712
|
+
"Errors if uncommented script is not valid JSON": {
|
3713
|
+
input: %(
|
3714
|
+
<html>
|
3715
|
+
<head>
|
3716
|
+
<script type="application/ld+json">
|
3717
|
+
foo
|
3718
|
+
</script>
|
3719
|
+
</head>
|
3720
|
+
</html>),
|
3721
|
+
exception: JSON::LD::JsonLdError::InvalidScriptElement
|
3722
|
+
},
|
3723
|
+
}.each do |title, params|
|
3724
|
+
it(title) do
|
3725
|
+
skip "rexml" if params[:not] == @library
|
3726
|
+
params[:input] = StringIO.new(params[:input])
|
3727
|
+
params[:input].send(:define_singleton_method, :content_type) {"text/html"}
|
3728
|
+
run_expand params.merge(validate: true, library: @library)
|
3729
|
+
end
|
3730
|
+
end
|
3731
|
+
end
|
3732
|
+
end
|
3733
|
+
end
|
3734
|
+
|
3735
|
+
context "deprectaions" do
|
3736
|
+
{
|
3737
|
+
"blank node property": {
|
3738
|
+
input: %({"_:bn": "value"}),
|
3739
|
+
output: %([{"_:bn": [{"@value": "value"}]}])
|
3740
|
+
}
|
3741
|
+
}.each do |name, params|
|
3742
|
+
it "deprecation on #{name} when validating" do
|
3743
|
+
run_expand(params.merge(validate: true, write: "[DEPRECATION]"))
|
3744
|
+
end
|
3745
|
+
|
3746
|
+
it "no deprecation on #{name} when not validating" do
|
3747
|
+
run_expand(params.merge(validate: false))
|
3748
|
+
end
|
3749
|
+
end
|
3750
|
+
end
|
3751
|
+
|
2343
3752
|
context "exceptions" do
|
2344
3753
|
{
|
2345
|
-
"non-null @value and null @type"
|
2346
|
-
input: {"http://example.com/foo"
|
3754
|
+
"non-null @value and null @type": {
|
3755
|
+
input: %({"http://example.com/foo": {"@value": "foo", "@type": null}}),
|
2347
3756
|
exception: JSON::LD::JsonLdError::InvalidTypeValue
|
2348
3757
|
},
|
2349
|
-
"non-null @value and null @language"
|
2350
|
-
input: {"http://example.com/foo"
|
3758
|
+
"non-null @value and null @language": {
|
3759
|
+
input: %({"http://example.com/foo": {"@value": "foo", "@language": null}}),
|
2351
3760
|
exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString
|
2352
3761
|
},
|
2353
|
-
"value with null language"
|
2354
|
-
input: {
|
2355
|
-
"@context"
|
2356
|
-
"http://example.org/nolang"
|
2357
|
-
},
|
3762
|
+
"value with null language": {
|
3763
|
+
input: %({
|
3764
|
+
"@context": {"@language": "en"},
|
3765
|
+
"http://example.org/nolang": {"@value": "no language", "@language": null}
|
3766
|
+
}),
|
2358
3767
|
exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString
|
2359
3768
|
},
|
2360
|
-
"colliding keywords"
|
3769
|
+
"colliding keywords": {
|
2361
3770
|
input: %({
|
2362
3771
|
"@context": {
|
2363
3772
|
"id": "@id",
|
@@ -2367,7 +3776,45 @@ describe JSON::LD::API do
|
|
2367
3776
|
"ID": "http://example/bar"
|
2368
3777
|
}),
|
2369
3778
|
exception: JSON::LD::JsonLdError::CollidingKeywords,
|
2370
|
-
}
|
3779
|
+
},
|
3780
|
+
"@language and @type": {
|
3781
|
+
input: %({
|
3782
|
+
"ex:p": {
|
3783
|
+
"@value": "v",
|
3784
|
+
"@type": "ex:t",
|
3785
|
+
"@language": "en"
|
3786
|
+
}
|
3787
|
+
}),
|
3788
|
+
exception: JSON::LD::JsonLdError::InvalidValueObject,
|
3789
|
+
processingMode: 'json-ld-1.1'
|
3790
|
+
},
|
3791
|
+
"@direction and @type": {
|
3792
|
+
input: %({
|
3793
|
+
"ex:p": {
|
3794
|
+
"@value": "v",
|
3795
|
+
"@type": "ex:t",
|
3796
|
+
"@direction": "rtl"
|
3797
|
+
}
|
3798
|
+
}),
|
3799
|
+
exception: JSON::LD::JsonLdError::InvalidValueObject,
|
3800
|
+
processingMode: 'json-ld-1.1'
|
3801
|
+
},
|
3802
|
+
}.each do |title, params|
|
3803
|
+
it(title) {run_expand params}
|
3804
|
+
end
|
3805
|
+
end
|
3806
|
+
|
3807
|
+
context "problem cases" do
|
3808
|
+
{
|
3809
|
+
"toRdf/0118": {
|
3810
|
+
input: %({
|
3811
|
+
"@context": {"term": "_:term", "termId": { "@id": "term", "@type": "@id" }},
|
3812
|
+
"termId": "term:AppendedToBlankNode"
|
3813
|
+
}),
|
3814
|
+
output: %([{
|
3815
|
+
"_:term": [{"@id": "_:termAppendedToBlankNode"}]
|
3816
|
+
}])
|
3817
|
+
},
|
2371
3818
|
}.each do |title, params|
|
2372
3819
|
it(title) {run_expand params}
|
2373
3820
|
end
|
@@ -2376,14 +3823,23 @@ describe JSON::LD::API do
|
|
2376
3823
|
|
2377
3824
|
def run_expand(params)
|
2378
3825
|
input, output = params[:input], params[:output]
|
3826
|
+
params[:base] ||= nil
|
2379
3827
|
input = ::JSON.parse(input) if input.is_a?(String)
|
2380
3828
|
output = ::JSON.parse(output) if output.is_a?(String)
|
2381
3829
|
pending params.fetch(:pending, "test implementation") unless input
|
2382
3830
|
if params[:exception]
|
2383
|
-
expect {JSON::LD::API.expand(input, params)}.to raise_error(params[:exception])
|
3831
|
+
expect {JSON::LD::API.expand(input, **params)}.to raise_error(params[:exception])
|
2384
3832
|
else
|
2385
|
-
jld =
|
3833
|
+
jld = nil
|
3834
|
+
if params[:write]
|
3835
|
+
expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.to write(params[:write]).to(:error)
|
3836
|
+
else
|
3837
|
+
expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.not_to write.to(:error)
|
3838
|
+
end
|
2386
3839
|
expect(jld).to produce_jsonld(output, logger)
|
3840
|
+
|
3841
|
+
# Also expect result to produce itself
|
3842
|
+
expect(output).to produce_jsonld(output, logger)
|
2387
3843
|
end
|
2388
3844
|
end
|
2389
3845
|
end
|