the-experimenters-rdf-rdfxml 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +13 -0
- data/AUTHORS +1 -0
- data/CONTRIBUTORS +1 -0
- data/History.rdoc +100 -0
- data/README +95 -0
- data/README.md +95 -0
- data/Rakefile +59 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/etc/doap.nt +47 -0
- data/etc/doap.xml +73 -0
- data/example.rb +37 -0
- data/lib/rdf/rdfxml.rb +50 -0
- data/lib/rdf/rdfxml/format.rb +43 -0
- data/lib/rdf/rdfxml/patches/array_hacks.rb +53 -0
- data/lib/rdf/rdfxml/patches/graph_properties.rb +34 -0
- data/lib/rdf/rdfxml/patches/literal_hacks.rb +156 -0
- data/lib/rdf/rdfxml/patches/nokogiri_hacks.rb +16 -0
- data/lib/rdf/rdfxml/reader.rb +646 -0
- data/lib/rdf/rdfxml/version.rb +18 -0
- data/lib/rdf/rdfxml/vocab.rb +3 -0
- data/lib/rdf/rdfxml/writer.rb +559 -0
- data/rdf-rdfxml.gemspec +109 -0
- data/script/console +10 -0
- data/script/parse +55 -0
- data/script/tc +50 -0
- data/script/yard-to-rubyforge +2 -0
- data/spec/.gitignore +1 -0
- data/spec/format_spec.rb +28 -0
- data/spec/graph_spec.rb +59 -0
- data/spec/literal_spec.rb +244 -0
- data/spec/matchers.rb +79 -0
- data/spec/rdf_test.rb +69 -0
- data/spec/reader_spec.rb +361 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/writer_spec.rb +714 -0
- metadata +190 -0
data/spec/matchers.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rspec/matchers'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :have_xpath do |xpath, value, namespaces = {}|
|
4
|
+
match do |actual|
|
5
|
+
@doc = Nokogiri::XML.parse(actual)
|
6
|
+
@doc.should be_a(Nokogiri::XML::Document)
|
7
|
+
@doc.root.should be_a(Nokogiri::XML::Element)
|
8
|
+
@namespaces = @doc.namespaces.
|
9
|
+
merge(namespaces).
|
10
|
+
merge("xhtml" => "http://www.w3.org/1999/xhtml", "xml" => "http://www.w3.org/XML/1998/namespace")
|
11
|
+
@result = @doc.root.at_xpath(xpath, @namespaces) rescue false
|
12
|
+
case value
|
13
|
+
when false
|
14
|
+
@result.should be_nil
|
15
|
+
when Array
|
16
|
+
@result.to_s.split(" ").should include(*value)
|
17
|
+
when Regexp
|
18
|
+
@result.to_s.should =~ value
|
19
|
+
else
|
20
|
+
@result.to_s.should == value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_for_should do |actual|
|
25
|
+
msg = "expected to that #{xpath.inspect} would be #{value.inspect} in:\n" + actual.to_s
|
26
|
+
msg += "was: #{@result}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def normalize(graph)
|
31
|
+
case graph
|
32
|
+
when RDF::Graph then graph
|
33
|
+
when IO, StringIO
|
34
|
+
RDF::Graph.new.load(graph, :base_uri => @info.about)
|
35
|
+
else
|
36
|
+
# Figure out which parser to use
|
37
|
+
g = RDF::Graph.new
|
38
|
+
reader_class = RDF::Reader.for(detect_format(graph))
|
39
|
+
reader_class.new(graph, :base_uri => @info.about).each {|s| g << s}
|
40
|
+
g
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Info = Struct.new(:about, :information, :trace, :compare, :inputDocument, :outputDocument)
|
45
|
+
|
46
|
+
RSpec::Matchers.define :be_equivalent_graph do |expected, info|
|
47
|
+
match do |actual|
|
48
|
+
@info = if info.respond_to?(:about)
|
49
|
+
info
|
50
|
+
elsif info.is_a?(Hash)
|
51
|
+
identifier = info[:identifier] || expected.is_a?(RDF::Graph) ? expected.context : info[:about]
|
52
|
+
trace = info[:trace]
|
53
|
+
trace = trace.join("\n") if trace.is_a?(Array)
|
54
|
+
Info.new(identifier, info[:information] || "", trace, info[:compare])
|
55
|
+
else
|
56
|
+
Info.new(expected.is_a?(RDF::Graph) ? expected.context : info, info.to_s)
|
57
|
+
end
|
58
|
+
@expected = normalize(expected)
|
59
|
+
@actual = normalize(actual)
|
60
|
+
@actual.isomorphic_with?(@expected)
|
61
|
+
end
|
62
|
+
|
63
|
+
failure_message_for_should do |actual|
|
64
|
+
info = @info.respond_to?(:information) ? @info.information : @info.inspect
|
65
|
+
if @expected.is_a?(RDF::Graph) && @actual.size != @expected.size
|
66
|
+
"Graph entry count differs:\nexpected: #{@expected.size}\nactual: #{@actual.size}"
|
67
|
+
elsif @expected.is_a?(Array) && @actual.size != @expected.length
|
68
|
+
"Graph entry count differs:\nexpected: #{@expected.length}\nactual: #{@actual.size}"
|
69
|
+
else
|
70
|
+
"Graph differs"
|
71
|
+
end +
|
72
|
+
"\n#{info + "\n" unless info.empty?}" +
|
73
|
+
(@info.inputDocument ? "Input file: #{@info.inputDocument}\n" : "") +
|
74
|
+
(@info.outputDocument ? "Output file: #{@info.outputDocument}\n" : "") +
|
75
|
+
"Unsorted Expected:\n#{@expected.dump(:ntriples)}" +
|
76
|
+
"Unsorted Results:\n#{@actual.dump(:ntriples)}" +
|
77
|
+
(@info.trace ? "\nDebug:\n#{@info.trace}" : "")
|
78
|
+
end
|
79
|
+
end
|
data/spec/rdf_test.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Spira class for manipulating test-manifest style test suites.
|
2
|
+
# Used for SWAP tests
|
3
|
+
require 'spira'
|
4
|
+
require 'rdf/n3'
|
5
|
+
require 'open-uri'
|
6
|
+
|
7
|
+
module Fixtures
|
8
|
+
module TestCase
|
9
|
+
class Test < RDF::Vocabulary("http://www.w3.org/2000/10/rdf-tests/rdfcore/testSchema#"); end
|
10
|
+
|
11
|
+
class Entry
|
12
|
+
attr_accessor :debug
|
13
|
+
attr_accessor :compare
|
14
|
+
include Spira::Resource
|
15
|
+
|
16
|
+
property :description, :predicate => Test.description, :type => XSD.string
|
17
|
+
property :status, :predicate => Test.status, :type => XSD.string
|
18
|
+
property :warning, :predicate => Test.warning, :type => XSD.string
|
19
|
+
property :approval, :predicate => Test.approval
|
20
|
+
property :issue, :predicate => Test.issue
|
21
|
+
property :document, :predicate => Test.document
|
22
|
+
property :discussion, :predicate => Test.discussion
|
23
|
+
property :inputDocument, :predicate => Test.inputDocument
|
24
|
+
property :outputDocument, :predicate => Test.outputDocument
|
25
|
+
|
26
|
+
def name
|
27
|
+
subject.to_s.split("#").last
|
28
|
+
end
|
29
|
+
|
30
|
+
def input
|
31
|
+
Kernel.open(self.inputDocument)
|
32
|
+
end
|
33
|
+
|
34
|
+
def output
|
35
|
+
self.outputDocument ? Kernel.open(self.outputDocument) : ""
|
36
|
+
end
|
37
|
+
|
38
|
+
def information; self.description; end
|
39
|
+
|
40
|
+
def inspect
|
41
|
+
"[#{self.class.to_s} " + %w(
|
42
|
+
subject
|
43
|
+
description
|
44
|
+
inputDocument
|
45
|
+
outputDocument
|
46
|
+
).map {|a| v = self.send(a); "#{a}='#{v}'" if v}.compact.join(", ") +
|
47
|
+
"]"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class PositiveParserTest < Entry
|
52
|
+
default_source :entries
|
53
|
+
type Test.PositiveParserTest
|
54
|
+
end
|
55
|
+
|
56
|
+
class NegativeParserTest < Entry
|
57
|
+
default_source :entries
|
58
|
+
type Test.NegativeParserTest
|
59
|
+
end
|
60
|
+
|
61
|
+
class MiscellaneousTest < Entry
|
62
|
+
default_source :entries
|
63
|
+
type Test.MiscellaneousTest
|
64
|
+
end
|
65
|
+
|
66
|
+
repo = RDF::Repository.load("http://www.w3.org/2000/10/rdf-tests/rdfcore/Manifest.rdf")
|
67
|
+
Spira.add_repository! :entries, repo
|
68
|
+
end
|
69
|
+
end
|
data/spec/reader_spec.rb
ADDED
@@ -0,0 +1,361 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.unshift "."
|
3
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
4
|
+
require 'rdf/spec/reader'
|
5
|
+
|
6
|
+
# w3c test suite: http://www.w3.org/TR/rdf-testcases/
|
7
|
+
|
8
|
+
describe "RDF::RDFXML::Reader" do
|
9
|
+
before :each do
|
10
|
+
@reader = RDF::RDFXML::Reader
|
11
|
+
end
|
12
|
+
|
13
|
+
it_should_behave_like RDF_Reader
|
14
|
+
|
15
|
+
context "discovery" do
|
16
|
+
{
|
17
|
+
"rdf" => RDF::Reader.for(:rdf),
|
18
|
+
"rdfxml" => RDF::Reader.for(:rdfxml),
|
19
|
+
"etc/foaf.xml" => RDF::Reader.for("etc/foaf.xml"),
|
20
|
+
"etc/foaf.rdf" => RDF::Reader.for("etc/foaf.rdf"),
|
21
|
+
"foaf.xml" => RDF::Reader.for(:file_name => "foaf.xml"),
|
22
|
+
"foaf.rdf" => RDF::Reader.for(:file_name => "foaf.rdf"),
|
23
|
+
".xml" => RDF::Reader.for(:file_extension => "xml"),
|
24
|
+
".rdf" => RDF::Reader.for(:file_extension => "rdf"),
|
25
|
+
"application/xml" => RDF::Reader.for(:content_type => "application/xml"),
|
26
|
+
"application/rdf+xml" => RDF::Reader.for(:content_type => "application/rdf+xml"),
|
27
|
+
}.each_pair do |label, format|
|
28
|
+
it "should discover '#{label}'" do
|
29
|
+
format.should == @reader
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context :interface do
|
35
|
+
before(:each) do
|
36
|
+
@sampledoc = <<-EOF;
|
37
|
+
<?xml version="1.0" ?>
|
38
|
+
<GenericXML xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/">
|
39
|
+
<rdf:RDF>
|
40
|
+
<rdf:Description rdf:about="http://example.org/one">
|
41
|
+
<ex:name>Foo</ex:name>
|
42
|
+
</rdf:Description>
|
43
|
+
</rdf:RDF>
|
44
|
+
<blablabla />
|
45
|
+
<rdf:RDF>
|
46
|
+
<rdf:Description rdf:about="http://example.org/two">
|
47
|
+
<ex:name>Bar</ex:name>
|
48
|
+
</rdf:Description>
|
49
|
+
</rdf:RDF>
|
50
|
+
</GenericXML>
|
51
|
+
EOF
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should yield reader" do
|
55
|
+
inner = mock("inner")
|
56
|
+
inner.should_receive(:called).with(@reader)
|
57
|
+
@reader.new(@sampledoc) do |reader|
|
58
|
+
inner.called(reader.class)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return reader" do
|
63
|
+
@reader.new(@sampledoc).should be_a(@reader)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should yield statements" do
|
67
|
+
inner = mock("inner")
|
68
|
+
inner.should_receive(:called).with(RDF::Statement).twice
|
69
|
+
@reader.new(@sampledoc).each_statement do |statement|
|
70
|
+
inner.called(statement.class)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should yield triples" do
|
75
|
+
inner = mock("inner")
|
76
|
+
inner.should_receive(:called).with(RDF::URI, RDF::URI, RDF::Literal).twice
|
77
|
+
@reader.new(@sampledoc).each_triple do |subject, predicate, object|
|
78
|
+
inner.called(subject.class, predicate.class, object.class)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "simple parsing" do
|
84
|
+
it "should recognise and create single triple for empty non-RDF root" do
|
85
|
+
sampledoc = %(<?xml version="1.0" ?>
|
86
|
+
<NotRDF />)
|
87
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
88
|
+
graph.size.should == 1
|
89
|
+
statement = graph.statements.first
|
90
|
+
statement.subject.class.should == RDF::Node
|
91
|
+
statement.predicate.should == RDF.type
|
92
|
+
statement.object.should == RDF::XML.NotRDF
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should parse on XML documents with multiple RDF nodes" do
|
96
|
+
sampledoc = <<-EOF;
|
97
|
+
<?xml version="1.0" ?>
|
98
|
+
<GenericXML xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/">
|
99
|
+
<rdf:RDF>
|
100
|
+
<rdf:Description rdf:about="http://example.org/one">
|
101
|
+
<ex:name>Foo</ex:name>
|
102
|
+
</rdf:Description>
|
103
|
+
</rdf:RDF>
|
104
|
+
<blablabla />
|
105
|
+
<rdf:RDF>
|
106
|
+
<rdf:Description rdf:about="http://example.org/two">
|
107
|
+
<ex:name>Bar</ex:name>
|
108
|
+
</rdf:Description>
|
109
|
+
</rdf:RDF>
|
110
|
+
</GenericXML>
|
111
|
+
EOF
|
112
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
113
|
+
objects = graph.statements.map {|s| s.object.value}.sort
|
114
|
+
objects.should == ["Bar", "Foo"]
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should be able to parse a simple single-triple document" do
|
118
|
+
sampledoc = <<-EOF;
|
119
|
+
<?xml version="1.0" ?>
|
120
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
121
|
+
xmlns:ex="http://www.example.org/" xml:lang="en" xml:base="http://www.example.org/foo">
|
122
|
+
<ex:Thing rdf:about="http://example.org/joe" ex:name="bar">
|
123
|
+
<ex:belongsTo rdf:resource="http://tommorris.org/" />
|
124
|
+
<ex:sampleText rdf:datatype="http://www.w3.org/2001/XMLSchema#string">foo</ex:sampleText>
|
125
|
+
<ex:hadADodgyRelationshipWith>
|
126
|
+
<rdf:Description>
|
127
|
+
<ex:name>Tom</ex:name>
|
128
|
+
<ex:hadADodgyRelationshipWith>
|
129
|
+
<rdf:Description>
|
130
|
+
<ex:name>Rob</ex:name>
|
131
|
+
<ex:hadADodgyRelationshipWith>
|
132
|
+
<rdf:Description>
|
133
|
+
<ex:name>Mary</ex:name>
|
134
|
+
</rdf:Description>
|
135
|
+
</ex:hadADodgyRelationshipWith>
|
136
|
+
</rdf:Description>
|
137
|
+
</ex:hadADodgyRelationshipWith>
|
138
|
+
</rdf:Description>
|
139
|
+
</ex:hadADodgyRelationshipWith>
|
140
|
+
</ex:Thing>
|
141
|
+
</rdf:RDF>
|
142
|
+
EOF
|
143
|
+
|
144
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
145
|
+
#puts @debug
|
146
|
+
graph.size.should == 10
|
147
|
+
# print graph.dump(:ntriples
|
148
|
+
# TODO: add datatype parsing
|
149
|
+
# TODO: make sure the BNode forging is done correctly - an internal element->nodeID mapping
|
150
|
+
# TODO: proper test
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should be able to handle Bags/Alts etc." do
|
154
|
+
sampledoc = <<-EOF;
|
155
|
+
<?xml version="1.0" ?>
|
156
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:eg="http://example.org/">
|
157
|
+
<rdf:Bag>
|
158
|
+
<rdf:li rdf:resource="http://tommorris.org/" />
|
159
|
+
<rdf:li rdf:resource="http://twitter.com/tommorris" />
|
160
|
+
</rdf:Bag>
|
161
|
+
</rdf:RDF>
|
162
|
+
EOF
|
163
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
164
|
+
graph.predicates.map(&:to_s).should include("http://www.w3.org/1999/02/22-rdf-syntax-ns#_1", "http://www.w3.org/1999/02/22-rdf-syntax-ns#_2")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context :exceptions do
|
169
|
+
it "should raise an error if rdf:aboutEach is used, as per the negative parser test rdfms-abouteach-error001 (rdf:aboutEach attribute)" do
|
170
|
+
sampledoc = <<-EOF;
|
171
|
+
<?xml version="1.0" ?>
|
172
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
173
|
+
xmlns:eg="http://example.org/">
|
174
|
+
|
175
|
+
<rdf:Bag rdf:ID="node">
|
176
|
+
<rdf:li rdf:resource="http://example.org/node2"/>
|
177
|
+
</rdf:Bag>
|
178
|
+
|
179
|
+
<rdf:Description rdf:aboutEach="#node">
|
180
|
+
<dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/">me</dc:rights>
|
181
|
+
|
182
|
+
</rdf:Description>
|
183
|
+
|
184
|
+
</rdf:RDF>
|
185
|
+
EOF
|
186
|
+
|
187
|
+
lambda do
|
188
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
189
|
+
end.should raise_error(RDF::ReaderError, /Obsolete attribute .*aboutEach/)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should raise an error if rdf:aboutEachPrefix is used, as per the negative parser test rdfms-abouteach-error002 (rdf:aboutEachPrefix attribute)" do
|
193
|
+
sampledoc = <<-EOF;
|
194
|
+
<?xml version="1.0" ?>
|
195
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
196
|
+
xmlns:eg="http://example.org/">
|
197
|
+
|
198
|
+
<rdf:Description rdf:about="http://example.org/node">
|
199
|
+
<eg:property>foo</eg:property>
|
200
|
+
</rdf:Description>
|
201
|
+
|
202
|
+
<rdf:Description rdf:aboutEachPrefix="http://example.org/">
|
203
|
+
<dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">me</dc:creator>
|
204
|
+
|
205
|
+
</rdf:Description>
|
206
|
+
|
207
|
+
</rdf:RDF>
|
208
|
+
EOF
|
209
|
+
|
210
|
+
lambda do
|
211
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
212
|
+
end.should raise_error(RDF::ReaderError, /Obsolete attribute .*aboutEachPrefix/)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should fail if given a non-ID as an ID (as per rdfcore-rdfms-rdf-id-error001)" do
|
216
|
+
sampledoc = <<-EOF;
|
217
|
+
<?xml version="1.0"?>
|
218
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
219
|
+
<rdf:Description rdf:ID='333-555-666' />
|
220
|
+
</rdf:RDF>
|
221
|
+
EOF
|
222
|
+
|
223
|
+
lambda do
|
224
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
225
|
+
end.should raise_error(RDF::ReaderError, /ID addtribute '.*' must be a NCName/)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should make sure that the value of rdf:ID attributes match the XML Name production (child-element version)" do
|
229
|
+
sampledoc = <<-EOF;
|
230
|
+
<?xml version="1.0" ?>
|
231
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
232
|
+
xmlns:eg="http://example.org/">
|
233
|
+
<rdf:Description>
|
234
|
+
<eg:prop rdf:ID="q:name" />
|
235
|
+
</rdf:Description>
|
236
|
+
</rdf:RDF>
|
237
|
+
EOF
|
238
|
+
|
239
|
+
lambda do
|
240
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
241
|
+
end.should raise_error(RDF::ReaderError, /ID addtribute '.*' must be a NCName/)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should make sure that the value of rdf:ID attributes match the XML Name production (data attribute version)" do
|
245
|
+
sampledoc = <<-EOF;
|
246
|
+
<?xml version="1.0" ?>
|
247
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
248
|
+
xmlns:eg="http://example.org/">
|
249
|
+
<rdf:Description rdf:ID="a/b" eg:prop="val" />
|
250
|
+
</rdf:RDF>
|
251
|
+
EOF
|
252
|
+
|
253
|
+
lambda do
|
254
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
255
|
+
end.should raise_error(RDF::ReaderError, "ID addtribute 'a/b' must be a NCName")
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should detect bad bagIDs" do
|
259
|
+
sampledoc = <<-EOF;
|
260
|
+
<?xml version="1.0" ?>
|
261
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
262
|
+
<rdf:Description rdf:bagID='333-555-666' />
|
263
|
+
</rdf:RDF>
|
264
|
+
EOF
|
265
|
+
|
266
|
+
lambda do
|
267
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
268
|
+
puts @debug
|
269
|
+
end.should raise_error(RDF::ReaderError, /Obsolete attribute .*bagID/)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context :reification do
|
274
|
+
it "should be able to reify according to §2.17 of RDF/XML Syntax Specification" do
|
275
|
+
sampledoc = <<-EOF;
|
276
|
+
<?xml version="1.0"?>
|
277
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
278
|
+
xmlns:ex="http://example.org/stuff/1.0/"
|
279
|
+
xml:base="http://example.org/triples/">
|
280
|
+
<rdf:Description rdf:about="http://example.org/">
|
281
|
+
<ex:prop rdf:ID="triple1">blah</ex:prop>
|
282
|
+
</rdf:Description>
|
283
|
+
</rdf:RDF>
|
284
|
+
EOF
|
285
|
+
|
286
|
+
triples = <<-EOF
|
287
|
+
<http://example.org/> <http://example.org/stuff/1.0/prop> \"blah\" .
|
288
|
+
<http://example.org/triples/#triple1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement> .
|
289
|
+
<http://example.org/triples/#triple1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject> <http://example.org/> .
|
290
|
+
<http://example.org/triples/#triple1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate> <http://example.org/stuff/1.0/prop> .
|
291
|
+
<http://example.org/triples/#triple1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#object> \"blah\" .
|
292
|
+
EOF
|
293
|
+
|
294
|
+
graph = parse(sampledoc, :base_uri => "http://example.com", :validate => true)
|
295
|
+
graph.should be_equivalent_graph(triples, :about => "http://example.com/", :trace => @debug)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# W3C Test suite from http://www.w3.org/2000/10/rdf-tests/rdfcore/
|
300
|
+
describe "w3c rdfcore tests" do
|
301
|
+
require 'rdf_test'
|
302
|
+
|
303
|
+
# Positive parser tests should raise errors.
|
304
|
+
describe "positive parser tests" do
|
305
|
+
Fixtures::TestCase::PositiveParserTest.each do |t|
|
306
|
+
next unless t.status == "APPROVED"
|
307
|
+
#next unless t.about =~ /rdfms-rdf-names-use/
|
308
|
+
#next unless t.name =~ /11/
|
309
|
+
#puts t.inspect
|
310
|
+
specify "#{t.name}: " + (t.description || "#{t.inputDocument} against #{t.outputDocument}") do
|
311
|
+
begin
|
312
|
+
graph = RDF::Graph.new << @reader.new(t.input,
|
313
|
+
:base_uri => t.inputDocument,
|
314
|
+
:validate => false,
|
315
|
+
:debug => t.debug)
|
316
|
+
|
317
|
+
# Parse result graph
|
318
|
+
#puts "parse #{self.outputDocument} as #{RDF::Reader.for(self.outputDocument)}"
|
319
|
+
format = detect_format(t.output)
|
320
|
+
output_graph = RDF::Graph.load(t.outputDocument, :format => format, :base_uri => t.inputDocument)
|
321
|
+
puts "result: #{CGI.escapeHTML(graph.dump(:ntriples))}" if ::RDF::N3::debug?
|
322
|
+
graph.should be_equivalent_graph(output_graph, t)
|
323
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
324
|
+
if t.inputDocument =~ %r(xml-literal|xml-canon)
|
325
|
+
pending("XMLLiteral canonicalization not implemented yet")
|
326
|
+
else
|
327
|
+
raise
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# Negative parser tests should raise errors.
|
335
|
+
describe "negative parser tests" do
|
336
|
+
Fixtures::TestCase::NegativeParserTest.each do |t|
|
337
|
+
next unless t.status == "APPROVED"
|
338
|
+
#next unless t.about =~ /rdfms-empty-property-elements/
|
339
|
+
#next unless t.name =~ /1/
|
340
|
+
#puts t.inspect
|
341
|
+
specify "test #{t.name}: " + (t.description || t.inputDocument) do
|
342
|
+
lambda do
|
343
|
+
RDF::Graph.new << @reader.new(t.input,
|
344
|
+
:base_uri => t.inputDocument,
|
345
|
+
:validate => true)
|
346
|
+
end.should raise_error(RDF::ReaderError)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def parse(input, options)
|
353
|
+
@debug = []
|
354
|
+
graph = RDF::Graph.new
|
355
|
+
@reader.new(input, options.merge(:debug => @debug)).each do |statement|
|
356
|
+
graph << statement
|
357
|
+
end
|
358
|
+
graph
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|