json-ld 3.1.4 → 3.1.9

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