rdf-spec 1.99.0 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/{README → README.md} +2 -0
- data/VERSION +1 -1
- data/lib/rdf/spec.rb +18 -0
- data/lib/rdf/spec/countable.rb +5 -28
- data/lib/rdf/spec/dataset.rb +47 -0
- data/lib/rdf/spec/durable.rb +8 -23
- data/lib/rdf/spec/enumerable.rb +118 -102
- data/lib/rdf/spec/format.rb +4 -26
- data/lib/rdf/spec/http_adapter.rb +1 -23
- data/lib/rdf/spec/indexable.rb +1 -23
- data/lib/rdf/spec/inferable.rb +0 -16
- data/lib/rdf/spec/inspects.rb +4 -5
- data/lib/rdf/spec/matchers.rb +95 -4
- data/lib/rdf/spec/mutable.rb +227 -81
- data/lib/rdf/spec/queryable.rb +122 -165
- data/lib/rdf/spec/readable.rb +0 -22
- data/lib/rdf/spec/reader.rb +21 -29
- data/lib/rdf/spec/repository.rb +80 -40
- data/lib/rdf/spec/transactable.rb +43 -0
- data/lib/rdf/spec/transaction.rb +294 -71
- data/lib/rdf/spec/version.rb +2 -2
- data/lib/rdf/spec/writable.rb +78 -100
- data/lib/rdf/spec/writer.rb +51 -28
- data/spec/countable_spec.rb +11 -0
- data/spec/dataset_spec.rb +14 -0
- data/spec/durable_spec.rb +12 -0
- data/spec/enumerable_spec.rb +11 -0
- data/spec/format_spec.rb +12 -0
- data/spec/http_adapter_spec.rb +15 -0
- data/spec/indexable.rb +15 -0
- data/spec/literal_spec.rb +75 -0
- data/spec/mutable_spec.rb +11 -0
- data/spec/queryable_spec.rb +13 -0
- data/spec/readable.rb +11 -0
- data/spec/reader_spec.rb +17 -0
- data/spec/repository_spec.rb +11 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/transaction_spec.rb +7 -0
- data/spec/version_spec.rb +2 -0
- data/spec/writable_spec.rb +13 -0
- data/spec/writer_spec.rb +11 -0
- metadata +56 -12
data/lib/rdf/spec/version.rb
CHANGED
@@ -13,7 +13,7 @@ module RDF; module Spec
|
|
13
13
|
def self.to_str() STRING end
|
14
14
|
|
15
15
|
##
|
16
|
-
# @return [Array(
|
17
|
-
def self.to_a()
|
16
|
+
# @return [Array(String, String, String, String)]
|
17
|
+
def self.to_a() STRING.split(".") end
|
18
18
|
end
|
19
19
|
end; end
|
data/lib/rdf/spec/writable.rb
CHANGED
@@ -5,10 +5,12 @@ RSpec.shared_examples 'an RDF::Writable' do
|
|
5
5
|
let(:filename) {RDF::Spec::TRIPLES_FILE}
|
6
6
|
let(:statements) {RDF::NTriples::Reader.new(File.open(filename)).to_a}
|
7
7
|
let(:supports_graph_name) {writable.respond_to?(:supports?) && writable.supports?(:graph_name)}
|
8
|
+
let(:supports_literal_equality) {writable.respond_to?(:supports?) && writable.supports?(:literal_equality)}
|
8
9
|
|
9
10
|
before :each do
|
10
|
-
raise 'writable must be defined in with let(:
|
11
|
+
raise 'writable must be defined in with let(:writable)' unless
|
11
12
|
defined? writable
|
13
|
+
skip "Unwritable resource" unless writable.respond_to?(:writable?) && writable.writable?
|
12
14
|
end
|
13
15
|
|
14
16
|
subject { writable }
|
@@ -20,152 +22,128 @@ RSpec.shared_examples 'an RDF::Writable' do
|
|
20
22
|
|
21
23
|
describe "#<<" do
|
22
24
|
it "inserts a reader" do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(subject.count).to eq count
|
28
|
-
end
|
25
|
+
reader = RDF::NTriples::Reader.new(File.open(filename)).to_a
|
26
|
+
subject << reader
|
27
|
+
is_expected.to have_statement(statement)
|
28
|
+
expect(subject.count).to eq count
|
29
29
|
end
|
30
30
|
|
31
31
|
it "inserts a graph" do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
expect(subject.count).to eq count
|
37
|
-
end
|
32
|
+
graph = RDF::Graph.new << statements
|
33
|
+
subject << graph
|
34
|
+
is_expected.to have_statement(statement)
|
35
|
+
expect(subject.count).to eq count
|
38
36
|
end
|
39
37
|
|
40
38
|
it "inserts an enumerable" do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect(subject.count).to eq count
|
46
|
-
end
|
39
|
+
enumerable = statements.dup.extend(RDF::Enumerable)
|
40
|
+
subject << enumerable
|
41
|
+
is_expected.to have_statement(statement)
|
42
|
+
expect(subject.count).to eq count
|
47
43
|
end
|
48
44
|
|
49
45
|
it "inserts data responding to #to_rdf" do
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
expect(subject.count).to eq count
|
56
|
-
end
|
46
|
+
mock = double('mock')
|
47
|
+
allow(mock).to receive(:to_rdf).and_return(statements)
|
48
|
+
subject << mock
|
49
|
+
is_expected.to have_statement(statement)
|
50
|
+
expect(subject.count).to eq count
|
57
51
|
end
|
58
52
|
|
59
53
|
it "inserts a statement" do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
expect(subject.count).to eq 1
|
64
|
-
end
|
54
|
+
subject << statement
|
55
|
+
is_expected.to have_statement(statement)
|
56
|
+
expect(subject.count).to eq 1
|
65
57
|
end
|
66
58
|
end
|
67
59
|
|
68
60
|
context "when inserting statements" do
|
69
61
|
it "should support #insert" do
|
70
|
-
is_expected.to respond_to(:insert)
|
62
|
+
is_expected.to respond_to(:insert)
|
71
63
|
end
|
72
64
|
|
73
65
|
it "should not raise errors" do
|
74
|
-
expect { subject.insert(statement) }.not_to raise_error
|
66
|
+
expect { subject.insert(statement) }.not_to raise_error
|
75
67
|
end
|
76
68
|
|
77
69
|
it "should support inserting one statement at a time" do
|
78
|
-
|
79
|
-
|
80
|
-
is_expected.to have_statement(statement)
|
81
|
-
end
|
70
|
+
subject.insert(statement)
|
71
|
+
is_expected.to have_statement(statement)
|
82
72
|
end
|
83
73
|
|
84
74
|
it "should support inserting multiple statements at a time" do
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
is_expected.to have_statement(statement) unless statement.to_a.any?(&:node?)
|
89
|
-
end
|
75
|
+
subject.insert(*statements)
|
76
|
+
statements.each do |statement|
|
77
|
+
is_expected.to have_statement(statement) unless statement.to_a.any?(&:node?)
|
90
78
|
end
|
91
79
|
end
|
92
80
|
|
93
81
|
it "should insert statements successfully" do
|
94
|
-
|
95
|
-
|
96
|
-
expect(subject.count).to eq count
|
97
|
-
end
|
82
|
+
subject.insert(*statements)
|
83
|
+
expect(subject.count).to eq count
|
98
84
|
end
|
99
85
|
|
100
86
|
it "should not insert a statement twice" do
|
87
|
+
subject.insert(statement)
|
88
|
+
subject.insert(statement)
|
89
|
+
expect(subject.count).to eq 1
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should insert statement with literal with unique language" do
|
101
93
|
if subject.writable?
|
94
|
+
statement.object = RDF::Literal('abc', language: 'en')
|
102
95
|
subject.insert(statement)
|
96
|
+
|
97
|
+
statement.object = RDF::Literal('abc', language: 'fi')
|
103
98
|
subject.insert(statement)
|
104
|
-
expect(subject.count).to eq 1
|
105
|
-
end
|
106
|
-
end
|
107
99
|
|
108
|
-
|
109
|
-
if subject.writable?
|
110
|
-
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(subject: nil)))}.to raise_error(ArgumentError)
|
111
|
-
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(predicate: nil)))}.to raise_error(ArgumentError)
|
112
|
-
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(object: nil)))}.to raise_error(ArgumentError)
|
113
|
-
expect(subject.count).to eql 0
|
100
|
+
expect(subject.count).to eq 2
|
114
101
|
end
|
115
102
|
end
|
116
103
|
|
117
|
-
it "should
|
118
|
-
if subject.writable?
|
119
|
-
|
120
|
-
|
121
|
-
s2 = statement.dup
|
122
|
-
s2.context = RDF::URI.new("urn:context:1")
|
123
|
-
s3 = statement.dup
|
124
|
-
s3.context = RDF::URI.new("urn:context:2")
|
125
|
-
subject.insert(s1)
|
126
|
-
subject.insert(s2)
|
127
|
-
subject.insert(s3)
|
128
|
-
# If contexts are not suported, all three are redundant
|
129
|
-
expect(subject.count).to eq (supports_graph_name ? 3 : 1)
|
130
|
-
end
|
131
|
-
end
|
104
|
+
it "should insert statement with literal with unique datatype" do
|
105
|
+
if subject.writable? && supports_literal_equality
|
106
|
+
statement.object = RDF::Literal::Decimal.new(1)
|
107
|
+
subject.insert(statement)
|
132
108
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
s2 = statement.dup
|
138
|
-
s2.graph_name = RDF::URI.new("urn:context:1")
|
139
|
-
s3 = statement.dup
|
140
|
-
s3.graph_name = RDF::URI.new("urn:context:2")
|
141
|
-
subject.insert(s1)
|
142
|
-
subject.insert(s2)
|
143
|
-
subject.insert(s3)
|
144
|
-
# If graph_names are not suported, all three are redundant
|
145
|
-
expect(subject.count).to eq (supports_graph_name ? 3 : 1)
|
109
|
+
statement.object = RDF::Literal::Integer.new(1)
|
110
|
+
subject.insert(statement)
|
111
|
+
|
112
|
+
expect(subject.count).to eq 2
|
146
113
|
end
|
147
114
|
end
|
148
|
-
end
|
149
|
-
end
|
150
115
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
include RDF::Spec::Matchers
|
156
|
-
|
157
|
-
def self.included(mod)
|
158
|
-
warn "[DEPRECATION] `RDF_Writable` is deprecated. "\
|
159
|
-
"Please use `it_behaves_like 'an RDF::Writable'`"
|
160
|
-
end
|
116
|
+
it 'inserts literal with unique lexical value' do
|
117
|
+
if subject.writable? && supports_literal_equality
|
118
|
+
statement.object = RDF::Literal::Integer.new("1")
|
119
|
+
subject.insert(statement)
|
161
120
|
|
162
|
-
|
163
|
-
|
164
|
-
let(:writable) { @writable }
|
121
|
+
statement.object = RDF::Literal::Integer.new("01")
|
122
|
+
subject.insert(statement)
|
165
123
|
|
166
|
-
|
167
|
-
raise '@writable must be defined' unless defined?(writable)
|
124
|
+
expect(subject.count).to eq 2
|
168
125
|
end
|
169
126
|
end
|
127
|
+
|
128
|
+
it "should not insert an incomplete statement" do
|
129
|
+
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(subject: nil)))}.to raise_error(ArgumentError)
|
130
|
+
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(predicate: nil)))}.to raise_error(ArgumentError)
|
131
|
+
expect {subject.insert(RDF::Statement.from(statement.to_hash.merge(object: nil)))}.to raise_error(ArgumentError)
|
132
|
+
expect(subject.count).to eql 0
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should treat statements with a different graph_name as distinct" do
|
136
|
+
s1 = statement.dup
|
137
|
+
s1.graph_name = nil
|
138
|
+
s2 = statement.dup
|
139
|
+
s2.graph_name = RDF::URI.new("urn:context:1")
|
140
|
+
s3 = statement.dup
|
141
|
+
s3.graph_name = RDF::URI.new("urn:context:2")
|
142
|
+
subject.insert(s1)
|
143
|
+
subject.insert(s2)
|
144
|
+
subject.insert(s3)
|
145
|
+
# If graph_names are not suported, all three are redundant
|
146
|
+
expect(subject.count).to eq (supports_graph_name ? 3 : 1)
|
147
|
+
end
|
170
148
|
end
|
171
149
|
end
|
data/lib/rdf/spec/writer.rb
CHANGED
@@ -10,6 +10,7 @@ RSpec.shared_examples 'an RDF::Writer' do
|
|
10
10
|
defined? writer
|
11
11
|
end
|
12
12
|
let(:writer_class) { writer.class }
|
13
|
+
let(:reader_class) { writer_class.format.reader}
|
13
14
|
|
14
15
|
describe ".each" do
|
15
16
|
it "yields each writer" do
|
@@ -26,6 +27,28 @@ RSpec.shared_examples 'an RDF::Writer' do
|
|
26
27
|
expect(r).to be_a(writer_class)
|
27
28
|
end
|
28
29
|
end
|
30
|
+
|
31
|
+
it "should serialize different BNodes sharing a common identifier to using different BNode ids" do
|
32
|
+
if reader_class
|
33
|
+
n1 = RDF::Node("a")
|
34
|
+
n2 = RDF::Node("a")
|
35
|
+
p = RDF::URI("http://example/pred")
|
36
|
+
s1 = RDF::Statement(n1, p, n1)
|
37
|
+
s2 = RDF::Statement(n2, p, n2)
|
38
|
+
s3 = RDF::Statement(n1, p, n2)
|
39
|
+
s4 = RDF::Statement(n2, p, n1)
|
40
|
+
graph = RDF::Graph.new.insert(s1, s2, s3, s4)
|
41
|
+
expect(graph.count).to eql 4
|
42
|
+
serialized = writer_class.buffer do |w|
|
43
|
+
w << graph
|
44
|
+
end
|
45
|
+
expect(serialized).not_to be_empty
|
46
|
+
graph2 = RDF::Graph.new do |g|
|
47
|
+
g << reader_class.new(serialized)
|
48
|
+
end
|
49
|
+
expect(graph2.count).to eql 4
|
50
|
+
end
|
51
|
+
end
|
29
52
|
end
|
30
53
|
|
31
54
|
describe ".open" do
|
@@ -134,10 +157,34 @@ RSpec.shared_examples 'an RDF::Writer' do
|
|
134
157
|
end
|
135
158
|
end
|
136
159
|
|
160
|
+
it "raises WriterError if writing an invalid statement" do
|
161
|
+
file = StringIO.new
|
162
|
+
expect do
|
163
|
+
writer_class.new(file, logger: false) do |w|
|
164
|
+
w << RDF::Statement(
|
165
|
+
RDF::URI("http://rubygems.org/gems/rdf"),
|
166
|
+
RDF::URI("http://purl.org/dc/terms/creator"),
|
167
|
+
nil)
|
168
|
+
end
|
169
|
+
end.to raise_error(RDF::WriterError)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "raises WriterError on any logged error" do
|
173
|
+
file = StringIO.new
|
174
|
+
logger = RDF::Spec.logger
|
175
|
+
expect do
|
176
|
+
writer_class.new(file, logger: logger) do |w|
|
177
|
+
w.log_error("some error")
|
178
|
+
end
|
179
|
+
end.to raise_error(RDF::WriterError)
|
180
|
+
expect(logger.to_s).to include("ERROR")
|
181
|
+
end
|
182
|
+
|
183
|
+
# FIXME: RSpec seems to blead over __write_epilogue_without_any_instance__ to other specs
|
137
184
|
#it "calls #write_prologue" do
|
138
185
|
# writer_mock = double("writer")
|
139
|
-
# writer_mock.
|
140
|
-
# writer_class.
|
186
|
+
# expect(writer_mock).to receive(:got_here)
|
187
|
+
# expect_any_instance_of(writer_class).to receive(:write_epilogue)
|
141
188
|
# writer_class.new(StringIO.new) do |r|
|
142
189
|
# writer_mock.got_here
|
143
190
|
# end
|
@@ -145,8 +192,8 @@ RSpec.shared_examples 'an RDF::Writer' do
|
|
145
192
|
#
|
146
193
|
#it "calls #write_epilogue" do
|
147
194
|
# writer_mock = double("writer")
|
148
|
-
# writer_mock.
|
149
|
-
# writer_class.
|
195
|
+
# expect(writer_mock).to receive(:got_here)
|
196
|
+
# expect_any_instance_of(writer_class).to receive(:write_epilogue)
|
150
197
|
# writer_class.new(StringIO.new) do |r|
|
151
198
|
# writer_mock.got_here
|
152
199
|
# end
|
@@ -173,27 +220,3 @@ RSpec.shared_examples 'an RDF::Writer' do
|
|
173
220
|
end
|
174
221
|
end
|
175
222
|
end
|
176
|
-
|
177
|
-
##
|
178
|
-
# @deprecated use `it_behaves_like "an RDF::Writer"` instead
|
179
|
-
module RDF_Writer
|
180
|
-
extend RSpec::SharedContext
|
181
|
-
include RDF::Spec::Matchers
|
182
|
-
|
183
|
-
def self.included(mod)
|
184
|
-
warn "[DEPRECATION] `RDF_Writer` is deprecated. "\
|
185
|
-
"Please use `it_behaves_like 'an RDF::Writer'`"
|
186
|
-
end
|
187
|
-
|
188
|
-
describe 'examples for' do
|
189
|
-
include_examples 'an RDF::Writer' do
|
190
|
-
let(:writer_class) { @writer_class }
|
191
|
-
let(:writer) { @writer }
|
192
|
-
|
193
|
-
before do
|
194
|
-
raise '@writer_class must be defined' unless defined?(writer_class)
|
195
|
-
raise '@writer must be defined' unless defined?(writer)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/countable'
|
3
|
+
|
4
|
+
describe RDF::Countable do
|
5
|
+
# @see lib/rdf/spec/countable.rb in rdf-spec
|
6
|
+
it_behaves_like 'an RDF::Countable' do
|
7
|
+
# The available reference implementations are `RDF::Repository` and
|
8
|
+
# `RDF::Graph`, but a plain Ruby array will do fine as well:
|
9
|
+
let(:countable) { RDF::Spec.quads.extend(described_class) }
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/dataset'
|
3
|
+
|
4
|
+
describe RDF::Dataset do
|
5
|
+
|
6
|
+
let(:dataset) do
|
7
|
+
RDF::Repository.new do |r|
|
8
|
+
r.insert(*RDF::Spec.quads)
|
9
|
+
end.snapshot
|
10
|
+
end
|
11
|
+
|
12
|
+
# @see lib/rdf/spec/dataset.rb in rdf-spec
|
13
|
+
it_behaves_like 'an RDF::Dataset'
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/durable'
|
3
|
+
|
4
|
+
describe RDF::Durable do
|
5
|
+
# The available reference implementations are `RDF::Repository` and
|
6
|
+
# `RDF::Graph`, but a plain Ruby array will do fine as well
|
7
|
+
# FIXME
|
8
|
+
before { @load_durable = lambda { RDF::Repository.new } }
|
9
|
+
|
10
|
+
# @see lib/rdf/spec/countable.rb in rdf-spec
|
11
|
+
it_behaves_like 'an RDF::Durable'
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/enumerable'
|
3
|
+
|
4
|
+
describe RDF::Enumerable do
|
5
|
+
# @see lib/rdf/spec/enumerable.rb in rdf-spec
|
6
|
+
it_behaves_like 'an RDF::Enumerable' do
|
7
|
+
# The available reference implementations are `RDF::Repository` and
|
8
|
+
# `RDF::Graph`, but a plain Ruby array will do fine as well:
|
9
|
+
let(:enumerable) { RDF::Spec.quads.extend(described_class) }
|
10
|
+
end
|
11
|
+
end
|
data/spec/format_spec.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/format'
|
3
|
+
require 'rdf/ntriples'
|
4
|
+
require 'rdf/nquads'
|
5
|
+
|
6
|
+
describe RDF::Format do
|
7
|
+
|
8
|
+
# @see lib/rdf/spec/format.rb in rdf-spec
|
9
|
+
it_behaves_like 'an RDF::Format' do
|
10
|
+
let(:format_class) { described_class }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'rdf/ntriples'
|
4
|
+
require 'rdf/spec/http_adapter'
|
5
|
+
|
6
|
+
context "HTTP Adapters" do
|
7
|
+
before(:each) {WebMock.disable_net_connect!}
|
8
|
+
after(:each) {WebMock.allow_net_connect!}
|
9
|
+
|
10
|
+
context "using Net::HTTP" do
|
11
|
+
it_behaves_like 'an RDF::HttpAdapter' do
|
12
|
+
let(:http_adapter) { RDF::Util::File::NetHttpAdapter }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/indexable.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'rdf/spec/indexable'
|
3
|
+
|
4
|
+
describe RDF::Indexable do
|
5
|
+
# @see lib/rdf/spec/indexable.rb in rdf-spec
|
6
|
+
it_behaves_like 'an RDF::Indexable' do
|
7
|
+
# The available reference implementations are `RDF::Repository` and
|
8
|
+
# `RDF::Graph`, but a double will do fine as well:
|
9
|
+
let(:indexable) do
|
10
|
+
d = double("Indexable").extend(RDF::Indexable)
|
11
|
+
allow(d).to receive(:index!) {d}
|
12
|
+
d
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|