rdf-spec 0.1.10 → 0.2.0
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.
- data/README +3 -3
- data/VERSION +1 -1
- data/etc/doap.nt +23 -0
- data/lib/rdf/spec/countable.rb +42 -0
- data/lib/rdf/spec/enumerable.rb +253 -124
- data/lib/rdf/spec/graph.rb +10 -0
- data/lib/rdf/spec/literal.rb +4 -0
- data/lib/rdf/spec/matchers.rb +37 -2
- data/lib/rdf/spec/mutable.rb +86 -45
- data/lib/rdf/spec/queryable.rb +93 -36
- data/lib/rdf/spec/repository.rb +21 -10
- data/lib/rdf/spec/statement.rb +46 -6
- data/lib/rdf/spec/uri.rb +36 -11
- data/lib/rdf/spec/version.rb +3 -4
- data/spec/countable_spec.rb +12 -0
- data/spec/enumerable_spec.rb +1 -1
- data/spec/queryable_spec.rb +4 -4
- metadata +15 -13
data/lib/rdf/spec/graph.rb
CHANGED
@@ -41,6 +41,16 @@ share_as :RDF_Graph do
|
|
41
41
|
graph.context.should_not be_nil
|
42
42
|
graph.contexts.size.should == 1
|
43
43
|
end
|
44
|
+
|
45
|
+
it "should be #anonymous? with a Node context" do
|
46
|
+
graph = @new.call(RDF::Node.new)
|
47
|
+
graph.should be_anonymous
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not be #anonymous? with a URI context" do
|
51
|
+
graph = @new.call("http://rdf.rubyforge.org/")
|
52
|
+
graph.should_not be_anonymous
|
53
|
+
end
|
44
54
|
end
|
45
55
|
|
46
56
|
end
|
data/lib/rdf/spec/literal.rb
CHANGED
data/lib/rdf/spec/matchers.rb
CHANGED
@@ -17,6 +17,41 @@ module RDF; module Spec
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
define :be_countable do
|
21
|
+
match do |countable|
|
22
|
+
countable.should be_a_kind_of(RDF::Countable)
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
define :be_enumerable do
|
28
|
+
match do |enumerable|
|
29
|
+
enumerable.should be_a_kind_of(RDF::Enumerable)
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
define :be_an_enumerator do
|
35
|
+
match do |enumerator|
|
36
|
+
enumerator.should be_a_kind_of(RDF::Enumerator)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
define :be_queryable do
|
42
|
+
match do |enumerable|
|
43
|
+
enumerable.should be_a_kind_of(RDF::Queryable)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
define :be_mutable do
|
49
|
+
match do |enumerable|
|
50
|
+
enumerable.should be_a_kind_of(RDF::Mutable)
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
20
55
|
define :be_a_statement do
|
21
56
|
match do |statement|
|
22
57
|
statement.should be_instance_of(RDF::Statement)
|
@@ -90,7 +125,7 @@ module RDF; module Spec
|
|
90
125
|
|
91
126
|
define :have_properties do |base_uri, properties|
|
92
127
|
match do |vocabulary|
|
93
|
-
properties.map
|
128
|
+
properties.map { |p| p.to_sym }.each do |property|
|
94
129
|
vocabulary[property].should be_a_uri
|
95
130
|
vocabulary[property].to_s.should == "#{base_uri}#{property}"
|
96
131
|
#vocabulary.should respond_to(property) # FIXME
|
@@ -105,7 +140,7 @@ module RDF; module Spec
|
|
105
140
|
|
106
141
|
define :have_subclasses do |base_uri, klasses|
|
107
142
|
match do |vocabulary|
|
108
|
-
klasses.map
|
143
|
+
klasses.map { |k| k.to_sym }.each do |klass|
|
109
144
|
# TODO
|
110
145
|
end
|
111
146
|
true
|
data/lib/rdf/spec/mutable.rb
CHANGED
@@ -3,61 +3,65 @@ require 'rdf/spec'
|
|
3
3
|
require 'rdf/ntriples'
|
4
4
|
|
5
5
|
share_as :RDF_Mutable do
|
6
|
-
|
7
6
|
include RDF::Spec::Matchers
|
8
7
|
|
9
8
|
before :each do
|
10
|
-
raise '+@
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
raise '+@mutable+ must be defined in a before(:each) block' unless instance_variable_get('@mutable')
|
10
|
+
|
11
|
+
@filename = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'etc', 'doap.nt'))
|
12
|
+
|
13
|
+
@subject = RDF::URI('http://rubygems.org/gems/rdf')
|
14
|
+
@context = RDF::URI('http://example.org/context')
|
15
|
+
|
16
|
+
# Assume contexts are supported unless declared otherwise:
|
17
|
+
@supports_context = @mutable.respond_to?(:supports?) ? @mutable.supports?(:context) : true
|
14
18
|
end
|
15
19
|
|
16
20
|
it "should be empty initially" do
|
17
|
-
@
|
18
|
-
@
|
21
|
+
@mutable.empty?.should be_true
|
22
|
+
@mutable.count.should be_zero
|
19
23
|
end
|
20
24
|
|
21
25
|
it "should be readable" do
|
22
|
-
@
|
26
|
+
@mutable.readable?.should be_true
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should be writable" do
|
26
|
-
@
|
30
|
+
@mutable.writable?.should be_true
|
27
31
|
end
|
28
32
|
|
29
33
|
it "should be mutable" do
|
30
|
-
@
|
31
|
-
@
|
34
|
+
@mutable.immutable?.should be_false
|
35
|
+
@mutable.mutable?.should be_true
|
32
36
|
end
|
33
37
|
|
34
38
|
it "should support #load" do
|
35
|
-
@
|
39
|
+
@mutable.respond_to?(:load).should be_true
|
36
40
|
end
|
37
41
|
|
38
42
|
context "#load" do
|
39
43
|
it "should require an argument" do
|
40
|
-
lambda { @
|
44
|
+
lambda { @mutable.load }.should raise_error(ArgumentError)
|
41
45
|
end
|
42
46
|
|
43
47
|
it "should accept a string filename argument" do
|
44
|
-
lambda { @
|
48
|
+
lambda { @mutable.load(@filename) }.should_not raise_error(ArgumentError)
|
45
49
|
end
|
46
50
|
|
47
51
|
it "should accept an optional hash argument" do
|
48
|
-
lambda { @
|
52
|
+
lambda { @mutable.load(@filename,{}) }.should_not raise_error(ArgumentError)
|
49
53
|
end
|
50
54
|
|
51
55
|
it "should load statements" do
|
52
|
-
@
|
53
|
-
@
|
54
|
-
@
|
56
|
+
@mutable.load @filename
|
57
|
+
@mutable.size.should == File.readlines(@filename).size
|
58
|
+
@mutable.should have_subject @subject
|
55
59
|
end
|
56
60
|
|
57
61
|
it "should load statements with a context override" do
|
58
|
-
@
|
59
|
-
@
|
60
|
-
@
|
62
|
+
@mutable.load @filename, :context => @context
|
63
|
+
@mutable.should have_context @context
|
64
|
+
@mutable.query(:context => @context).size.should == @mutable.size
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
@@ -67,75 +71,112 @@ share_as :RDF_Mutable do
|
|
67
71
|
end
|
68
72
|
|
69
73
|
it "should support #insert" do
|
70
|
-
@
|
74
|
+
@mutable.should respond_to(:insert)
|
71
75
|
end
|
72
76
|
|
73
77
|
it "should not raise errors" do
|
74
|
-
lambda { @
|
78
|
+
lambda { @mutable.insert(@statements.first) }.should_not raise_error
|
75
79
|
end
|
76
80
|
|
77
81
|
it "should support inserting one statement at a time" do
|
78
|
-
@
|
79
|
-
@
|
82
|
+
@mutable.insert(@statements.first)
|
83
|
+
@mutable.should have_statement(@statements.first)
|
80
84
|
end
|
81
85
|
|
82
86
|
it "should support inserting multiple statements at a time" do
|
83
|
-
@
|
87
|
+
@mutable.insert(*@statements)
|
84
88
|
end
|
85
89
|
|
86
90
|
it "should insert statements successfully" do
|
87
|
-
@
|
88
|
-
@
|
91
|
+
@mutable.insert(*@statements)
|
92
|
+
@mutable.count.should == @statements.size
|
89
93
|
end
|
90
94
|
|
91
95
|
it "should not insert a statement twice" do
|
92
|
-
@
|
93
|
-
@
|
94
|
-
@
|
96
|
+
@mutable.insert(@statements.first)
|
97
|
+
@mutable.insert(@statements.first)
|
98
|
+
@mutable.count.should == 1
|
95
99
|
end
|
100
|
+
|
101
|
+
it "should treat statements with a different context as distinct" do
|
102
|
+
s1 = @statements.first.dup
|
103
|
+
s1.context = nil
|
104
|
+
s2 = @statements.first.dup
|
105
|
+
s2.context = RDF::URI.new("urn:context:1")
|
106
|
+
s3 = @statements.first.dup
|
107
|
+
s3.context = RDF::URI.new("urn:context:2")
|
108
|
+
@mutable.insert(s1)
|
109
|
+
@mutable.insert(s2)
|
110
|
+
@mutable.insert(s3)
|
111
|
+
# If contexts are not suported, all three are redundant
|
112
|
+
@mutable.count.should == (@supports_context ? 3 : 1)
|
113
|
+
end
|
114
|
+
|
96
115
|
end
|
97
116
|
|
98
117
|
context "when deleting statements" do
|
99
118
|
before :each do
|
100
119
|
@statements = RDF::NTriples::Reader.new(File.open(@filename)).to_a
|
101
|
-
@
|
120
|
+
@mutable.insert(*@statements)
|
102
121
|
end
|
103
122
|
|
104
123
|
it "should support #delete" do
|
105
|
-
@
|
124
|
+
@mutable.should respond_to(:delete)
|
106
125
|
end
|
107
126
|
|
108
127
|
it "should not raise errors" do
|
109
|
-
lambda { @
|
128
|
+
lambda { @mutable.delete(@statements.first) }.should_not raise_error
|
110
129
|
end
|
111
130
|
|
112
131
|
it "should support deleting one statement at a time" do
|
113
|
-
@
|
114
|
-
@
|
132
|
+
@mutable.delete(@statements.first)
|
133
|
+
@mutable.should_not have_statement(@statements.first)
|
115
134
|
end
|
116
135
|
|
117
136
|
it "should support deleting multiple statements at a time" do
|
118
|
-
@
|
119
|
-
@statements.find { |s| @
|
137
|
+
@mutable.delete(*@statements)
|
138
|
+
@statements.find { |s| @mutable.has_statement?(s) }.should be_false
|
120
139
|
end
|
121
140
|
|
122
141
|
it "should support wildcard deletions" do
|
123
142
|
# nothing deleted
|
124
143
|
require 'digest/sha1'
|
125
|
-
count = @
|
126
|
-
@
|
127
|
-
@
|
128
|
-
@
|
144
|
+
count = @mutable.count
|
145
|
+
@mutable.delete([nil, nil, random = Digest::SHA1.hexdigest(File.read(__FILE__))])
|
146
|
+
@mutable.should_not be_empty
|
147
|
+
@mutable.count.should == count
|
129
148
|
|
130
149
|
# everything deleted
|
131
|
-
@
|
132
|
-
@
|
150
|
+
@mutable.delete([nil, nil, nil])
|
151
|
+
@mutable.should be_empty
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should only delete statements when the context matches" do
|
155
|
+
# Setup three statements identical except for context
|
156
|
+
count = @mutable.count + (@supports_context ? 3 : 1)
|
157
|
+
s1 = RDF::Statement.new(@subject, RDF::URI.new("urn:predicate:1"), RDF::URI.new("urn:object:1"))
|
158
|
+
s2 = s1.dup
|
159
|
+
s2.context = RDF::URI.new("urn:context:1")
|
160
|
+
s3 = s1.dup
|
161
|
+
s3.context = RDF::URI.new("urn:context:2")
|
162
|
+
@mutable.insert(s1)
|
163
|
+
@mutable.insert(s2)
|
164
|
+
@mutable.insert(s3)
|
165
|
+
@mutable.count.should == count
|
166
|
+
|
167
|
+
# Delete one by one
|
168
|
+
@mutable.delete(s1)
|
169
|
+
@mutable.count.should == count - (@supports_context ? 1 : 1)
|
170
|
+
@mutable.delete(s2)
|
171
|
+
@mutable.count.should == count - (@supports_context ? 2 : 1)
|
172
|
+
@mutable.delete(s3)
|
173
|
+
@mutable.count.should == count - (@supports_context ? 3 : 1)
|
133
174
|
end
|
134
175
|
end
|
135
176
|
|
136
177
|
context "when clearing all statements" do
|
137
178
|
it "should support #clear" do
|
138
|
-
@
|
179
|
+
@mutable.should respond_to(:clear)
|
139
180
|
end
|
140
181
|
end
|
141
182
|
end
|
data/lib/rdf/spec/queryable.rb
CHANGED
@@ -5,53 +5,89 @@ share_as :RDF_Queryable do
|
|
5
5
|
include RDF::Spec::Matchers
|
6
6
|
|
7
7
|
before :each do
|
8
|
-
# RDF::Queryable cares about the contents of this file too much to let someone set it
|
9
|
-
@filename = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'etc', 'doap.nt'))
|
10
8
|
raise '+@queryable+ must be defined in a before(:each) block' unless instance_variable_get('@queryable')
|
11
|
-
|
9
|
+
|
10
|
+
@filename = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'etc', 'doap.nt'))
|
11
|
+
@statements = RDF::NTriples::Reader.new(File.open(@filename)).to_a
|
12
|
+
|
12
13
|
if @queryable.empty?
|
13
|
-
if @queryable.respond_to?(
|
14
|
-
@
|
14
|
+
if @queryable.respond_to?(:<<)
|
15
|
+
@statements.each { |statement| @queryable << statement }
|
15
16
|
else
|
16
|
-
raise "@queryable must
|
17
|
+
raise "@queryable must respond to #<< or be pre-populated with the statements in #{@filename} in a before(:each) block"
|
17
18
|
end
|
18
19
|
end
|
20
|
+
|
21
|
+
@subject = RDF::URI('http://rubygems.org/gems/rdf')
|
19
22
|
end
|
20
23
|
|
21
24
|
##
|
22
25
|
# @see RDF::Queryable#query
|
23
26
|
|
24
|
-
it "should
|
25
|
-
@queryable.respond_to
|
27
|
+
it "should respond to #query" do
|
28
|
+
@queryable.should respond_to(:query)
|
26
29
|
end
|
27
30
|
|
28
|
-
context "#query" do
|
31
|
+
context "#query when called" do
|
29
32
|
it "should require an argument" do
|
30
33
|
lambda { @queryable.query }.should raise_error(ArgumentError)
|
31
34
|
end
|
32
35
|
|
36
|
+
it "should accept a pattern argument" do
|
37
|
+
lambda { @queryable.query(RDF::Query::Pattern.new(nil, nil, nil)) }.should_not raise_error(ArgumentError)
|
38
|
+
lambda { @queryable.query(RDF::Query::Pattern.new(:s, :p, :o)) }.should_not raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept a statement argument" do
|
42
|
+
lambda { @queryable.query(RDF::Statement.new(nil, nil, nil)) }.should_not raise_error(ArgumentError)
|
43
|
+
end
|
44
|
+
|
33
45
|
it "should accept a triple argument" do
|
34
46
|
lambda { @queryable.query([nil, nil, nil]) }.should_not raise_error(ArgumentError)
|
35
47
|
end
|
36
48
|
|
49
|
+
it "should accept a quad argument" do
|
50
|
+
lambda { @queryable.query([nil, nil, nil, nil]) }.should_not raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
|
37
53
|
it "should accept a hash argument" do
|
38
54
|
lambda { @queryable.query({}) }.should_not raise_error(ArgumentError)
|
39
55
|
end
|
40
56
|
|
41
|
-
it "should
|
42
|
-
|
57
|
+
it "should not alter a given hash argument" do
|
58
|
+
query = {:subject => @subject, :predicate => RDF::DOAP.name, :object => RDF::FOAF.Person}
|
59
|
+
original_query = query.dup
|
60
|
+
@queryable.query(query)
|
61
|
+
query.should == original_query
|
43
62
|
end
|
44
63
|
|
45
|
-
it "should
|
46
|
-
lambda { @queryable.query(
|
47
|
-
|
64
|
+
it "should reject other kinds of arguments" do
|
65
|
+
lambda { @queryable.query(nil) }.should raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "#query when called with a block" do
|
70
|
+
it "should yield statements" do
|
71
|
+
@queryable.query([nil, nil, nil]) do |statement|
|
72
|
+
statement.should be_a_statement
|
73
|
+
end
|
48
74
|
end
|
75
|
+
end
|
49
76
|
|
50
|
-
|
51
|
-
|
77
|
+
context "#query when called without a block" do
|
78
|
+
it "should return an enumerator" do
|
79
|
+
@queryable.query([nil, nil, nil]).should be_a_kind_of(RDF::Enumerator)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return an enumerable enumerator" do
|
83
|
+
@queryable.query([nil, nil, nil]).should be_a_kind_of(RDF::Enumerable)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should return a queryable enumerator" do
|
87
|
+
@queryable.query([nil, nil, nil]).should be_a_kind_of(RDF::Queryable)
|
52
88
|
end
|
53
89
|
|
54
|
-
it "should return
|
90
|
+
it "should return statements" do
|
55
91
|
@queryable.query([nil, nil, nil]).each do |statement|
|
56
92
|
statement.should be_a_statement
|
57
93
|
end
|
@@ -61,7 +97,7 @@ share_as :RDF_Queryable do
|
|
61
97
|
@queryable.query([nil, nil, nil]).size.should == File.readlines(@filename).size
|
62
98
|
@queryable.query([@subject, nil, nil]).size.should == File.readlines(@filename).grep(/^<http:\/\/rubygems\.org\/gems\/rdf>/).size
|
63
99
|
@queryable.query([@subject, RDF::DOAP.name, nil]).size.should == 1
|
64
|
-
|
100
|
+
#@queryable.query([@subject, RDF::DOAP.developer, nil]).size.should == @queryable.query([nil, nil, RDF::FOAF.Person]).size # FIXME: assumes too much about the doap.nt data
|
65
101
|
@queryable.query([nil, nil, RDF::DOAP.Project]).size.should == 1
|
66
102
|
end
|
67
103
|
|
@@ -69,23 +105,44 @@ share_as :RDF_Queryable do
|
|
69
105
|
@queryable.query({}).size.should == File.readlines(@filename).size
|
70
106
|
@queryable.query(:subject => @subject) .size.should == File.readlines(@filename).grep(/^<http:\/\/rubygems\.org\/gems\/rdf>/).size
|
71
107
|
@queryable.query(:subject => @subject, :predicate => RDF::DOAP.name).size.should == 1
|
72
|
-
|
108
|
+
#@queryable.query(:subject => @subject, :predicate => RDF::DOAP.developer).size.should == @queryable.query(:object => RDF::FOAF.Person).size # FIXME: assumes too much about the doap.nt data
|
73
109
|
@queryable.query(:object => RDF::DOAP.Project).size.should == 1
|
74
110
|
end
|
111
|
+
end
|
75
112
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
113
|
+
##
|
114
|
+
# @see RDF::Queryable#query_pattern
|
115
|
+
|
116
|
+
it "should respond to #query_pattern" do
|
117
|
+
@queryable.should respond_to(:query_pattern)
|
118
|
+
end
|
119
|
+
|
120
|
+
context "#query_pattern when called" do
|
121
|
+
it "should require an argument" do
|
122
|
+
lambda { @queryable.send(:query_pattern) }.should raise_error(ArgumentError)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should call the given block" do
|
126
|
+
called = false
|
127
|
+
@queryable.send(:query_pattern, RDF::Query::Pattern.new) do |statement|
|
128
|
+
called = true
|
129
|
+
break
|
130
|
+
end
|
131
|
+
called.should be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should yield statements" do
|
135
|
+
@queryable.send(:query_pattern, RDF::Query::Pattern.new) do |statement|
|
136
|
+
statement.should be_a_statement
|
137
|
+
end
|
81
138
|
end
|
82
139
|
end
|
83
140
|
|
84
141
|
##
|
85
142
|
# @see RDF::Queryable#first
|
86
143
|
|
87
|
-
it "should
|
88
|
-
@queryable.respond_to
|
144
|
+
it "should respond to #first" do
|
145
|
+
@queryable.should respond_to(:first)
|
89
146
|
end
|
90
147
|
|
91
148
|
context "#first" do
|
@@ -119,8 +176,8 @@ share_as :RDF_Queryable do
|
|
119
176
|
##
|
120
177
|
# @see RDF::Queryable#first_subject
|
121
178
|
|
122
|
-
it "should
|
123
|
-
@queryable.respond_to
|
179
|
+
it "should respond to #first_subject" do
|
180
|
+
@queryable.should respond_to(:first_subject)
|
124
181
|
end
|
125
182
|
|
126
183
|
context "#first_subject" do
|
@@ -154,8 +211,8 @@ share_as :RDF_Queryable do
|
|
154
211
|
##
|
155
212
|
# @see RDF::Queryable#first_predicate
|
156
213
|
|
157
|
-
it "should
|
158
|
-
@queryable.respond_to
|
214
|
+
it "should respond to #first_predicate" do
|
215
|
+
@queryable.should respond_to(:first_predicate)
|
159
216
|
end
|
160
217
|
|
161
218
|
context "#first_predicate" do
|
@@ -189,8 +246,8 @@ share_as :RDF_Queryable do
|
|
189
246
|
##
|
190
247
|
# @see RDF::Queryable#first_object
|
191
248
|
|
192
|
-
it "should
|
193
|
-
@queryable.respond_to
|
249
|
+
it "should respond to #first_object" do
|
250
|
+
@queryable.should respond_to(:first_object)
|
194
251
|
end
|
195
252
|
|
196
253
|
context "#first_object" do
|
@@ -224,8 +281,8 @@ share_as :RDF_Queryable do
|
|
224
281
|
##
|
225
282
|
# @see RDF::Queryable#first_literal
|
226
283
|
|
227
|
-
it "should
|
228
|
-
@queryable.respond_to
|
284
|
+
it "should respond to #first_literal" do
|
285
|
+
@queryable.should respond_to(:first_literal)
|
229
286
|
end
|
230
287
|
|
231
288
|
context "#first_literal" do
|
@@ -266,8 +323,8 @@ share_as :RDF_Queryable do
|
|
266
323
|
##
|
267
324
|
# @see RDF::Queryable#first_value
|
268
325
|
|
269
|
-
it "should
|
270
|
-
@queryable.respond_to
|
326
|
+
it "should respond to #first_value" do
|
327
|
+
@queryable.should respond_to(:first_value)
|
271
328
|
end
|
272
329
|
|
273
330
|
context "#first_value" do
|