json-ld 3.1.6 → 3.1.10

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.
data/spec/flatten_spec.rb CHANGED
@@ -206,7 +206,8 @@ describe JSON::LD::API do
206
206
  "http://example.org/bar": [ { "@id": "_:b0" } ]
207
207
  }
208
208
  ]
209
- }
209
+ },
210
+ remap_nodes: true
210
211
  },
211
212
  "@list with embedded object": {
212
213
  input: %([{
@@ -665,6 +666,519 @@ describe JSON::LD::API do
665
666
  end
666
667
  end
667
668
 
669
+ context "JSON-LD-star" do
670
+ {
671
+ "node object with @annotation property is ignored without rdfstar option": {
672
+ input: %({
673
+ "@id": "ex:bob",
674
+ "ex:knows": {
675
+ "@id": "ex:fred",
676
+ "@annotation": {
677
+ "ex:certainty": 0.8
678
+ }
679
+ }
680
+ }),
681
+ output: %([{
682
+ "@id": "ex:bob",
683
+ "ex:knows": [{"@id": "ex:fred"}]
684
+ }])
685
+ },
686
+ "value object with @annotation property is ignored without rdfstar option": {
687
+ input: %({
688
+ "@id": "ex:bob",
689
+ "ex:age": {
690
+ "@value": 23,
691
+ "@annotation": {
692
+ "ex:certainty": 0.8
693
+ }
694
+ }
695
+ }),
696
+ output: %([{
697
+ "@id": "ex:bob",
698
+ "ex:age": [{"@value": 23}]
699
+ }])
700
+ },
701
+ }.each do |title, params|
702
+ it(title) {run_flatten params}
703
+ end
704
+
705
+ {
706
+ "node with embedded subject having no @id": {
707
+ input: %({
708
+ "@id": {
709
+ "ex:prop": "value"
710
+ },
711
+ "ex:prop": "value2"
712
+ }),
713
+ output: %([{
714
+ "@id": {
715
+ "ex:prop": [{"@value": "value"}]
716
+ },
717
+ "ex:prop": [{"@value": "value2"}]
718
+ }])
719
+ },
720
+ "node with embedded subject having IRI @id": {
721
+ input: %({
722
+ "@id": {
723
+ "@id": "ex:rei",
724
+ "ex:prop": "value"
725
+ },
726
+ "ex:prop": "value2"
727
+ }),
728
+ output: %([{
729
+ "@id": {
730
+ "@id": "ex:rei",
731
+ "ex:prop": [{"@value": "value"}]
732
+ },
733
+ "ex:prop": [{"@value": "value2"}]
734
+ }])
735
+ },
736
+ "node with embedded subject having BNode @id": {
737
+ input: %({
738
+ "@id": {
739
+ "@id": "_:rei",
740
+ "ex:prop": "value"
741
+ },
742
+ "ex:prop": "value2"
743
+ }),
744
+ output: %([{
745
+ "@id": {
746
+ "@id": "_:b0",
747
+ "ex:prop": [{"@value": "value"}]
748
+ },
749
+ "ex:prop": [{"@value": "value2"}]
750
+ }])
751
+ },
752
+ "node with embedded subject having a type": {
753
+ input: %({
754
+ "@id": {
755
+ "@id": "ex:rei",
756
+ "@type": "ex:Type"
757
+ },
758
+ "ex:prop": "value2"
759
+ }),
760
+ output: %([{
761
+ "@id": {
762
+ "@id": "ex:rei",
763
+ "@type": ["ex:Type"]
764
+ },
765
+ "ex:prop": [{"@value": "value2"}]
766
+ }])
767
+ },
768
+ "node with embedded subject having an IRI value": {
769
+ input: %({
770
+ "@id": {
771
+ "@id": "ex:rei",
772
+ "ex:prop": {"@id": "ex:value"}
773
+ },
774
+ "ex:prop": "value2"
775
+ }),
776
+ output: %([{
777
+ "@id": {
778
+ "@id": "ex:rei",
779
+ "ex:prop": [{"@id": "ex:value"}]
780
+ },
781
+ "ex:prop": [{"@value": "value2"}]
782
+ }])
783
+ },
784
+ "node with embedded subject having an BNode value": {
785
+ input: %({
786
+ "@id": {
787
+ "@id": "ex:rei",
788
+ "ex:prop": {"@id": "_:value"}
789
+ },
790
+ "ex:prop": "value2"
791
+ }),
792
+ output: %([{
793
+ "@id": {
794
+ "@id": "ex:rei",
795
+ "ex:prop": [{"@id": "_:b0"}]
796
+ },
797
+ "ex:prop": [{"@value": "value2"}]
798
+ }])
799
+ },
800
+ "node with recursive embedded subject": {
801
+ input: %({
802
+ "@id": {
803
+ "@id": {
804
+ "@id": "ex:rei",
805
+ "ex:prop": "value3"
806
+ },
807
+ "ex:prop": "value"
808
+ },
809
+ "ex:prop": "value2"
810
+ }),
811
+ output: %([{
812
+ "@id": {
813
+ "@id": {
814
+ "@id": "ex:rei",
815
+ "ex:prop": [{"@value": "value3"}]
816
+ },
817
+ "ex:prop": [{"@value": "value"}]
818
+ },
819
+ "ex:prop": [{"@value": "value2"}]
820
+ }])
821
+ },
822
+ "node with embedded object": {
823
+ input: %({
824
+ "@id": "ex:subj",
825
+ "ex:value": {
826
+ "@id": {
827
+ "@id": "ex:rei",
828
+ "ex:prop": "value"
829
+ }
830
+ }
831
+ }),
832
+ output: %([{
833
+ "@id": "ex:subj",
834
+ "ex:value": [{
835
+ "@id": {
836
+ "@id": "ex:rei",
837
+ "ex:prop": [{"@value": "value"}]
838
+ }
839
+ }]
840
+ }])
841
+ },
842
+ "node with embedded object having properties": {
843
+ input: %({
844
+ "@id": "ex:subj",
845
+ "ex:value": {
846
+ "@id": {
847
+ "@id": "ex:rei",
848
+ "ex:prop": "value"
849
+ },
850
+ "ex:prop": "value2"
851
+ }
852
+ }),
853
+ output: %([{
854
+ "@id": "ex:subj",
855
+ "ex:value": [{
856
+ "@id": {
857
+ "@id": "ex:rei",
858
+ "ex:prop": [{"@value": "value"}]
859
+ }
860
+ }]
861
+ }, {
862
+ "@id": {
863
+ "@id": "ex:rei",
864
+ "ex:prop": [{"@value": "value"}]
865
+ },
866
+ "ex:prop": [{"@value": "value2"}]
867
+ }])
868
+ },
869
+ "node with recursive embedded object": {
870
+ input: %({
871
+ "@id": "ex:subj",
872
+ "ex:value": {
873
+ "@id": {
874
+ "@id": {
875
+ "@id": "ex:rei",
876
+ "ex:prop": "value3"
877
+ },
878
+ "ex:prop": "value"
879
+ },
880
+ "ex:prop": "value2"
881
+ }
882
+ }),
883
+ output: %([{
884
+ "@id": "ex:subj",
885
+ "ex:value": [{
886
+ "@id": {
887
+ "@id": {
888
+ "@id": "ex:rei",
889
+ "ex:prop": [{"@value": "value3"}]
890
+ },
891
+ "ex:prop":[{"@value": "value"}]
892
+ }
893
+ }]
894
+ }, {
895
+ "@id": {
896
+ "@id": {
897
+ "@id": "ex:rei",
898
+ "ex:prop": [{"@value": "value3"}]
899
+ },
900
+ "ex:prop":[{"@value": "value"}]
901
+ },
902
+ "ex:prop": [{"@value": "value2"}]
903
+ }])
904
+ },
905
+ "node with @annotation property on value object": {
906
+ input: %({
907
+ "@id": "ex:bob",
908
+ "ex:age": {
909
+ "@value": 23,
910
+ "@annotation": {"ex:certainty": 0.8}
911
+ }
912
+ }),
913
+ output: %([{
914
+ "@id": "ex:bob",
915
+ "ex:age": [{"@value": 23}]
916
+ }, {
917
+ "@id": {
918
+ "@id": "ex:bob",
919
+ "ex:age": [{"@value": 23}]
920
+ },
921
+ "ex:certainty": [{"@value": 0.8}]
922
+ }])
923
+ },
924
+ "node with @annotation property on node object": {
925
+ input: %({
926
+ "@id": "ex:bob",
927
+ "ex:name": "Bob",
928
+ "ex:knows": {
929
+ "@id": "ex:fred",
930
+ "ex:name": "Fred",
931
+ "@annotation": {"ex:certainty": 0.8}
932
+ }
933
+ }),
934
+ output: %([{
935
+ "@id": "ex:bob",
936
+ "ex:name": [{"@value": "Bob"}],
937
+ "ex:knows": [{"@id": "ex:fred"}]
938
+ }, {
939
+ "@id": "ex:fred",
940
+ "ex:name": [{"@value": "Fred"}]
941
+ }, {
942
+ "@id": {
943
+ "@id": "ex:bob",
944
+ "ex:knows": [{"@id": "ex:fred"}]
945
+ },
946
+ "ex:certainty": [{"@value": 0.8}]
947
+ }])
948
+ },
949
+ "node with @annotation property multiple values": {
950
+ input: %({
951
+ "@id": "ex:bob",
952
+ "ex:name": "Bob",
953
+ "ex:knows": {
954
+ "@id": "ex:fred",
955
+ "ex:name": "Fred",
956
+ "@annotation": [{
957
+ "ex:certainty": 0.8
958
+ }, {
959
+ "ex:source": {"@id": "http://example.org/"}
960
+ }]
961
+ }
962
+ }),
963
+ output: %([{
964
+ "@id": "ex:bob",
965
+ "ex:name": [{"@value": "Bob"}],
966
+ "ex:knows": [{"@id": "ex:fred"}]
967
+ }, {
968
+ "@id": "ex:fred",
969
+ "ex:name": [{"@value": "Fred"}]
970
+ }, {
971
+ "@id": {
972
+ "@id": "ex:bob",
973
+ "ex:knows": [{"@id": "ex:fred"}]
974
+ },
975
+ "ex:certainty": [{"@value": 0.8}],
976
+ "ex:source": [{"@id": "http://example.org/"}]
977
+ }])
978
+ },
979
+ "node with @annotation property on embedded subject": {
980
+ input: %({
981
+ "@id": {
982
+ "@id": "ex:rei",
983
+ "ex:prop": {"@id": "_:value"}
984
+ },
985
+ "ex:prop": {
986
+ "@value": "value2",
987
+ "@annotation": {"ex:certainty": 0.8}
988
+ }
989
+ }),
990
+ output: %([{
991
+ "@id": {
992
+ "@id": "ex:rei",
993
+ "ex:prop": [{"@id": "_:b0"}]
994
+ },
995
+ "ex:prop": [{"@value": "value2"}]
996
+ }, {
997
+ "@id": {
998
+ "@id": {
999
+ "@id": "ex:rei",
1000
+ "ex:prop": [{"@id": "_:b0"}]
1001
+ },
1002
+ "ex:prop": [{"@value": "value2"}]
1003
+ },
1004
+ "ex:certainty": [{"@value": 0.8}]
1005
+ }])
1006
+ },
1007
+ "node with @annotation property on embedded object": {
1008
+ input: %({
1009
+ "@id": "ex:subj",
1010
+ "ex:value": {
1011
+ "@id": {
1012
+ "@id": "ex:rei",
1013
+ "ex:prop": "value"
1014
+ },
1015
+ "@annotation": {"ex:certainty": 0.8}
1016
+ }
1017
+ }),
1018
+ output: %([{
1019
+ "@id": "ex:subj",
1020
+ "ex:value": [{
1021
+ "@id": {
1022
+ "@id": "ex:rei",
1023
+ "ex:prop": [{"@value": "value"}]
1024
+ }
1025
+ }]
1026
+ }, {
1027
+ "@id": {
1028
+ "@id": "ex:subj",
1029
+ "ex:value": [{
1030
+ "@id": {
1031
+ "@id": "ex:rei",
1032
+ "ex:prop": [{"@value": "value"}]
1033
+ }
1034
+ }]
1035
+ },
1036
+ "ex:certainty": [{"@value": 0.8}]
1037
+ }])
1038
+ },
1039
+ "embedded node used as subject in reverse relationship": {
1040
+ input: %({
1041
+ "@context": {
1042
+ "rel": {"@reverse": "ex:rel"}
1043
+ },
1044
+ "@id": {
1045
+ "@id": "ex:rei",
1046
+ "ex:prop": {"@id": "ex:value"}
1047
+ },
1048
+ "rel": {"@id": "ex:value2"}
1049
+ }),
1050
+ output: %([{
1051
+ "@id": "ex:value2",
1052
+ "ex:rel": [{
1053
+ "@id": {
1054
+ "@id": "ex:rei",
1055
+ "ex:prop": [{"@id": "ex:value"}]
1056
+ }
1057
+ }]
1058
+ }])
1059
+ },
1060
+ "embedded node used as object in reverse relationship": {
1061
+ input: %({
1062
+ "@context": {
1063
+ "rel": {"@reverse": "ex:rel"}
1064
+ },
1065
+ "@id": "ex:subj",
1066
+ "rel": {
1067
+ "@id": {
1068
+ "@id": "ex:rei",
1069
+ "ex:prop": {"@id": "ex:value"}
1070
+ },
1071
+ "ex:prop": {"@id": "ex:value2"}
1072
+ }
1073
+ }),
1074
+ output: %([{
1075
+ "@id": {
1076
+ "@id": "ex:rei",
1077
+ "ex:prop": [{"@id": "ex:value"}]
1078
+ },
1079
+ "ex:rel": [{"@id": "ex:subj"}],
1080
+ "ex:prop": [{"@id": "ex:value2"}]
1081
+ }])
1082
+ },
1083
+ "node with @annotation property on node object with reverse relationship": {
1084
+ input: %({
1085
+ "@context": {
1086
+ "knownBy": {"@reverse": "ex:knows"}
1087
+ },
1088
+ "@id": "ex:bob",
1089
+ "ex:name": "Bob",
1090
+ "knownBy": {
1091
+ "@id": "ex:fred",
1092
+ "ex:name": "Fred",
1093
+ "@annotation": {"ex:certainty": 0.8}
1094
+ }
1095
+ }),
1096
+ output: %([{
1097
+ "@id": "ex:bob",
1098
+ "ex:name": [{"@value": "Bob"}]
1099
+ }, {
1100
+ "@id": "ex:fred",
1101
+ "ex:name": [{"@value": "Fred"}],
1102
+ "ex:knows": [{"@id": "ex:bob"}]
1103
+ }, {
1104
+ "@id": {
1105
+ "@id": "ex:fred",
1106
+ "ex:knows": [{"@id": "ex:bob"}]
1107
+ },
1108
+ "ex:certainty": [{"@value": 0.8}]
1109
+ }])
1110
+ },
1111
+ "reverse relationship inside annotation": {
1112
+ input: %({
1113
+ "@context": {
1114
+ "claims": {"@reverse": "ex:claims", "@type": "@id"}
1115
+ },
1116
+ "@id": "ex:bob",
1117
+ "ex:knows": {
1118
+ "@id": "ex:jane",
1119
+ "@annotation": {
1120
+ "ex:certainty": 0.8,
1121
+ "claims": "ex:sue"
1122
+ }
1123
+ }
1124
+ }),
1125
+ output: %([{
1126
+ "@id": "ex:bob",
1127
+ "ex:knows": [{"@id": "ex:jane"}]
1128
+ }, {
1129
+ "@id": {
1130
+ "@id": "ex:bob",
1131
+ "ex:knows": [{"@id": "ex:jane"}]
1132
+ },
1133
+ "ex:certainty": [{"@value": 0.8}]
1134
+ }, {
1135
+ "@id": "ex:sue",
1136
+ "ex:claims": [{
1137
+ "@id": {
1138
+ "@id": "ex:bob",
1139
+ "ex:knows": [{"@id": "ex:jane"}]
1140
+ }
1141
+ }]
1142
+ }])
1143
+ },
1144
+ "embedded node with annotation on value object": {
1145
+ input: %({
1146
+ "@context": {
1147
+ "@base": "http://example.org/",
1148
+ "@vocab": "http://example.org/",
1149
+ "claims": {"@type": "@id"}
1150
+ },
1151
+ "@id": {
1152
+ "@id": "bob",
1153
+ "knows": {"@id": "alice"}
1154
+ },
1155
+ "certainty": {
1156
+ "@value": 0.8,
1157
+ "@annotation": {"claims": "ted"}
1158
+ }
1159
+ }),
1160
+ output: %([{
1161
+ "@id": {
1162
+ "@id": "http://example.org/bob",
1163
+ "http://example.org/knows": [{"@id": "http://example.org/alice"}]
1164
+ },
1165
+ "http://example.org/certainty": [{"@value": 0.8}]
1166
+ }, {
1167
+ "@id": {
1168
+ "@id": {
1169
+ "@id": "http://example.org/bob",
1170
+ "http://example.org/knows": [{"@id": "http://example.org/alice"}]
1171
+ },
1172
+ "http://example.org/certainty": [{"@value": 0.8}]
1173
+ },
1174
+ "http://example.org/claims": [{"@id": "http://example.org/ted"}]
1175
+ }])
1176
+ }
1177
+ }.each do |title, params|
1178
+ it(title) {run_flatten params.merge(rdfstar: true)}
1179
+ end
1180
+ end
1181
+
668
1182
  def run_flatten(params)
669
1183
  input, output, context = params[:input], params[:output], params[:context]
670
1184
  input = ::JSON.parse(input) if input.is_a?(String)
@@ -681,6 +1195,8 @@ describe JSON::LD::API do
681
1195
  else
682
1196
  expect{jld = JSON::LD::API.flatten(input, context, logger: logger, **params)}.not_to write.to(:error)
683
1197
  end
1198
+
1199
+ jld = remap_bnodes(jld, output) if params[:remap_nodes]
684
1200
  expect(jld).to produce_jsonld(output, logger)
685
1201
  end
686
1202
  end
data/spec/frame_spec.rb CHANGED
@@ -992,6 +992,95 @@ describe JSON::LD::API do
992
992
  end
993
993
  end
994
994
 
995
+ context "omitGraph option" do
996
+ {
997
+ "Defaults to false in 1.0": {
998
+ input: %([{
999
+ "http://example.org/prop": [{"@value": "value"}],
1000
+ "http://example.org/foo": [{"@value": "bar"}]
1001
+ }]),
1002
+ frame: %({
1003
+ "@context": {
1004
+ "@vocab": "http://example.org/"
1005
+ }
1006
+ }),
1007
+ output: %({
1008
+ "@context": {
1009
+ "@vocab": "http://example.org/"
1010
+ },
1011
+ "@graph": [{
1012
+ "foo": "bar",
1013
+ "prop": "value"
1014
+ }]
1015
+ }),
1016
+ processingMode: "json-ld-1.0"
1017
+ },
1018
+ "Set with option in 1.0": {
1019
+ input: %([{
1020
+ "http://example.org/prop": [{"@value": "value"}],
1021
+ "http://example.org/foo": [{"@value": "bar"}]
1022
+ }]),
1023
+ frame: %({
1024
+ "@context": {
1025
+ "@vocab": "http://example.org/"
1026
+ }
1027
+ }),
1028
+ output: %({
1029
+ "@context": {
1030
+ "@vocab": "http://example.org/"
1031
+ },
1032
+ "foo": "bar",
1033
+ "prop": "value"
1034
+ }),
1035
+ processingMode: "json-ld-1.0",
1036
+ omitGraph: true
1037
+ },
1038
+ "Defaults to true in 1.1": {
1039
+ input: %([{
1040
+ "http://example.org/prop": [{"@value": "value"}],
1041
+ "http://example.org/foo": [{"@value": "bar"}]
1042
+ }]),
1043
+ frame: %({
1044
+ "@context": {
1045
+ "@vocab": "http://example.org/"
1046
+ }
1047
+ }),
1048
+ output: %({
1049
+ "@context": {
1050
+ "@vocab": "http://example.org/"
1051
+ },
1052
+ "foo": "bar",
1053
+ "prop": "value"
1054
+ }),
1055
+ processingMode: "json-ld-1.1"
1056
+ },
1057
+ "Set with option in 1.1": {
1058
+ input: %([{
1059
+ "http://example.org/prop": [{"@value": "value"}],
1060
+ "http://example.org/foo": [{"@value": "bar"}]
1061
+ }]),
1062
+ frame: %({
1063
+ "@context": {
1064
+ "@vocab": "http://example.org/"
1065
+ }
1066
+ }),
1067
+ output: %({
1068
+ "@context": {
1069
+ "@vocab": "http://example.org/"
1070
+ },
1071
+ "@graph": [{
1072
+ "foo": "bar",
1073
+ "prop": "value"
1074
+ }]
1075
+ }),
1076
+ processingMode: "json-ld-1.1",
1077
+ omitGraph: false
1078
+ },
1079
+ }.each do |title, params|
1080
+ it(title) {do_frame(params.merge(pruneBlankNodeIdentifiers: true))}
1081
+ end
1082
+ end
1083
+
995
1084
  context "@included" do
996
1085
  {
997
1086
  "Basic Included array": {
@@ -2359,15 +2448,16 @@ describe JSON::LD::API do
2359
2448
 
2360
2449
  def do_frame(params)
2361
2450
  begin
2362
- input, frame, output, processingMode = params[:input], params[:frame], params[:output], params.fetch(:processingMode, 'json-ld-1.0')
2451
+ input, frame, output = params[:input], params[:frame], params[:output]
2452
+ params = {processingMode: 'json-ld-1.0'}.merge(params)
2363
2453
  input = ::JSON.parse(input) if input.is_a?(String)
2364
2454
  frame = ::JSON.parse(frame) if frame.is_a?(String)
2365
2455
  output = ::JSON.parse(output) if output.is_a?(String)
2366
2456
  jld = nil
2367
2457
  if params[:write]
2368
- expect{jld = JSON::LD::API.frame(input, frame, logger: logger, processingMode: processingMode)}.to write(params[:write]).to(:error)
2458
+ expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.to write(params[:write]).to(:error)
2369
2459
  else
2370
- expect{jld = JSON::LD::API.frame(input, frame, logger: logger, processingMode: processingMode)}.not_to write.to(:error)
2460
+ expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.not_to write.to(:error)
2371
2461
  end
2372
2462
  expect(jld).to produce_jsonld(output, logger)
2373
2463
 
@@ -766,7 +766,7 @@ describe JSON::LD::API do
766
766
  end
767
767
  end
768
768
 
769
- context "RDF*" do
769
+ context "RDF-star" do
770
770
  {
771
771
  "subject-iii": {
772
772
  input: RDF::Statement(
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe JSON::LD do
5
+ describe "test suite" do
6
+ require_relative 'suite_helper'
7
+ %w{
8
+ expand
9
+ compact
10
+ flatten
11
+ fromRdf
12
+ toRdf
13
+ }.each do |partial|
14
+ m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STAR_SUITE}#{partial}-manifest.jsonld")
15
+ describe m.name do
16
+ m.entries.each do |t|
17
+ specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
18
+ t.options[:ordered] = false
19
+ expect {t.run self}.not_to write.to(:error)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end unless ENV['CI']