json-ld 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ require 'rspec/matchers' # @see http://rubygems.org/gems/rspec
2
+ require_relative 'support/extensions'
3
+
4
+ RSpec::Matchers.define :produce_jsonld do |expected, logger|
5
+ match do |actual|
6
+ expect(actual).to be_equivalent_jsonld expected
7
+ end
8
+
9
+ failure_message do |actual|
10
+ "Expected: #{expected.is_a?(String) ? expected : expected.to_json(JSON_STATE) rescue 'malformed json'}\n" +
11
+ "Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" +
12
+ "\nDebug:\n#{logger}"
13
+ end
14
+
15
+ failure_message_when_negated do |actual|
16
+ "Expected not to produce the following:\n" +
17
+ "Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" +
18
+ "\nDebug:\n#{logger}"
19
+ end
20
+ end
@@ -11,6 +11,7 @@ require 'rdf/trig'
11
11
  require 'rdf/vocab'
12
12
  require 'rdf/spec'
13
13
  require 'rdf/spec/matchers'
14
+ require_relative 'matchers'
14
15
  require 'yaml'
15
16
  begin
16
17
  require 'simplecov'
@@ -17,7 +17,7 @@ describe JSON::LD::StreamingWriter do
17
17
  input = %(<http://a/b> <http://a/c> <http://a/d> .)
18
18
  obj = serialize(input)
19
19
  expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse(input), logger: logger)
20
- expect(obj).to produce([{
20
+ expect(obj).to produce_jsonld([{
21
21
  '@id' => "http://a/b",
22
22
  "http://a/c" => [{"@id" => "http://a/d"}]
23
23
  }], logger)
@@ -7,7 +7,13 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}compact-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
11
17
  t.run self
12
18
  end
13
19
  end
@@ -7,7 +7,13 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}expand-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
11
17
  t.run self
12
18
  end
13
19
  end
@@ -7,8 +7,13 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}flatten-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
11
- pending "context corner-case" if t.input_loc.end_with?('flatten-0044-in.jsonld')
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
12
17
  t.run self
13
18
  end
14
19
  end
@@ -7,10 +7,16 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::FRAME_SUITE}frame-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
11
17
  t.run self
12
18
  end
13
19
  end
14
20
  end
15
21
  end
16
- end unless ENV['CI'] || true
22
+ end unless ENV['CI']
@@ -7,7 +7,13 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
11
17
  t.run self
12
18
  end
13
19
  end
@@ -1,5 +1,4 @@
1
1
  require 'json/ld'
2
- require_relative 'support/extensions'
3
2
 
4
3
  # For now, override RDF::Utils::File.open_file to look for the file locally before attempting to retrieve it
5
4
  module RDF::Util
@@ -72,37 +71,50 @@ module Fixtures
72
71
  FRAME_SUITE = RDF::URI("https://w3c.github.io/json-ld-framing/tests/")
73
72
 
74
73
  class Manifest < JSON::LD::Resource
74
+ attr_accessor :manifest_url
75
+
75
76
  def self.open(file)
76
77
  RDF::Util::File.open_file(file) do |remote|
77
78
  json = JSON.parse(remote.read)
78
79
  if block_given?
79
- yield self.from_jsonld(json)
80
+ yield self.from_jsonld(json, manifest_url: RDF::URI(file))
80
81
  else
81
- self.from_jsonld(json)
82
+ self.from_jsonld(json, manifest_url: RDF::URI(file))
82
83
  end
83
84
  end
84
85
  end
85
86
 
87
+ def initialize(json, manifest_url:)
88
+ @manifest_url = manifest_url
89
+ super
90
+ end
91
+
86
92
  # @param [Hash] json framed JSON-LD
87
93
  # @return [Array<Manifest>]
88
- def self.from_jsonld(json)
89
- Manifest.new(json)
94
+ def self.from_jsonld(json, manifest_url: )
95
+ Manifest.new(json, manifest_url: manifest_url)
90
96
  end
91
97
 
92
98
  def entries
93
99
  # Map entries to resources
94
100
  attributes['sequence'].map do |e|
95
- e.is_a?(String) ? Manifest.open("#{SUITE}#{e}") : Entry.new(e)
101
+ e.is_a?(String) ? Manifest.open(manifest_url.join(e).to_s) : Entry.new(e, manifest_url: manifest_url)
96
102
  end
97
103
  end
98
104
  end
99
105
 
100
106
  class Entry < JSON::LD::Resource
