This repository has been archived by the owner on Jun 3, 2020. It is now read-only.
forked from ruby-rdf/spira
/
querying_spec.rb
174 lines (146 loc) · 7.43 KB
/
querying_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
require "spec_helper"
describe Spira do
before :all do
class ::LoadTest < Spira::Base
type FOAF.load_type
property :name, :predicate => FOAF.name
property :label, :predicate => RDFS.label
property :child, :predicate => FOAF.load_test, :type => 'LoadTest'
end
end
context "when querying repositories" do
before :each do
@repo = RDF::Repository.new
Spira.add_repository(:default, @repo)
@uri = RDF::URI('http://example.org/example')
end
it "should not attempt to query on instantiation" do
@repo.should_not_receive(:query)
test = @uri.as(LoadTest)
end
it "should not attempt query on property setting" do
@repo.should_not_receive(:query)
test = @uri.as(LoadTest)
test.name = "test"
end
it "should attempt to query on property getting" do
@repo.should_receive(:query).once.and_return([])
test = @uri.as(LoadTest)
name = test.name
end
it "should only query once for all properties" do
pending "no longer applies, but the current implementation should be reconsidered"
@repo.should_receive(:query).once.and_return([])
test = @uri.as(LoadTest)
name = test.name
label = test.label
end
it "should support :reload" do
test = @uri.as(LoadTest)
test.should respond_to :reload
end
it "should not touch the repository to reload" do
@repo.should_not_receive(:query)
test = @uri.as(LoadTest)
test.reload
end
it "should query the repository again after a reload" do
@repo.should_receive(:query).twice.and_return([])
test = @uri.as(LoadTest)
name = test.name
test.reload
name = test.name
end
context "for relations" do
before :each do
@child_uri = RDF::URI("http://example.org/example2")
@parent_statements = []
@child_statements = []
st = RDF::Statement.new(:subject => @uri, :predicate => RDF::FOAF.load_test, :object => @child_uri)
# @uri and @child_uri now point at each other
@repo << st
@parent_statements << st
st = RDF::Statement.new(:subject => @uri, :predicate => RDF::FOAF.name, :object => RDF::Literal.new("a name"))
@repo << st
@parent_statements << st
st = RDF::Statement.new(:subject => @uri, :predicate => RDF::RDFS.label, :object => RDF::Literal.new("a name"))
@repo << st
@parent_statements << st
st = RDF::Statement.new(:subject => @uri, :predicate => RDF.type, :object => RDF::FOAF.load_type)
@repo << st
@parent_statements << st
st = RDF::Statement.new(:subject => @child_uri, :predicate => RDF::FOAF.load_test, :object => @uri)
@repo << st
@child_statements << st
st = RDF::Statement.new(:subject => @child_uri, :predicate => RDF::FOAF.load_test, :object => @uri)
@repo << st
@child_statements << st
st = RDF::Statement.new(:subject => @child_uri, :predicate => RDF.type, :object => RDF::FOAF.load_type)
@repo << st
@child_statements << st
# We need this copy to return from mocks, as the return value is itself queried inside spira, confusing the count
end
it "should not query the repository when loading a parent and not accessing a child" do
name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.name).once.and_return(name_statements)
test = @uri.as(LoadTest)
test.name
end
it "should query the repository when loading a parent and accessing a field on a child" do
name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.load_test).once.and_return(@parent_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.name).once.and_return(name_statements)
test = @uri.as(LoadTest)
test.child.name
end
it "should not re-query to access a child twice" do
name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.load_test).once.and_return(@parent_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.name).once.and_return(name_statements)
test = @uri.as(LoadTest)
2.times { test.child.name }
end
it "should not re-query to access a child's parent from the child" do
name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.load_test).once.and_return(@parent_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.load_test).once.and_return(@child_statements)
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.name).once.and_return(name_statements)
test = @uri.as(LoadTest)
3.times do
test.child.child.name.should == "a name"
end
end
it "should re-query for children after a #reload" do
parent_name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
child_name_statements = @child_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.load_test).twice.and_return(@parent_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.load_test).twice.and_return(@child_statements)
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.name).twice.and_return(parent_name_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.name).twice.and_return(child_name_statements)
test = @uri.as(LoadTest)
test.child.child.name.should == "a name"
test.child.name.should be_nil
test.reload
test.child.child.name.should == "a name"
test.child.name.should be_nil
end
it "should not re-query to iterate by type twice" do
pending "no longer applies as the global cache is gone?"
# once to get the list of subjects, once for @uri, once for @child_uri,
# and once for the list of subjects again
parent_name_statements = @parent_statements.select {|st| st.predicate == RDF::FOAF.name }
child_name_statements = @child_statements.select {|st| st.predicate == RDF::FOAF.name }
@repo.should_receive(:query).with(:subject => @uri, :predicate => RDF::FOAF.name).twice.and_return(parent_name_statements)
@repo.should_receive(:query).with(:subject => @child_uri, :predicate => RDF::FOAF.name).twice.and_return(child_name_statements)
@types = RDF::Repository.new
@types.insert *@repo.statements.select{|s| s.predicate == RDF.type && s.object == RDF::FOAF.load_type}
@repo.should_receive(:query).with(:predicate => RDF.type, :object => RDF::FOAF.load_type).twice.and_return(@types.statements)
# need to map to touch a property on each to make sure they actually
# get loaded due to lazy evaluation
2.times do
LoadTest.each.map { |lt| lt.name }.size.should == 2
end
end
end
end
end