json-ld 3.1.7 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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']