rdf-spec 1.99.0 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|