the-experimenters-rdf-rdfxml 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,53 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', 'rdf-n3', 'lib'))
3
+ $:.unshift File.dirname(__FILE__)
4
+
5
+ require 'rubygems'
6
+ require 'rspec'
7
+ require 'matchers'
8
+ require 'rdf/rdfxml'
9
+ require 'rdf/ntriples'
10
+ require 'rdf/spec'
11
+ require 'rdf/spec/matchers'
12
+ require 'rdf/isomorphic'
13
+ require 'yaml' # XXX should be in open-uri/cached
14
+ require 'open-uri/cached'
15
+
16
+ # Create and maintain a cache of downloaded URIs
17
+ URI_CACHE = File.expand_path(File.join(File.dirname(__FILE__), "uri-cache"))
18
+ Dir.mkdir(URI_CACHE) unless File.directory?(URI_CACHE)
19
+ OpenURI::Cache.class_eval { @cache_path = URI_CACHE }
20
+
21
+ module RDF
22
+ module Isomorphic
23
+ alias_method :==, :isomorphic_with?
24
+ end
25
+ end
26
+
27
+ ::RSpec.configure do |c|
28
+ c.filter_run :focus => true
29
+ c.run_all_when_everything_filtered = true
30
+ c.exclusion_filter = {
31
+ :ruby => lambda { |version| !(RUBY_VERSION.to_s =~ /^#{version.to_s}/) },
32
+ }
33
+ c.include(RDF::Spec::Matchers)
34
+ end
35
+
36
+ # Heuristically detect the input stream
37
+ def detect_format(stream)
38
+ # Got to look into the file to see
39
+ if stream.is_a?(IO) || stream.is_a?(StringIO)
40
+ stream.rewind
41
+ string = stream.read(1000)
42
+ stream.rewind
43
+ else
44
+ string = stream.to_s
45
+ end
46
+ case string
47
+ when /<\w+:RDF/ then :rdf
48
+ when /<RDF/ then :rdf
49
+ #when /<html/i then :rdfa
50
+ when /@prefix/i then :n3
51
+ else :ntriples
52
+ end
53
+ end
@@ -0,0 +1,714 @@
1
+ $:.unshift "."
2
+ require File.join(File.dirname(__FILE__), 'spec_helper')
3
+ require 'rdf/spec/writer'
4
+ autoload :CGI, 'cgi'
5
+
6
+ class FOO < RDF::Vocabulary("http://foo/"); end
7
+
8
+ describe "RDF::RDFXML::Writer" do
9
+ before(:each) do
10
+ @graph = RDF::Graph.new
11
+ @writer = RDF::RDFXML::Writer
12
+ end
13
+
14
+ it_should_behave_like RDF_Writer
15
+
16
+ describe "#buffer" do
17
+ context "typed resources" do
18
+ context "resource without type" do
19
+ subject do
20
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
21
+ serialize(:max_depth => 1, :attributes => :untyped)
22
+ end
23
+
24
+ {
25
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
26
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo"
27
+ }.each do |path, value|
28
+ it "returns #{value.inspect} for xpath #{path}" do
29
+ subject.should have_xpath(path, value)
30
+ end
31
+ end
32
+ end
33
+
34
+ context "resource with type" do
35
+ subject do
36
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
37
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
38
+ serialize(:max_depth => 1, :attributes => :untyped)
39
+ end
40
+
41
+ {
42
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
43
+ "/rdf:RDF/foo:Release/@dc:title" =>"foo",
44
+ "/rdf:RDF/foo:Release/rdf:type" => ""
45
+ }.each do |path, value|
46
+ it "returns #{value.inspect} for xpath #{path}" do
47
+ subject.should have_xpath(path, value)
48
+ end
49
+ end
50
+ end
51
+
52
+ context "resource with two types as attribute" do
53
+ subject do
54
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
55
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.XtraRelease]
56
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
57
+ serialize(:max_depth => 1, :attributes => :untyped)
58
+ end
59
+
60
+ {
61
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
62
+ "/rdf:RDF/foo:Release/@dc:title" => "foo",
63
+ "/rdf:RDF/foo:Release/@rdf:type" => FOO.XtraRelease.to_s
64
+ }.each do |path, value|
65
+ it "returns #{value.inspect} for xpath #{path}" do
66
+ subject.should have_xpath(path, value)
67
+ end
68
+ end
69
+ end
70
+
71
+ context "resource with two types as element" do
72
+ subject do
73
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
74
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.XtraRelease]
75
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
76
+ serialize(:max_depth => 1, :attributes => :none)
77
+ end
78
+
79
+ {
80
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
81
+ "/rdf:RDF/foo:Release/dc:title/text()" => "foo",
82
+ %(/rdf:RDF/foo:Release/rdf:type/@rdf:resource) => FOO.XtraRelease.to_s,
83
+ %(/rdf:RDF/foo:Release/rdf:type[@rdf:resource="#{FOO.Release}"]) => false
84
+ }.each do |path, value|
85
+ it "returns #{value.inspect} for xpath #{path}" do
86
+ subject.should have_xpath(path, value)
87
+ end
88
+ end
89
+ end
90
+
91
+ context "resource with three types as element" do
92
+ subject do
93
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
94
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.XtraRelease]
95
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.XXtraRelease]
96
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
97
+ serialize(:max_depth => 1, :attributes => :typed)
98
+ end
99
+
100
+ {
101
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
102
+ "/rdf:RDF/foo:Release/@dc:title" => "foo",
103
+ %(/rdf:RDF/foo:Release/rdf:type[@rdf:resource="#{FOO.XtraRelease}"]) => %r(#{FOO.XtraRelease}),
104
+ %(/rdf:RDF/foo:Release/rdf:type[@rdf:resource="#{FOO.XXtraRelease}"]) => %r(#{FOO.XXtraRelease})
105
+ }.each do |path, value|
106
+ it "returns #{value.inspect} for xpath #{path}" do
107
+ subject.should have_xpath(path, value)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ context "with children" do
114
+ context "referenced resource by ref" do
115
+ subject do
116
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
117
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
118
+ @graph << [RDF::URI.new("http://release/contributor"), RDF.type, FOO.Contributor]
119
+ @graph << [RDF::URI.new("http://release/contributor"), RDF::DC.title, "bar"]
120
+ @graph << [RDF::URI.new("http://release/"), FOO.releaseContributor, RDF::URI.new("http://release/contributor")]
121
+ serialize(:max_depth => 1, :attributes => :untyped)
122
+ end
123
+
124
+ {
125
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
126
+ "/rdf:RDF/foo:Release/@dc:title" => "foo",
127
+ "/rdf:RDF/foo:Release/foo:releaseContributor/@rdf:resource" => "http://release/contributor",
128
+ "/rdf:RDF/foo:Contributor/@rdf:about" => "http://release/contributor",
129
+ "/rdf:RDF/foo:Contributor/@dc:title" => "bar"
130
+ }.each do |path, value|
131
+ it "returns #{value.inspect} for xpath #{path}" do
132
+ subject.should have_xpath(path, value)
133
+ end
134
+ end
135
+ end
136
+
137
+ context "referenced resource by inclusion" do
138
+ subject do
139
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
140
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
141
+ @graph << [RDF::URI.new("http://release/contributor"), RDF.type, FOO.Contributor]
142
+ @graph << [RDF::URI.new("http://release/contributor"), RDF::DC.title, "bar"]
143
+ @graph << [RDF::URI.new("http://release/"), FOO.releaseContributor, RDF::URI.new("http://release/contributor")]
144
+ serialize(:max_depth => 3, :attributes => :untyped)
145
+ end
146
+
147
+ {
148
+ "/rdf:RDF/foo:Release/@rdf:about" => "http://release/",
149
+ "/rdf:RDF/foo:Release/@dc:title" => "foo",
150
+ "/rdf:RDF/foo:Release/foo:releaseContributor/foo:Contributor/@rdf:about" => "http://release/contributor"
151
+ }.each do |path, value|
152
+ it "returns #{value.inspect} for xpath #{path}" do
153
+ subject.should have_xpath(path, value)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ context "with sequences" do
160
+ context "rdf:Seq with rdf:_n" do
161
+ subject do
162
+ @graph << [RDF::URI.new("http://example/seq"), RDF.type, RDF.Seq]
163
+ @graph << [RDF::URI.new("http://example/seq"), RDF._1, RDF::URI.new("http://example/first")]
164
+ @graph << [RDF::URI.new("http://example/seq"), RDF._2, RDF::URI.new("http://example/second")]
165
+ serialize(:max_depth => 1, :attributes => :none)
166
+ end
167
+
168
+ {
169
+ "/rdf:RDF/rdf:Seq/@rdf:about" => "http://example/seq",
170
+ %(/rdf:RDF/rdf:Seq/rdf:_1[@rdf:resource="http://example/first"]) => /first/,
171
+ %(/rdf:RDF/rdf:Seq/rdf:_2[@rdf:resource="http://example/second"]) => /second/
172
+ }.each do |path, value|
173
+ it "returns #{value.inspect} for xpath #{path}" do
174
+ subject.should have_xpath(path, value)
175
+ end
176
+ end
177
+ end
178
+
179
+ context "rdf:Seq with rdf:_n in proper sequence" do
180
+ subject do
181
+ @graph << [RDF::URI.new("http://example/seq"), RDF.type, RDF.Seq]
182
+ @graph << [RDF::URI.new("http://example/seq"), RDF._2, RDF::URI.new("http://example/second")]
183
+ @graph << [RDF::URI.new("http://example/seq"), RDF._1, RDF::URI.new("http://example/first")]
184
+ serialize(:max_depth => 1, :attributes => :none)
185
+ end
186
+
187
+ {
188
+ "/rdf:RDF/rdf:Seq/@rdf:about" => "http://example/seq",
189
+ %(/rdf:RDF/rdf:Seq/rdf:_1[@rdf:resource="http://example/first"]) => /first/,
190
+ %(/rdf:RDF/rdf:Seq/rdf:_2[@rdf:resource="http://example/second"]) => /secon/
191
+ }.each do |path, value|
192
+ it "returns #{value.inspect} for xpath #{path}" do
193
+ subject.should have_xpath(path, value)
194
+ end
195
+ end
196
+ end
197
+
198
+ context "rdf:Bag with rdf:_n" do
199
+ subject do
200
+ @graph << [RDF::URI.new("http://example/seq"), RDF.type, RDF.Bag]
201
+ @graph << [RDF::URI.new("http://example/seq"), RDF._2, RDF::URI.new("http://example/second")]
202
+ @graph << [RDF::URI.new("http://example/seq"), RDF._1, RDF::URI.new("http://example/first")]
203
+ serialize(:max_depth => 1, :attributes => :none)
204
+ end
205
+
206
+ {
207
+ "/rdf:RDF/rdf:Bag/@rdf:about" => "http://example/seq",
208
+ %(/rdf:RDF/rdf:Bag/rdf:_1[@rdf:resource="http://example/first"]) => /first/,
209
+ %(/rdf:RDF/rdf:Bag/rdf:_2[@rdf:resource="http://example/second"]) => /secon/
210
+ }.each do |path, value|
211
+ it "returns #{value.inspect} for xpath #{path}" do
212
+ subject.should have_xpath(path, value)
213
+ end
214
+ end
215
+ end
216
+
217
+ context "rdf:Alt with rdf:_n" do
218
+ subject do
219
+ @graph << [RDF::URI.new("http://example/seq"), RDF.type, RDF.Alt]
220
+ @graph << [RDF::URI.new("http://example/seq"), RDF._2, RDF::URI.new("http://example/second")]
221
+ @graph << [RDF::URI.new("http://example/seq"), RDF._1, RDF::URI.new("http://example/first")]
222
+ serialize(:max_depth => 1, :attributes => :none)
223
+ end
224
+
225
+ {
226
+ "/rdf:RDF/rdf:Alt/@rdf:about" => "http://example/seq",
227
+ %(/rdf:RDF/rdf:Alt/rdf:_1[@rdf:resource="http://example/first"]) => /first/,
228
+ %(/rdf:RDF/rdf:Alt/rdf:_2[@rdf:resource="http://example/second"]) => /secon/
229
+ }.each do |path, value|
230
+ it "returns #{value.inspect} for xpath #{path}" do
231
+ subject.should have_xpath(path, value)
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ describe "with lists" do
238
+ context "List rdf:first/rdf:rest" do
239
+ subject do
240
+ @graph = parse(%(
241
+ @prefix foo: <http://foo/> . foo:author foo:is (:Gregg :Barnum :Kellogg) .
242
+ ), :base_uri => "http://foo/", :reader => RDF::N3::Reader)
243
+ serialize({})
244
+ end
245
+
246
+ {
247
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://foo/author",
248
+ "/rdf:RDF/rdf:Description/foo:is/@rdf:parseType" => "Collection",
249
+ %(/rdf:RDF/rdf:Description/foo:is/rdf:Description[@rdf:about="http://foo/#Gregg"]) => /Gregg/,
250
+ %(/rdf:RDF/rdf:Description/foo:is/rdf:Description[@rdf:about="http://foo/#Barnum"]) => /Barnum/,
251
+ %(/rdf:RDF/rdf:Description/foo:is/rdf:Description[@rdf:about="http://foo/#Kellogg"]) => /Kellogg/,
252
+ %(//rdf:first) => false
253
+ }.each do |path, value|
254
+ it "returns #{value.inspect} for xpath #{path}" do
255
+ subject.should have_xpath(path, value)
256
+ end
257
+ end
258
+ end
259
+
260
+ context "resource with rdf:_n in proper sequence" do
261
+ subject do
262
+ @graph << [RDF::URI.new("http://example/seq"), RDF.type, RDF.Seq]
263
+ @graph << [RDF::URI.new("http://example/seq"), RDF._2, RDF::URI.new("http://example/second")]
264
+ @graph << [RDF::URI.new("http://example/seq"), RDF._1, RDF::URI.new("http://example/first")]
265
+ serialize(:max_depth => 1, :attributes => :none)
266
+ end
267
+
268
+ {
269
+ "/rdf:RDF/rdf:Seq/@rdf:about" => "http://example/seq",
270
+ %(/rdf:RDF/rdf:Seq/rdf:_1[@rdf:resource="http://example/first"]) => /first/,
271
+ %(/rdf:RDF/rdf:Seq/rdf:_2[@rdf:resource="http://example/second"]) => /second/
272
+ }.each do |path, value|
273
+ it "returns #{value.inspect} for xpath #{path}" do
274
+ subject.should have_xpath(path, value)
275
+ end
276
+ end
277
+ end
278
+ end
279
+
280
+ context "with untyped literals" do
281
+ context ":attributes == :none" do
282
+ subject do
283
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
284
+ serialize(:attributes => :none)
285
+ end
286
+
287
+ {
288
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
289
+ "/rdf:RDF/rdf:Description/dc:title/text()" => "foo"
290
+ }.each do |path, value|
291
+ it "returns #{value.inspect} for xpath #{path}" do
292
+ subject.should have_xpath(path, value)
293
+ end
294
+ end
295
+ end
296
+
297
+ [:untyped, :typed].each do |opt|
298
+ context ":attributes == #{opt}" do
299
+ subject do
300
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
301
+ serialize(:attributes => opt)
302
+ end
303
+
304
+ {
305
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
306
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo"
307
+ }.each do |path, value|
308
+ it "returns #{value.inspect} for xpath #{path}" do
309
+ subject.should have_xpath(path, value)
310
+ end
311
+ end
312
+ end
313
+ end
314
+
315
+ context "untyped without lang if attribute lang set" do
316
+ subject do
317
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "de")]
318
+ serialize(:attributes => :untyped, :lang => "de")
319
+ end
320
+
321
+ {
322
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
323
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo"
324
+ }.each do |path, value|
325
+ it "returns #{value.inspect} for xpath #{path}" do
326
+ subject.should have_xpath(path, value)
327
+ end
328
+ end
329
+ end
330
+
331
+ context "with language" do
332
+ context "property for title" do
333
+ subject do
334
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "en-us")]
335
+ serialize(:attributes => :untyped, :lang => "de")
336
+ end
337
+
338
+ {
339
+ "/rdf:RDF/@xml:lang" => "de",
340
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
341
+ "/rdf:RDF/rdf:Description/dc:title" => %(<dc:title xml:lang="en-us">foo</dc:title>)
342
+ }.each do |path, value|
343
+ it "returns #{value.inspect} for xpath #{path}" do
344
+ subject.should have_xpath(path, value)
345
+ end
346
+ end
347
+ end
348
+ end
349
+
350
+ context "attribute if lang is default" do
351
+ subject do
352
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "de")]
353
+ serialize(:attributes => :untyped, :lang => "de")
354
+ end
355
+
356
+ {
357
+ "/rdf:RDF/@xml:lang" => "de",
358
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
359
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo"
360
+ }.each do |path, value|
361
+ it "returns #{value.inspect} for xpath #{path}" do
362
+ subject.should have_xpath(path, value)
363
+ end
364
+ end
365
+ end
366
+
367
+ context "untyped as property if lang set and no default" do
368
+ subject do
369
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "de")]
370
+ serialize(:attributes => :untyped)
371
+ end
372
+
373
+ {
374
+ "/rdf:RDF/@xml:lang" => false,
375
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
376
+ "/rdf:RDF/rdf:Description/dc:title" => %(<dc:title xml:lang="de">foo</dc:title>)
377
+ }.each do |path, value|
378
+ it "returns #{value.inspect} for xpath #{path}" do
379
+ subject.should have_xpath(path, value)
380
+ end
381
+ end
382
+ end
383
+
384
+ context "untyped as property if lang set and not default" do
385
+ subject do
386
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "de")]
387
+ serialize(:attributes => :untyped, :lang => "en-us")
388
+ end
389
+
390
+ {
391
+ "/rdf:RDF/@xml:lang" => "en-us",
392
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
393
+ "/rdf:RDF/rdf:Description/dc:title" => %(<dc:title xml:lang="de">foo</dc:title>)
394
+ }.each do |path, value|
395
+ it "returns #{value.inspect} for xpath #{path}" do
396
+ subject.should have_xpath(path, value)
397
+ end
398
+ end
399
+ end
400
+
401
+ context "multiple untyped attributes values through properties" do
402
+ subject do
403
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "de")]
404
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :language => "en-us")]
405
+ serialize(:attributes => :untyped, :lang => "en-us")
406
+ end
407
+
408
+ {
409
+ "/rdf:RDF/@xml:lang" => "en-us",
410
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
411
+ "/rdf:RDF/rdf:Description/dc:title" => %(<dc:title xml:lang="de">foo</dc:title>)
412
+ }.each do |path, value|
413
+ it "returns #{value.inspect} for xpath #{path}" do
414
+ subject.should have_xpath(path, value)
415
+ end
416
+ end
417
+ end
418
+
419
+ context "typed node as element if :untyped" do
420
+ subject do
421
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :datatype => RDF::XSD.string)]
422
+ serialize(:attributes => :untyped)
423
+ end
424
+
425
+ {
426
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
427
+ "/rdf:RDF/rdf:Description/dc:title" => %(<dc:title rdf:datatype="#{RDF::XSD.string}">foo</dc:title>)
428
+ }.each do |path, value|
429
+ it "returns #{value.inspect} for xpath #{path}" do
430
+ subject.should have_xpath(path, value)
431
+ end
432
+ end
433
+ end
434
+
435
+ context "typed node as attribute if :typed" do
436
+ subject do
437
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :datatype => RDF::XSD.string)]
438
+ serialize(:attributes => :typed)
439
+ end
440
+
441
+ {
442
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
443
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo",
444
+ }.each do |path, value|
445
+ it "returns #{value.inspect} for xpath #{path}" do
446
+ subject.should have_xpath(path, value)
447
+ end
448
+ end
449
+ end
450
+
451
+ context "multiple typed values through properties" do
452
+ subject do
453
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("foo", :datatype => RDF::XSD.string)]
454
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, RDF::Literal.new("bar", :datatype => RDF::XSD.string)]
455
+ serialize(:attributes => :untyped)
456
+ end
457
+
458
+ {
459
+ "/rdf:RDF/rdf:Description/@rdf:about" => "http://release/",
460
+ "/rdf:RDF/rdf:Description/dc:title[contains(., 'foo')]" => %(<dc:title rdf:datatype="#{RDF::XSD.string}">foo</dc:title>),
461
+ "/rdf:RDF/rdf:Description/dc:title[contains(., 'bar')]" => %(<dc:title rdf:datatype="#{RDF::XSD.string}">bar</dc:title>)
462
+ }.each do |path, value|
463
+ it "returns #{value.inspect} for xpath #{path}" do
464
+ subject.should have_xpath(path, value)
465
+ end
466
+ end
467
+ end
468
+ end
469
+
470
+ context "with namespace" do
471
+ before(:each) do
472
+ @graph << [RDF::URI.new("http://release/"), RDF.type, FOO.Release]
473
+ @graph << [RDF::URI.new("http://release/"), RDF::DC.title, "foo"]
474
+ @graph << [RDF::URI.new("http://release/"), FOO.pred, FOO.obj]
475
+ end
476
+
477
+ context "default namespace" do
478
+ subject do
479
+ serialize(:max_depth => 1, :attributes => :none,
480
+ :default_namespace => FOO.to_s,
481
+ :prefixes => {:foo => FOO.to_s})
482
+ end
483
+
484
+ {
485
+ "/rdf:RDF/foo:Release/foo:pred/@rdf:resource" => FOO.obj.to_s,
486
+ }.each do |path, value|
487
+ it "returns #{value.inspect} for xpath #{path}" do
488
+ subject.should have_xpath(path, value, {"foo" => FOO.to_s})
489
+ end
490
+ end
491
+
492
+ specify { subject.should =~ /<Release/ }
493
+ specify { subject.should =~ /<pred/ }
494
+ end
495
+
496
+ context "nil namespace" do
497
+ subject do
498
+ serialize(:max_depth => 1, :attributes => :none,
499
+ :prefixes => {nil => FOO.to_s, :foo => FOO.to_s})
500
+ end
501
+
502
+ {
503
+ "/rdf:RDF/foo:Release/foo:pred/@rdf:resource" => FOO.obj.to_s,
504
+ }.each do |path, value|
505
+ it "returns #{value.inspect} for xpath #{path}" do
506
+ subject.should have_xpath(path, value, {"foo" => FOO.to_s})
507
+ end
508
+ end
509
+
510
+ specify { subject.should =~ /<Release/ }
511
+ specify { subject.should =~ /<pred/ }
512
+ end
513
+ end
514
+
515
+ describe "with base" do
516
+ context "relative about URI" do
517
+ subject do
518
+ @graph << [RDF::URI.new("http://release/a"), FOO.ref, RDF::URI.new("http://release/b")]
519
+ serialize(:attributes => :untyped, :base_uri => "http://release/")
520
+ end
521
+
522
+ {
523
+ "/rdf:RDF/rdf:Description/@rdf:about" => "a",
524
+ "/rdf:RDF/rdf:Description/foo:ref/@rdf:resource" => "b"
525
+ }.each do |path, value|
526
+ it "returns #{value.inspect} for xpath #{path}" do
527
+ subject.should have_xpath(path, value)
528
+ end
529
+ end
530
+ end
531
+ end
532
+
533
+ context "with bnodes" do
534
+ context "no nodeID attribute unless node is referenced as an object" do
535
+ subject do
536
+ @graph << [RDF::Node.new("a"), RDF::DC.title, "foo"]
537
+ serialize(:attributes => :untyped, :base_uri => "http://release/")
538
+ end
539
+
540
+ {
541
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo",
542
+ "/rdf:RDF/rdf:Description/@rdf:nodeID" => false
543
+ }.each do |path, value|
544
+ it "returns #{value.inspect} for xpath #{path}" do
545
+ subject.should have_xpath(path, value)
546
+ end
547
+ end
548
+ end
549
+
550
+ context "nodeID attribute if node is referenced as an object" do
551
+ subject do
552
+ bn = RDF::Node.new("a")
553
+ @graph << [bn, RDF::DC.title, "foo"]
554
+ @graph << [bn, RDF::OWL.equals, bn]
555
+ serialize(:attributes => :untyped, :base_uri => "http://release/")
556
+ end
557
+
558
+ {
559
+ "/rdf:RDF/rdf:Description/@dc:title" => "foo",
560
+ "/rdf:RDF/rdf:Description/@rdf:nodeID" => /a$/,
561
+ "/rdf:RDF/rdf:Description/owl:equals/@rdf:nodeID" => /a$/
562
+ }.each do |path, value|
563
+ it "returns #{value.inspect} for xpath #{path}" do
564
+ subject.should have_xpath(path, value)
565
+ end
566
+ end
567
+ end
568
+
569
+ context "rdf:nodeID for forced BNode generation" do
570
+ subject do
571
+ bn = RDF::Node.new("a")
572
+ @graph = parse(%(
573
+ @prefix : <http://example/> .
574
+ _:bar :list (_:foo (_:foo)).
575
+ ))
576
+ serialize
577
+ end
578
+
579
+ specify { parse(subject).should be_equivalent_graph(@graph, :trace => @debug.join("\n")) }
580
+ end
581
+
582
+ it "should replicate rdfcore/rdfms-seq-representation" do
583
+ @graph = parse(%(
584
+ <http://example.org/eg#eric> a [ <http://example.org/eg#intersectionOf> (<http://example.org/eg#Person> <http://example.org/eg#Male>)] .
585
+ ), :reader => RDF::N3::Reader)
586
+ parse(serialize).should be_equivalent_graph(@graph, :trace => @debug.join("\n"))
587
+ end
588
+
589
+ it "should not generate extraneous BNode" do
590
+ @graph = parse(%(
591
+ <part_of> a <http://www.w3.org/2002/07/owl#ObjectProperty> .
592
+ <a> a <http://www.w3.org/2002/07/owl#Class> .
593
+ <b> a <http://www.w3.org/2002/07/owl#Class> .
594
+ [ a <http://www.w3.org/2002/07/owl#Class>;
595
+ <http://www.w3.org/2002/07/owl#intersectionOf> (<b> [ a <http://www.w3.org/2002/07/owl#Class>,
596
+ <http://www.w3.org/2002/07/owl#Restriction>;
597
+ <http://www.w3.org/2002/07/owl#onProperty> <part_of>;
598
+ <http://www.w3.org/2002/07/owl#someValuesFrom> <a>])] .
599
+ [ a <http://www.w3.org/2002/07/owl#Class>;
600
+ <http://www.w3.org/2002/07/owl#intersectionOf> (<a> <b>)] .
601
+ ), :reader => RDF::N3::Reader)
602
+ parse(serialize).should be_equivalent_graph(@graph, :trace => @debug.join("\n"))
603
+ end
604
+ end
605
+
606
+ describe "illegal RDF values" do
607
+ it "raises error with literal as subject" do
608
+ @graph << [RDF::Literal.new("literal"), RDF::DC.title, RDF::Literal.new("foo")]
609
+ lambda { serialize }.should raise_error(RDF::WriterError)
610
+ end
611
+ it "raises error with node as predicate" do
612
+ @graph << [RDF::URI("http://example.com"), RDF::Node.new, RDF::Literal.new("foo")]
613
+ lambda { serialize }.should raise_error(RDF::WriterError)
614
+ end
615
+ end
616
+
617
+ describe "w3c rdfcore tests" do
618
+ require 'rdf_test'
619
+
620
+ # Positive parser tests should raise errors.
621
+ describe "positive parser tests" do
622
+ Fixtures::TestCase::PositiveParserTest.each do |t|
623
+ next unless t.status == "APPROVED"
624
+ next if t.subject =~ /rdfms-xml-literal-namespaces|xml-canon/ # Literal serialization adds namespace definitions
625
+ specify "#{t.name}: " + (t.description || t.outputDocument) do
626
+ @graph = parse(t.output, :base_uri => t.subject, :format => :ntriples)
627
+ parse(serialize(:format => :rdfxml, :base_uri => t.subject), :base_uri => t.subject).should be_equivalent_graph(@graph, :trace => @debug.join("\n"))
628
+ end
629
+ end
630
+ end
631
+
632
+ # Miscellaneous parser tests should raise errors.
633
+ describe "positive parser tests" do
634
+ Fixtures::TestCase::MiscellaneousTest.each do |t|
635
+ next unless t.status == "APPROVED"
636
+ specify "#{t.name}: " + (t.description || t.document) do
637
+ @graph = parse(Kernel.open(t.document), :base_uri => t.subject, :format => :ntriples)
638
+ lambda do
639
+ serialize(:format => :rdfxml, :base_uri => t.subject)
640
+ end.should raise_error(RDF::WriterError)
641
+ end
642
+ end
643
+ end
644
+ end
645
+
646
+ def check_xpaths(doc, paths)
647
+ puts doc.to_s if ::RDF::RDFXML::debug? || $verbose
648
+ doc = Nokogiri::XML.parse(doc)
649
+ doc.should be_a(Nokogiri::XML::Document)
650
+ doc.root.should be_a(Nokogiri::XML::Element)
651
+ paths.each_pair do |path, value|
652
+ next if path.is_a?(Symbol)
653
+ @debug << doc.root.at_xpath(path, doc.namespaces).to_s if ::RDF::RDFXML::debug?
654
+ case value
655
+ when false
656
+ doc.root.at_xpath(path, doc.namespaces).should be_nil
657
+ when true
658
+ doc.root.at_xpath(path, doc.namespaces).should_not be_nil
659
+ when Array
660
+ doc.root.at_xpath(path, doc.namespaces).to_s.split(" ").should include(*value)
661
+ when Regexp
662
+ doc.root.at_xpath(path, doc.namespaces).to_s.should =~ value
663
+ else
664
+ doc.root.at_xpath(path, doc.namespaces).to_s.should == value
665
+ end
666
+ end
667
+
668
+ # Parse generated graph and compare to source
669
+ if paths[:reparse]
670
+ graph = RDF::Graph.new
671
+ RDF::RDFXML::Reader.new(doc, :base_uri => "http://release/", :format => :rdfxml).each {|st| graph << st}
672
+ graph.should be_equivalent_graph(@graph, :about => "http://release/", :trace => @debug.join("\n"))
673
+ end
674
+ end
675
+
676
+ require 'rdf/n3'
677
+ def parse(input, options = {})
678
+ reader_class = options.fetch(:reader, RDF::Reader.for(detect_format(input)))
679
+
680
+ graph = RDF::Graph.new
681
+ reader_class.new(input, options).each do |statement|
682
+ graph << statement
683
+ end
684
+ graph
685
+ end
686
+
687
+ # Serialize @graph to a string and compare against regexps
688
+ def serialize(options = {})
689
+ @debug = []
690
+ result = @writer.buffer({:debug => @debug, :standard_prefixes => true}.merge(options)) do |writer|
691
+ writer << @graph
692
+ end
693
+ require 'cgi'
694
+ puts CGI.escapeHTML(result) if $verbose
695
+ result
696
+ end
697
+ end
698
+
699
+ describe "#get_qname" do
700
+ subject { RDF::RDFXML::Writer.new(StringIO.new, :prefixes => {:foo => "http://foo/"}) }
701
+ context "with undefined predicate URIs" do
702
+ {
703
+ "http://a/b" => "ns0:b",
704
+ "dc:title" => "ns0:title",
705
+ "http://a/%b" => "ns0:b",
706
+ "http://foo/%bar" => "ns0:bar"
707
+ }.each_pair do |uri, qname|
708
+ it "returns #{qname.inspect} given #{uri}" do
709
+ subject.get_qname(RDF::URI(uri)).should == qname
710
+ end
711
+ end
712
+ end
713
+ end
714
+ end