101
107
  attr_accessor :logger
108
+ attr_accessor :manifest_url
109
+
110
+ def initialize(json, manifest_url:)
111
+ @manifest_url = manifest_url
112
+ super
113
+ end
102
114
 
103
115
  # Base is expanded input file
104
116
  def base
105
- options.fetch('base', "#{SUITE}#{property('input')}")
117
+ options.fetch('base', manifest_url.join(property('input')).to_s)
106
118
  end
107
119
 
108
120
  def options
@@ -138,7 +150,7 @@ module Fixtures
138
150
  file = options[:redirectTo]
139
151
  end
140
152
 
141
- property(m) && "#{SUITE}#{file}"
153
+ property(m) && manifest_url.join(file).to_s
142
154
  end
143
155
 
144
156
  define_method("#{m}_json".to_sym) do
@@ -155,7 +167,7 @@ module Fixtures
155
167
  end
156
168
 
157
169
  def positiveTest?
158
- property('@type').include?('jld:PositiveEvaluationTest')
170
+ property('@type').to_s.include?('Positive')
159
171
  end
160
172
 
161
173
 
@@ -214,9 +226,27 @@ module Fixtures
214
226
  }
215
227
  else
216
228
  expected = JSON.load(expect)
217
- rspec_example.instance_eval {
218
- expect(result).to produce(expected, logger)
219
- }
229
+ if options[:ordered]
230
+ # Compare without transformation
231
+ rspec_example.instance_eval {
232
+ expect(result).to produce(expected, logger)
233
+ }
234
+ else
235
+ # Without key ordering, reorder result and expected embedded array values and compare
236
+ # If results are compacted, expand both, reorder and re-compare
237
+ rspec_example.instance_eval {
238
+ expect(result).to produce_jsonld(expected, logger)
239
+ }
240
+
241
+ # If results are compacted, expand both, reorder and re-compare
242
+ if result.to_s.include?('@context')
243
+ exp_expected = JSON::LD::API.expand(expected, **options)
244
+ exp_result = JSON::LD::API.expand(result, **options)
245
+ rspec_example.instance_eval {
246
+ expect(exp_result).to produce_jsonld(exp_expected, logger)
247
+ }
248
+ end
249
+ end
220
250
  end
221
251
  else
222
252
  rspec_example.instance_eval {
@@ -7,7 +7,13 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}remote-doc-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
- specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
10
+ specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
+ t.options[:ordered] = false
12
+ t.run self
13
+ end
14
+
15
+ specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
+ t.options[:ordered] = true
11
17
  t.run self
12
18
  end
13
19
  end
@@ -1,4 +1,18 @@
1
+ class Object
2
+ def equivalent_jsonld?(other, ordered: false)
3
+ self == other
4
+ end
5
+ end
6
+
1
7
  class Hash
8
+ def equivalent_jsonld?(other, ordered: false)
9
+ return false unless other.is_a?(Hash) && other.length == length
10
+ all? do |key, value|
11
+ # List values are still ordered
12
+ value.equivalent_jsonld?(other[key], ordered: key == '@list')
13
+ end
14
+ end
15
+
2
16
  def diff(other)
3
17
  self.keys.inject({}) do |memo, key|
4
18
  unless self[key] == other[key]
@@ -7,4 +21,20 @@ class Hash
7
21
  memo
8
22
  end
9
23
  end
10
- end
24
+ end
25
+
26
+ class Array
27
+ def equivalent_jsonld?(other, ordered: false)
28
+ return false unless other.is_a?(Array) && other.length == length
29
+ if ordered
30
+ b = other.dup
31
+ # All elements must match in order
32
+ all? {|av| av.equivalent_jsonld?(b.shift)}
33
+ else
34
+ # Look for any element which matches
35
+ all? do |av|
36
+ other.any? {|bv| av.equivalent_jsonld?(bv)}
37
+ end
38
+ end
39
+ end
40
+ end
@@ -29,7 +29,7 @@ describe JSON::LD::Writer do
29
29
  context "simple tests" do
30
30
  it "should use full URIs without base" do
