Skip to content

Commit 4528f33

Browse files
committed
Finish 1.1.4
Windows compatibility. Fixed bug in context parsing which removed elements. Made Resource an RDF::Enumerable.
2 parents 31b034a + 044779f commit 4528f33

File tree

8 files changed

+143
-85
lines changed

8 files changed

+143
-85
lines changed

.gemspec

Lines changed: 0 additions & 42 deletions
This file was deleted.

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
source "https://rubygems.org"
22

3-
gemspec :name => ""
3+
gemspec
44
gem 'rdf', :git => "git://github.com/ruby-rdf/rdf.git", :branch => "develop"
55
gem 'rdf-spec', :git => "git://github.com/ruby-rdf/rdf-spec.git", :branch => "develop"
66

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ To get a local working copy of the development repository, do:
268268
* Don't use hard tabs, and don't leave trailing whitespace on any line.
269269
* Do document every method you add using [YARD][] annotations. Read the
270270
[tutorial][YARD-GS] or just look at the existing code for examples.
271-
* Don't touch the `.gemspec`, `VERSION` or `AUTHORS` files. If you need to
271+
* Don't touch the `json-ld.gemspec`, `VERSION` or `AUTHORS` files. If you need to
272272
change them, do so on your private branch only.
273273
* Do feel free to add yourself to the `CREDITS` file and the corresponding
274274
list in the the `README`. Alphabetical order applies.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.3.1
1+
1.1.4

json-ld.gemspec

Lines changed: 0 additions & 1 deletion
This file was deleted.

json-ld.gemspec

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env ruby -rubygems
2+
# -*- encoding: utf-8 -*-
3+
4+
Gem::Specification.new do |gem|
5+
gem.version = File.read('VERSION').chomp
6+
gem.date = File.mtime('VERSION').strftime('%Y-%m-%d')
7+
8+
gem.name = "json-ld"
9+
gem.homepage = "http://github.com/ruby-rdf/json-ld"
10+
gem.license = 'Public Domain' if gem.respond_to?(:license=)
11+
gem.summary = "JSON-LD reader/writer for Ruby."
12+
gem.description = "JSON::LD parses and serializes JSON-LD into RDF and implements expansion, compaction and framing API interfaces."
13+
gem.rubyforge_project = 'json-ld'
14+
15+
gem.authors = ['Gregg Kellogg']
16+
gem.email = 'public-linked-json@w3.org'
17+
18+
gem.platform = Gem::Platform::RUBY
19+
gem.files = %w(AUTHORS README.md UNLICENSE VERSION) + Dir.glob('lib/**/*.rb')
20+
gem.bindir = %q(bin)
21+
gem.executables = %w(jsonld)
22+
gem.default_executable = gem.executables.first
23+
gem.require_paths = %w(lib)
24+
gem.extensions = %w()
25+
gem.test_files = Dir.glob('spec/**/*.rb') + Dir.glob('spec/test-files/*')
26+
gem.has_rdoc = false
27+
28+
gem.required_ruby_version = '>= 1.9.2'
29+
gem.requirements = []
30+
gem.add_runtime_dependency 'rdf', '~> 1.1'
31+
gem.add_development_dependency 'equivalent-xml' , '~> 0.4'
32+
gem.add_development_dependency 'open-uri-cached', '~> 0.0', '>= 0.0.5'
33+
gem.add_development_dependency 'yard' , '~> 0.8'
34+
gem.add_development_dependency 'rspec', '~> 2.14'
35+
gem.add_development_dependency 'rdf-spec', '~> 1.1'
36+
gem.add_development_dependency 'rdf-turtle', '~> 1.1'
37+
gem.add_development_dependency 'rdf-trig', '~> 1.1'
38+
gem.add_development_dependency 'rdf-isomorphic', '~> 1.1'
39+
gem.add_development_dependency 'rdf-xsd', '~> 1.1'
40+
41+
gem.post_install_message = nil
42+
end

