rdf-spec 1.1.5 → 1.1.13
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/CREDITS +1 -0
- data/README +1 -0
- data/VERSION +1 -1
- data/lib/rdf/spec/countable.rb +34 -11
- data/lib/rdf/spec/durable.rb +38 -20
- data/lib/rdf/spec/enumerable.rb +365 -345
- data/lib/rdf/spec/format.rb +58 -37
- data/lib/rdf/spec/http_adapter.rb +293 -0
- data/lib/rdf/spec/indexable.rb +36 -14
- data/lib/rdf/spec/inferable.rb +15 -2
- data/lib/rdf/spec/literal.rb +143 -0
- data/lib/rdf/spec/mutable.rb +36 -19
- data/lib/rdf/spec/queryable.rb +68 -33
- data/lib/rdf/spec/readable.rb +29 -6
- data/lib/rdf/spec/reader.rb +183 -157
- data/lib/rdf/spec/repository.rb +59 -38
- data/lib/rdf/spec/transaction.rb +92 -90
- data/lib/rdf/spec/writable.rb +109 -97
- data/lib/rdf/spec/writer.rb +153 -131
- metadata +22 -6
data/lib/rdf/spec/format.rb
CHANGED
@@ -1,53 +1,74 @@
|
|
1
1
|
require 'rdf/spec'
|
2
2
|
|
3
|
-
|
4
|
-
extend RSpec::SharedContext
|
3
|
+
RSpec.shared_examples 'an RDF::Format' do
|
5
4
|
include RDF::Spec::Matchers
|
6
5
|
|
7
6
|
before(:each) do
|
8
|
-
raise
|
7
|
+
raise 'format_class must be defined with let(:format_class)' unless
|
8
|
+
defined? format_class
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
11
|
+
subject { format_class }
|
12
|
+
|
13
|
+
describe ".for" do
|
14
|
+
RDF::Format.file_extensions.each do |ext, formats|
|
15
|
+
it "detects #{formats.first} using file path foo.#{ext}" do
|
16
|
+
expect(RDF::Format.for("foo.#{ext}")).to eq formats.first
|
17
|
+
end
|
18
|
+
|
19
|
+
it "detects #{formats.first} using file_name foo.#{ext}" do
|
20
|
+
expect(RDF::Format.for(:file_name => "foo.#{ext}")).to eq formats.first
|
21
|
+
end
|
22
|
+
|
23
|
+
it "detects #{formats.first} using file_extension #{ext}" do
|
24
|
+
expect(RDF::Format.for(:file_extension => ext)).to eq formats.first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
RDF::Format.content_types.each do |content_type, formats|
|
29
|
+
it "detects #{formats.first} using content_type #{content_type}" do
|
30
|
+
expect(RDF::Format.for(:content_type => content_type)).to eq formats.first
|
26
31
|
end
|
32
|
+
end
|
33
|
+
end
|
27
34
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
describe ".reader" do
|
36
|
+
it "returns a reader" do
|
37
|
+
subject.each do |f|
|
38
|
+
expect(f.reader).not_to be_nil
|
32
39
|
end
|
33
40
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".writer" do
|
44
|
+
##
|
45
|
+
# May not return a writer, only does if one is defined by the format
|
46
|
+
it "returns a writer" do
|
47
|
+
subject.each do |f|
|
48
|
+
format_namespace = f.name.split('::')[0..-2].inject(Kernel) {|base, const| base.const_get(const)}
|
49
|
+
expect(f.writer).not_to be_nil if format_namespace.const_defined?(:Writer)
|
40
50
|
end
|
41
51
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# @deprecated use `it_behaves_like "an RDF::Format"` instead
|
57
|
+
module RDF_Format
|
58
|
+
extend RSpec::SharedContext
|
59
|
+
include RDF::Spec::Matchers
|
60
|
+
|
61
|
+
def self.included(mod)
|
62
|
+
warn "[DEPRECATION] `RDF_Format` is deprecated. "\
|
63
|
+
"Please use `it_behaves_like 'an RDF::Format'`"
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'examples for' do
|
67
|
+
include_examples 'an RDF::Format' do
|
68
|
+
let(:format_class) { @format_class }
|
69
|
+
|
70
|
+
before do
|
71
|
+
raise '@format_class must be defined' unless defined?(format_class)
|
51
72
|
end
|
52
73
|
end
|
53
74
|
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
require 'rdf/spec'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
|
4
|
+
RSpec.shared_examples 'an RDF::HttpAdapter' do
|
5
|
+
let(:doap_file) {File.expand_path("../../../../etc/doap.nt", __FILE__)}
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
raise '`http_adapter` must be defined with `let(:http_adapter`' unless
|
9
|
+
defined? http_adapter
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:uri) {"http://ruby-rdf.github.com/rdf/etc/doap.nt"}
|
13
|
+
|
14
|
+
let(:opened) {double("opened")}
|
15
|
+
before(:each) do
|
16
|
+
expect(opened).to receive(:opened)
|
17
|
+
end
|
18
|
+
|
19
|
+
context "using a HTTP client" do
|
20
|
+
before { RDF::Util::File.http_adapter = http_adapter }
|
21
|
+
after { RDF::Util::File.http_adapter = nil }
|
22
|
+
|
23
|
+
it "returns an http URL" do
|
24
|
+
WebMock.stub_request(:get, uri).
|
25
|
+
to_return(body: File.read(doap_file),
|
26
|
+
status: 200,
|
27
|
+
headers: { 'Content-Type' => RDF::NTriples::Format.content_type.first})
|
28
|
+
f = RDF::Util::File.open_file(uri)
|
29
|
+
expect(f).to respond_to(:read)
|
30
|
+
expect(f.content_type).to eq RDF::NTriples::Format.content_type.first
|
31
|
+
expect(f.code).to eq 200
|
32
|
+
opened.opened
|
33
|
+
end
|
34
|
+
|
35
|
+
it "adds Accept header using defined readers" do
|
36
|
+
content_types = RDF::Reader.map {|r| r.format.content_type}.flatten.uniq
|
37
|
+
WebMock.stub_request(:get, uri).with do |request|
|
38
|
+
expect(request.headers['Accept']).to include(*content_types)
|
39
|
+
end.to_return(body: "foo")
|
40
|
+
RDF::Util::File.open_file(uri) do |f|
|
41
|
+
opened.opened
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "adds Accept header with low-priority */*" do
|
46
|
+
WebMock.stub_request(:get, uri).with do |request|
|
47
|
+
expect(request.headers['Accept']).to include('*/*;q=0.1')
|
48
|
+
end.to_return(body: "foo")
|
49
|
+
RDF::Util::File.open_file(uri) do |f|
|
50
|
+
opened.opened
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "used provided Accept header" do
|
55
|
+
WebMock.stub_request(:get, uri).with do |request|
|
56
|
+
expect(request.headers["Accept"]).to include('a/b')
|
57
|
+
end.to_return(body: "foo")
|
58
|
+
RDF::Util::File.open_file(uri, headers: {"Accept" => "a/b"}) do |f|
|
59
|
+
opened.opened
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "sets content_type and encoding to utf-8 if absent" do
|
64
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"Content-Type" => "text/turtle"})
|
65
|
+
RDF::Util::File.open_file(uri) do |f|
|
66
|
+
expect(f.content_type).to eq "text/turtle"
|
67
|
+
expect(f.charset).to eq Encoding::UTF_8
|
68
|
+
expect(f.content_encoding).to eq "utf-8"
|
69
|
+
expect(f.external_encoding.to_s.downcase).to eq "utf-8"
|
70
|
+
opened.opened
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "sets content_type and encoding if provided" do
|
75
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"Content-Type" => "text/turtle ; charset=ISO-8859-4"})
|
76
|
+
RDF::Util::File.open_file(uri) do |f|
|
77
|
+
expect(f.content_type).to eq "text/turtle"
|
78
|
+
expect(f.charset).to eq "ISO-8859-4"
|
79
|
+
expect(f.external_encoding.to_s.downcase).to eq "iso-8859-4"
|
80
|
+
opened.opened
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "sets last_modified if provided" do
|
85
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"Last-Modified" => "Thu, 24 Oct 2013 23:46:56 GMT"})
|
86
|
+
RDF::Util::File.open_file(uri) do |f|
|
87
|
+
expect(f.last_modified).to eq DateTime.parse("Thu, 24 Oct 2013 23:46:56 GMT")
|
88
|
+
opened.opened
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it "sets etag if provided" do
|
93
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"ETag" => "abc123"})
|
94
|
+
RDF::Util::File.open_file(uri) do |f|
|
95
|
+
expect(f.etag).to eq "abc123"
|
96
|
+
opened.opened
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "sets arbitrary header" do
|
101
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"Foo" => "Bar"})
|
102
|
+
RDF::Util::File.open_file(uri) do |f|
|
103
|
+
expect(f.headers[:foo]).to eq "Bar"
|
104
|
+
opened.opened
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "redirects" do
|
109
|
+
it "sets base_uri to resource" do
|
110
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo")
|
111
|
+
RDF::Util::File.open_file(uri) do |f|
|
112
|
+
expect(f.base_uri).to eq uri
|
113
|
+
opened.opened
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "sets base_uri to location if present" do
|
118
|
+
WebMock.stub_request(:get, uri).to_return(body: "foo", headers: {"Location" => "http://example/"})
|
119
|
+
RDF::Util::File.open_file(uri) do |f|
|
120
|
+
expect(f.base_uri).to eq "http://example/"
|
121
|
+
opened.opened
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "follows 301 and uses new location" do
|
126
|
+
WebMock.stub_request(:get, uri).to_return({status: 301, headers: {"Location" => "http://example/"}})
|
127
|
+
WebMock.stub_request(:get, "http://example/").to_return({body: "foo"})
|
128
|
+
RDF::Util::File.open_file(uri) do |f|
|
129
|
+
expect(f.base_uri).to eq "http://example/"
|
130
|
+
expect(f.read).to eq "foo"
|
131
|
+
opened.opened
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "follows 302 and uses new location" do
|
136
|
+
WebMock.stub_request(:get, uri).to_return({status: 302, headers: {"Location" => "http://example/"}})
|
137
|
+
WebMock.stub_request(:get, "http://example/").to_return({body: "foo"})
|
138
|
+
RDF::Util::File.open_file(uri) do |f|
|
139
|
+
expect(f.base_uri).to eq "http://example/"
|
140
|
+
expect(f.read).to eq "foo"
|
141
|
+
opened.opened
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "follows 303 and uses new location" do
|
146
|
+
WebMock.stub_request(:get, uri).to_return({status: 303, headers: {"Location" => "http://example/"}})
|
147
|
+
WebMock.stub_request(:get, "http://example/").to_return({body: "foo"})
|
148
|
+
RDF::Util::File.open_file(uri) do |f|
|
149
|
+
expect(f.base_uri).to eq "http://example/"
|
150
|
+
expect(f.read).to eq "foo"
|
151
|
+
opened.opened
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
it "follows 307 and uses new location" do
|
156
|
+
WebMock.stub_request(:get, uri).to_return({status: 307, headers: {"Location" => "http://example/"}})
|
157
|
+
WebMock.stub_request(:get, "http://example/").to_return({body: "foo"})
|
158
|
+
RDF::Util::File.open_file(uri) do |f|
|
159
|
+
expect(f.base_uri).to eq "http://example/"
|
160
|
+
expect(f.read).to eq "foo"
|
161
|
+
opened.opened
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it "raises an IOError for HTTP 4xx status codes" do
|
166
|
+
opened.opened
|
167
|
+
|
168
|
+
WebMock.stub_request(:get, uri).to_return({status: 404})
|
169
|
+
expect do
|
170
|
+
RDF::Util::File.open_file(uri)
|
171
|
+
end.to raise_exception IOError
|
172
|
+
end
|
173
|
+
|
174
|
+
it "raises an IOError for HTTP 5xx status codes" do
|
175
|
+
opened.opened
|
176
|
+
|
177
|
+
WebMock.stub_request(:get, uri).to_return({status: 500})
|
178
|
+
expect do
|
179
|
+
RDF::Util::File.open_file(uri)
|
180
|
+
end.to raise_exception IOError
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "proxy" do
|
185
|
+
it "requests through proxy" do
|
186
|
+
WebMock.stub_request(:get, uri).
|
187
|
+
to_return(body: File.read(doap_file),
|
188
|
+
status: 200,
|
189
|
+
headers: { 'Content-Type' => RDF::NTriples::Format.content_type.first})
|
190
|
+
RDF::Util::File.open_file(uri, proxy: "http://proxy.example.com") do |f|
|
191
|
+
opened.opened
|
192
|
+
end
|
193
|
+
expect(WebMock).to have_requested(:get, uri)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "https" do
|
198
|
+
let(:uri) {"https://some/secure/uri"}
|
199
|
+
|
200
|
+
it "returns an https URL" do
|
201
|
+
WebMock.stub_request(:get, uri).
|
202
|
+
to_return(body: "foo",
|
203
|
+
status: 200,
|
204
|
+
headers: { 'Content-Type' => RDF::NTriples::Format.content_type.first})
|
205
|
+
f = RDF::Util::File.open_file(uri)
|
206
|
+
expect(f).to respond_to(:read)
|
207
|
+
expect(f.content_type).to eq RDF::NTriples::Format.content_type.first
|
208
|
+
expect(f.code).to eq 200
|
209
|
+
opened.opened
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context "links" do
|
214
|
+
{
|
215
|
+
"no links" => [
|
216
|
+
'',
|
217
|
+
[]
|
218
|
+
],
|
219
|
+
"rel" => [
|
220
|
+
'<http://example.com/foo>; rel="self"',
|
221
|
+
[["http://example.com/foo", [%w(rel self)]]]
|
222
|
+
],
|
223
|
+
"rel-meta" => [
|
224
|
+
'<http://example.com/>; rel="up"; meta="bar"',
|
225
|
+
[["http://example.com/", [%w(rel up), %w(meta bar)]]]
|
226
|
+
],
|
227
|
+
'bar' => [
|
228
|
+
'<http://example.com/>',
|
229
|
+
[["http://example.com/", []]]
|
230
|
+
],
|
231
|
+
'two links' => [
|
232
|
+
'<http://example.com/foo>; rel="self", <http://example.com/>; rel="up"; meta="bar"',
|
233
|
+
[
|
234
|
+
["http://example.com/foo", [%w(rel self)]],
|
235
|
+
["http://example.com/", [%w(rel up), %w(meta bar)]]
|
236
|
+
]
|
237
|
+
]
|
238
|
+
}.each do |name, (input, output)|
|
239
|
+
it name do
|
240
|
+
WebMock.stub_request(:get, uri).
|
241
|
+
to_return(body: "content",
|
242
|
+
status: 200,
|
243
|
+
headers: {
|
244
|
+
'Content-Type' => RDF::NTriples::Format.content_type.first,
|
245
|
+
'Link' => input
|
246
|
+
})
|
247
|
+
RDF::Util::File.open_file(uri) do |f|
|
248
|
+
expect(f).to respond_to(:read)
|
249
|
+
expect(f.links.to_a).to eq output
|
250
|
+
opened.opened
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
it "can find a link using #find_link" do
|
256
|
+
WebMock.stub_request(:get, uri).
|
257
|
+
to_return(body: "content",
|
258
|
+
status: 200,
|
259
|
+
headers: {
|
260
|
+
'Content-Type' => RDF::NTriples::Format.content_type.first,
|
261
|
+
'Link' => '<http://example.com/foo> rel="describedby" type="application/n-triples"'
|
262
|
+
})
|
263
|
+
RDF::Util::File.open_file(uri) do |f|
|
264
|
+
expect(f.links.find_link(['rel', 'describedby']).to_a).to eq ['http://example.com/foo', [%w(rel describedby)]]
|
265
|
+
opened.opened
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
272
|
+
|
273
|
+
##
|
274
|
+
# @deprecated use `it_behaves_like "an RDF::HttpAdapter"` instead
|
275
|
+
module RDF_HttpAdapter
|
276
|
+
extend RSpec::SharedContext
|
277
|
+
include RDF::Spec::Matchers
|
278
|
+
|
279
|
+
def self.included(mod)
|
280
|
+
warn "[DEPRECATION] `RDF_HttpAdapter` is deprecated. "\
|
281
|
+
"Please use `it_behaves_like 'an RDF::HttpAdapter'`"
|
282
|
+
end
|
283
|
+
|
284
|
+
describe 'examples for' do
|
285
|
+
include_examples 'an RDF::HttpAdapter' do
|
286
|
+
let(:http_adapter) { @http_adapter }
|
287
|
+
|
288
|
+
before do
|
289
|
+
raise '@http_adapter must be defined' unless defined?(http_adapter)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
data/lib/rdf/spec/indexable.rb
CHANGED
@@ -1,25 +1,47 @@
|
|
1
1
|
require 'rdf/spec'
|
2
2
|
|
3
|
+
RSpec.shared_examples 'an RDF::Indexable' do
|
4
|
+
include RDF::Spec::Matchers
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
raise 'indexable must be defined with let(:indexable)' unless
|
8
|
+
defined? indexable
|
9
|
+
end
|
10
|
+
|
11
|
+
subject { indexable }
|
12
|
+
|
13
|
+
it {should respond_to(:indexed?)}
|
14
|
+
its(:indexed?) {should == subject.indexed?}
|
15
|
+
it {should respond_to(:index!)}
|
16
|
+
|
17
|
+
it "does not raise error on #index! if #indexed?" do
|
18
|
+
expect {subject.index!}.not_to raise_error if subject.indexed?
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises error on #index! if not #indexed?" do
|
22
|
+
expect {subject.index!}.to raise_error unless subject.indexed?
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# @deprecated use `it_behaves_like "an RDF::Indexable"` instead
|
3
29
|
module RDF_Indexable
|
4
30
|
extend RSpec::SharedContext
|
5
31
|
include RDF::Spec::Matchers
|
6
32
|
|
7
|
-
|
8
|
-
|
33
|
+
def self.included(mod)
|
34
|
+
warn "[DEPRECATION] `RDF_Indexable` is deprecated. "\
|
35
|
+
"Please use `it_behaves_like 'an RDF::Indexable'`"
|
9
36
|
end
|
10
37
|
|
11
|
-
describe
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
expect {subject.index!}.not_to raise_error if subject.indexed?
|
19
|
-
end
|
20
|
-
|
21
|
-
it "raises error on #index! if not #indexed?" do
|
22
|
-
expect {subject.index!}.to raise_error unless subject.indexed?
|
38
|
+
describe 'examples for' do
|
39
|
+
include_examples 'an RDF::Indexable' do
|
40
|
+
let(:indexable) { @indexable }
|
41
|
+
|
42
|
+
before do
|
43
|
+
raise '@indexable must be defined' unless defined?(indexable)
|
44
|
+
end
|
23
45
|
end
|
24
46
|
end
|
25
47
|
end
|