31
31
  input = %(<http://a/b> <http://a/c> <http://a/d> .)
32
- expect(serialize(input)).to produce([{
32
+ expect(serialize(input)).to produce_jsonld([{
33
33
  '@id' => "http://a/b",
34
34
  "http://a/c" => [{"@id" => "http://a/d"}]
35
35
  }], logger)
@@ -37,7 +37,7 @@ describe JSON::LD::Writer do
37
37
 
38
38
  it "should use qname URIs with standard prefix" do
39
39
  input = %(<http://xmlns.com/foaf/0.1/b> <http://xmlns.com/foaf/0.1/c> <http://xmlns.com/foaf/0.1/d> .)
40
- expect(serialize(input, standard_prefixes: true)).to produce({
40
+ expect(serialize(input, standard_prefixes: true)).to produce_jsonld({
41
41
  '@context' => {
42
42
  "foaf" => "http://xmlns.com/foaf/0.1/",
43
43
  },
@@ -57,7 +57,7 @@ describe JSON::LD::Writer do
57
57
  dc: "http://purl.org/dc/terms/",
58
58
  frbr: "http://vocab.org/frbr/core#",
59
59
  senet: "https://senet.org/ns#",
60
- })).to produce({
60
+ })).to produce_jsonld({
61
61
  '@context' => {
62
62
  "dc" => "http://purl.org/dc/terms/",
63
63
  "frbr" => "http://vocab.org/frbr/core#",
@@ -75,7 +75,7 @@ describe JSON::LD::Writer do
75
75
  input = %(<http://xmlns.com/foaf/0.1/b> <http://xmlns.com/foaf/0.1/c> <http://xmlns.com/foaf/0.1/d> .)
76
76
  begin
77
77
  expect(serialize(input, prefixes: { "" => RDF::Vocab::FOAF})).
78
- to produce({
78
+ to produce_jsonld({
79
79
  "@context" => {
80
80
  "" => "http://xmlns.com/foaf/0.1/"
81
81
  },
@@ -92,7 +92,7 @@ describe JSON::LD::Writer do
92
92
  it "should not use terms if no suffix" do
93
93
  input = %(<http://xmlns.com/foaf/0.1/> <http://xmlns.com/foaf/0.1/> <http://xmlns.com/foaf/0.1/> .)
94
94
  expect(serialize(input, standard_prefixes: true)).
95
- not_to produce({
95
+ not_to produce_jsonld({
96
96
  "@context" => {"foaf" => "http://xmlns.com/foaf/0.1/"},
97
97
  '@id' => "foaf",
98
98
  "foaf" => {"@id" => "foaf"}
@@ -109,7 +109,7 @@ describe JSON::LD::Writer do
109
109
  expect(serialize(input, prefixes: {
110
110
  "db" => RDF::URI("http://dbpedia.org/resource/"),
111
111
  "dbo" => RDF::URI("http://dbpedia.org/ontology/")})).
112
- to produce({
112
+ to produce_jsonld({
113
113
  "@context" => {
114
114
  "db" => "http://dbpedia.org/resource/",
115
115
  "dbo" => "http://dbpedia.org/ontology/"
@@ -133,7 +133,7 @@ describe JSON::LD::Writer do
133
133
  <http://example.com/test-cases/0002> a :TestCase .
134
134
  )
135
135
  expect(serialize(input, prefixes: {"" => "http://www.w3.org/2006/03/test-description#"})).
136
- to produce({
136
+ to produce_jsonld({
137
137
  '@context' => {
138
138
  "" => "http://www.w3.org/2006/03/test-description#",
139
139
  "dc" => RDF::Vocab::DC.to_s
@@ -164,7 +164,7 @@ describe JSON::LD::Writer do
164
164
  rdfs: "http://www.w3.org/2000/01/rdf-schema#",
165
165
  xsd: "http://www.w3.org/2001/XMLSchema#"
166
166
  })).
167
- to produce({
167
+ to produce_jsonld({
168
168
  '@context' => {
169
169
  "owl" => "http://www.w3.org/2002/07/owl#",
170
170
  "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-17 00:00:00.000000000 Z
11
+ date: 2018-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -286,6 +286,7 @@ files:
286
286
  - spec/format_spec.rb
287
287
  - spec/frame_spec.rb
288
288
  - spec/from_rdf_spec.rb
289
+ - spec/matchers.rb
289
290
  - spec/reader_spec.rb
290
291
  - spec/resource_spec.rb
291
292
  - spec/spec_helper.rb
@@ -376,6 +377,7 @@ specification_version: 4
376
377
  summary: JSON-LD reader/writer for Ruby.
377
378
  test_files:
378
379
  - spec/spec_helper.rb
380
+ - spec/matchers.rb
379
381
  - spec/api_spec.rb
380
382
  - spec/suite_from_rdf_spec.rb
381
383
  - spec/context_spec.rb