lib/json/ld/context.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ def parse(local_context, remote_contexts = [])
295295
debug("parse") {"=> provided_context: #{context.inspect}"}
296296
when Hash
297297
# If context has a @vocab member: if its value is not a valid absolute IRI or null trigger an INVALID_VOCAB_MAPPING error; otherwise set the active context's vocabulary mapping to its value and remove the @vocab member from context.
298+
context = context.dup # keep from modifying a hash passed as a param
298299
{
299300
'@base' => :base=,
300301
'@language' => :default_language=,

lib/json/ld/resource.rb

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,59 @@ module JSON::LD
22
# Simple Ruby reflector class to provide native
33
# access to JSON-LD objects
44
class Resource
5-
# @!attribute [r] attributes
5+
include RDF::Enumerable
6+
67
# @return [Hash<String => Object] Object representation of resource
78
attr_reader :attributes
89

9-
# @!attribute [r] id
1010
# @return [String] ID of this resource
1111
attr_reader :id
1212

13-
# @!attribute [r] context
1413
# @return [JSON::LD::Context] Context associated with this resource
1514
attr_reader :context
1615

16+
##
1717
# Is this resource clean (i.e., saved to mongo?)
1818
#
1919
# @return [Boolean]
2020
def clean?; @clean; end
2121

22+
##
2223
# Is this resource dirty (i.e., not yet saved to mongo?)
2324
#
2425
# @return [Boolean]
2526
def dirty?; !clean?; end
26-
27+
28+
##
2729
# Has this resource been reconciled against a mongo ID?
2830
#
2931
# @return [Boolean]
3032
def reconciled?; @reconciled; end
3133

34+
##
3235
# Has this resource been resolved so that
3336
# all references are to other Resources?
3437
#
3538
# @return [Boolean]
3639
def resolved?; @resolved; end
3740

41+
##
3842
# Anonymous resources have BNode ids or no schema:url
3943
#
4044
# @return [Boolean]
4145
def anonymous?; @anon; end
4246

47+
##
4348
# Is this a stub resource, which has not yet been
4449
# synched or created within the DB?
4550
def stub?; !!@stub; end
4651

52+
##
4753
# Is this a new resource, which has not yet been
4854
# synched or created within the DB?
4955
def new?; !!@new; end
5056

51-
# Manage contexts used by resources.
52-
#
53-
# @param [String] ctx
54-
# @return [JSON::LD::Context]
55-
def self.set_context(ctx)
56-
(@@contexts ||= {})[ctx] = JSON::LD::Context.new.parse(ctx)
57-
end
58-
57+
##
5958
# A new resource from the parsed graph
6059
# @param [Hash{String => Object}] node_definition
6160
# @param [Hash{Symbol => Object}] options
@@ -76,8 +75,7 @@ def self.set_context(ctx)
7675
# This is a stand-in for another resource that has
7776
# not yet been retrieved (or created) from Mongo
7877
def initialize(node_definition, options = {})
79-
@context_name = options[:context]
80-
@context = self.class.set_context(@context_name)
78+
@context = options[:context]
8179
@clean = options.fetch(:clean, false)
8280
@new = options.fetch(:new, true)
8381
@reconciled = options.fetch(:reconciled, !@new)
@@ -91,12 +89,14 @@ def initialize(node_definition, options = {})
9189
@anon = @id.nil? || @id.to_s[0,2] == '_:'
9290
end
9391

92+
##
9493
# Return a hash of this object, suitable for use by for ETag
9594
# @return [Fixnum]
9695
def hash
9796
self.deresolve.hash
9897
end
9998

99+
##
100100
# Reverse resolution of resource attributes.
101101
# Just returns `attributes` if
102102
# resource is unresolved. Otherwise, replaces `Resource`
@@ -134,6 +134,7 @@ def deresolve
134134
compacted.delete_if {|k, v| k == '@context'}
135135
end
136136

137+
##
137138
# Serialize to JSON-LD, minus `@context` using
138139
# a deresolved version of the attributes
139140
#
@@ -143,6 +144,13 @@ def to_json(options = nil)
143144
deresolve.to_json(options)
144145
end
145146

147+
##
148+
# Enumerate over statements associated with this resource
149+
def each(&block)
150+
JSON::LD::API.toRdf(attributes, expandContext: context, &block)
151+
end
152+
153+
##
146154
# Update node references using the provided map.
147155
# This replaces node references with Resources,
148156
# either stub or instantiated.
@@ -186,29 +194,7 @@ def update_obj(obj, reference_map)
186194
self
187195
end
188196

189-
# Merge resources
190-
# FIXME: If unreconciled or unresolved resources are merged
191-
# against reconciled/resolved resources, they will appear
192-
# to not match, even if they are really the same thing.
193-
#
194-
# @param [Resource] resource
195-
# @return [Resource] self
196-
def merge(resource)
197-
if attributes.neq?(resource.attributes)
198-
resource.attributes.each do |p, v|
199-
next if p == 'id'
200-
if v.nil? or (v.is_a?(Array) and v.empty?)
201-
attributes.delete(p)
202-
else
203-
attributes[p] = v
204-
end
205-
end
206-
@resolved = @clean = false
207-
end
208-
self
209-
end
210-
211-
#
197+
##
212198
# Override this method to implement save using
213199
# an appropriate storage mechanism.
214200
#
@@ -218,12 +204,14 @@ def merge(resource)
218204
#
219205
# @return [Boolean] true or false if resource not saved
220206
def save
221-
raise NotImplemented
207+
raise NotImplementedError
222208
end
223209

210+
##
224211
# Access individual fields, from subject definition
225212
def property(prop_name); @attributes.fetch(prop_name, nil); end
226213

214+
##
227215
# Access individual fields, from subject definition
228216
def method_missing(method, *args)
229217
property(method.to_s)

spec/resource_spec.rb

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,75 @@
33
require 'spec_helper'
44

55
describe JSON::LD::Resource do
6-
it "is pending"
6+
subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"})}
7+
describe "#initialize" do
8+
specify {expect(subject).not_to be_nil}
9+
specify {expect(subject).to be_a(JSON::LD::Resource)}
10+
specify {expect(subject).not_to be_clean}
11+
specify {expect(subject).to be_anonymous}
12+
specify {expect(subject).to be_dirty}
13+
specify {expect(subject).to be_new}
14+
specify {expect(subject).not_to be_resolved}
15+
specify {expect(subject).not_to be_stub}
16+
context "schema:name property" do
17+
specify {expect(subject.property("http://schema.org/name")).to eq "foo"}
18+
end
19+
20+
describe "compacted with context" do
21+
subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"}, :compact => true, :context => {"@vocab" => "http://schema.org/"})}
22+
specify {expect(subject).not_to be_nil}
23+
specify {expect(subject).to be_a(JSON::LD::Resource)}
24+
specify {expect(subject).not_to be_clean}
25+
specify {expect(subject).to be_anonymous}
26+
specify {expect(subject).to be_dirty}
27+
specify {expect(subject).to be_new}
28+
specify {expect(subject).not_to be_resolved}
29+
specify {expect(subject).not_to be_stub}
30+
its(:name) {should eq "foo"}
31+
end
32+
end
33+
34+
describe "#deresolve" do
35+
it "FIXME"
36+
end
37+
38+
describe "#resolve" do
39+
it "FIXME"
40+
end
41+
42+
describe "#hash" do
43+
specify {subject.hash.should be_a(Fixnum)}
44+
45+
it "returns the hash of the attributes" do
46+
subject.hash.should == subject.deresolve.hash
47+
end
48+
end
49+
50+
describe "#to_json" do
51+
it "has JSON" do
52+
subject.to_json.should be_a(String)
53+
JSON.parse(subject.to_json).should be_a(Hash)
54+
end
55+
it "has same ID" do
56+
JSON.parse(subject.to_json)['@id'].should == subject.id
57+
end
58+
end
59+
60+
describe "#each" do
61+
specify {expect {|b| subject.each(&b)}.to yield_with_args(RDF::Statement)}
62+
end
63+
64+
describe RDF::Enumerable do
65+
specify {expect(subject).to be_enumerable}
66+
67+
it "initializes a graph" do
68+
g = RDF::Graph.new << subject
69+
expect(g.count).to eq 1
70+
expect(g.objects.first).to eq "foo"
71+
end
72+
end
73+
74+
describe "#save" do
75+
specify {expect {subject.save}.to raise_error(NotImplementedError)}
76+
end
777
end

0 commit comments

Comments
 (0)