tripod 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/spec_helper.rb CHANGED
@@ -6,11 +6,13 @@ $LOAD_PATH.unshift(MODELS)
6
6
 
7
7
  require 'tripod'
8
8
  require 'rspec'
9
+ require 'webmock/rspec'
9
10
 
10
11
  RSpec.configure do |config|
11
12
  config.mock_with :rspec
12
13
 
13
14
  config.before(:each) do
15
+ WebMock.disable!
14
16
  # delete from all graphs.
15
17
  Tripod::SparqlClient::Update.update('
16
18
  # delete from default graph:
@@ -26,6 +28,7 @@ end
26
28
  Tripod.configure do |config|
27
29
  config.update_endpoint = 'http://127.0.0.1:3030/tripod-test/update'
28
30
  config.query_endpoint = 'http://127.0.0.1:3030/tripod-test/sparql'
31
+ config.data_endpoint = 'http://127.0.0.1:3030/tripod-test/data'
29
32
  end
30
33
 
31
34
  # Autoload every model for the test suite that sits in spec/app/models.
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+
3
+ describe Tripod::Criteria do
4
+
5
+ let(:person_criteria) do
6
+ c = Tripod::Criteria.new(Person)
7
+ end
8
+
9
+ let(:resource_criteria) do
10
+ c = Tripod::Criteria.new(Resource)
11
+ end
12
+
13
+ let(:john) do
14
+ p = Person.new('http://john', 'http://people')
15
+ p.name = "John"
16
+ p
17
+ end
18
+
19
+ let(:barry) do
20
+ p = Person.new('http://barry', 'http://people')
21
+ p.name = "Barry"
22
+ p
23
+ end
24
+
25
+ describe "#build_select_query" do
26
+
27
+ context "for a class with an rdf_type" do
28
+ it "should return a SELECT query based with an rdf type restriction" do
29
+ person_criteria.send(:build_select_query).should == "SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri a <http://person> } }"
30
+ end
31
+
32
+ context "and extra restrictions" do
33
+ before { person_criteria.where("[pattern]") }
34
+
35
+ it "should return a SELECT query with the extra restriction and rdf type restriction" do
36
+ person_criteria.send(:build_select_query).should == "SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri a <http://person> . [pattern] } }"
37
+ end
38
+ end
39
+ end
40
+
41
+ context "for a class without an rdf_type" do
42
+ it "should return a SELECT query without an rdf_type restriction" do
43
+ resource_criteria.send(:build_select_query).should == "SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }"
44
+ end
45
+
46
+ context "and extra restrictions" do
47
+ before { resource_criteria.where("[pattern]") }
48
+
49
+ it "should return a SELECT query with the extra restrictions" do
50
+ resource_criteria.send(:build_select_query).should == "SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o . [pattern] } }"
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#resources" do
57
+
58
+ before do
59
+ john.save!
60
+ barry.save!
61
+ end
62
+
63
+ context "with no extra restrictions" do
64
+ it "should return a set of hydrated objects for the type" do
65
+ person_criteria.resources.should == [john, barry]
66
+ end
67
+ end
68
+
69
+ context "with extra restrictions" do
70
+
71
+ before { person_criteria.where("?uri <http://name> 'John'") }
72
+
73
+ it "should return a set of hydrated objects for the type and restrictions" do
74
+ person_criteria.resources.should == [john]
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ describe "#first" do
81
+
82
+ before do
83
+ john.save!
84
+ barry.save!
85
+ end
86
+
87
+ it "should return the first resource for the criteria" do
88
+ person_criteria.first.should == john
89
+ end
90
+
91
+ it "should call Query.select with the 'first sparql'" do
92
+ sparql = Tripod::SparqlQuery.new(person_criteria.send(:build_select_query)).as_first_query_str
93
+ Tripod::SparqlClient::Query.should_receive(:select).with(sparql).and_call_original
94
+ person_criteria.first
95
+ end
96
+ end
97
+
98
+ describe "#count" do
99
+
100
+ before do
101
+ john.save!
102
+ barry.save!
103
+ end
104
+
105
+ it "should return a set of hydrated objects for the criteria" do
106
+ person_criteria.count.should == 2
107
+ person_criteria.where("?uri <http://name> 'John'").count.should ==1
108
+ end
109
+
110
+ it "should call Query.select with the 'count sparql'" do
111
+ sparql = Tripod::SparqlQuery.new(person_criteria.send(:build_select_query)).as_count_query_str
112
+ Tripod::SparqlClient::Query.should_receive(:select).with(sparql).and_call_original
113
+ person_criteria.count
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,65 @@
1
+ require "spec_helper"
2
+
3
+ describe Tripod::Criteria do
4
+
5
+ let(:person_criteria) { Tripod::Criteria.new(Person) }
6
+
7
+ let(:resource_criteria) { Tripod::Criteria.new(Resource) }
8
+
9
+ describe "#initialize" do
10
+
11
+ it "should set the resource class accessor" do
12
+ person_criteria.resource_class.should == Person
13
+ end
14
+
15
+ it "should initialize the extra clauses to a blank array" do
16
+ person_criteria.extra_clauses.should == []
17
+ end
18
+
19
+ context "with rdf_type set on the class" do
20
+ it "should initialize the where clauses to include a type restriction" do
21
+ person_criteria.where_clauses.should == ["?uri a <http://person>"]
22
+ end
23
+ end
24
+
25
+ context "with no rdf_type set on the class" do
26
+ it "should initialize the where clauses to ?uri ?p ?o" do
27
+ resource_criteria.where_clauses.should == ["?uri ?p ?o"]
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#where" do
33
+
34
+ it "should add the sparql snippet to the where clauses" do
35
+ resource_criteria.where("blah")
36
+ resource_criteria.where_clauses.should == ["?uri ?p ?o", "blah"]
37
+ end
38
+
39
+ it "should return an instance of Criteria" do
40
+ resource_criteria.where("blah").class == Tripod::Criteria
41
+ end
42
+
43
+ it "should return an instance of Criteria with the where clauses added" do
44
+ resource_criteria.where("blah").where_clauses.should == ["?uri ?p ?o", "blah"]
45
+ end
46
+
47
+ end
48
+
49
+ describe "#extras" do
50
+
51
+ it "should add the sparql snippet to the extra clauses" do
52
+ resource_criteria.extras("bleh")
53
+ resource_criteria.extra_clauses.should == ["bleh"]
54
+ end
55
+
56
+ it "should return an instance of Criteria" do
57
+ resource_criteria.extras("bleh").class == Tripod::Criteria
58
+ end
59
+
60
+ it "should return an instance of Criteria with the extra clauses added" do
61
+ resource_criteria.extras("bleh").extra_clauses.should == ["bleh"]
62
+ end
63
+ end
64
+
65
+ end
@@ -3,43 +3,25 @@ require "spec_helper"
3
3
  describe Tripod::Finders do
4
4
 
5
5
  let(:ric) do
6
- @ric_uri = 'http://ric'
7
- stmts = RDF::Graph.new
8
-
9
- stmt = RDF::Statement.new
10
- stmt.subject = RDF::URI.new(@ric_uri)
11
- stmt.predicate = RDF::URI.new('http://name')
12
- stmt.object = "ric"
13
- stmts << stmt
14
-
15
- stmt = RDF::Statement.new
16
- stmt.subject = RDF::URI.new(@ric_uri)
17
- stmt.predicate = RDF::URI.new('http://knows')
18
- stmt.object = RDF::URI.new('http://bill')
19
- stmts << stmt
20
-
21
- r = Person.new(@ric_uri)
22
- r.hydrate!(:graph => stmts)
23
- r.save
6
+ r = Person.new('http://example.com/people/id/ric')
7
+ r.name = "ric"
8
+ r.knows = RDF::URI.new("http://bill")
24
9
  r
25
10
  end
26
11
 
27
12
  let(:bill) do
28
- @bill_uri = 'http://bill'
29
- stmts = RDF::Graph.new
30
- stmt = RDF::Statement.new
31
- stmt.subject = RDF::URI.new(@bill_uri)
32
- stmt.predicate = RDF::URI.new('http://name')
33
- stmt.object = "bill"
34
- stmts << stmt
35
- b = Person.new(@bill_uri)
36
- b.hydrate!(:graph => stmts)
37
- b.save
13
+ b = Person.new('http://example.com/people/id/bill')
14
+ b.name = "bill"
38
15
  b
39
16
  end
40
17
 
41
18
  describe '.find' do
42
19
 
20
+ before do
21
+ ric.save!
22
+ bill.save!
23
+ end
24
+
43
25
  context 'when record exists' do
44
26
  let(:person) { Person.find(ric.uri) }
45
27
 
@@ -65,39 +47,77 @@ describe Tripod::Finders do
65
47
  end
66
48
  end
67
49
 
68
- context 'with a given graph URI' do
50
+ context 'with graph_uri supplied' do
51
+ it 'should use that graph to call new' do
52
+ ric # trigger the lazy load
53
+ Person.should_receive(:new).with(ric.uri, 'http://graphx').and_call_original
54
+ Person.find(ric.uri, "http://graphx")
55
+ end
56
+ end
57
+
58
+ context 'with no graph_uri supplied' do
59
+ it 'should look up the graph to call new' do
60
+ ric # trigger the lazy load
61
+ Person.should_receive(:new).with(ric.uri, Person._GRAPH_URI).and_call_original
62
+ Person.find(ric.uri, Person._GRAPH_URI)
63
+ end
64
+ end
65
+ end
69
66
 
67
+ describe ".all" do
68
+ it "should make and return a new criteria for the current class" do
69
+ Person.all.should == Tripod::Criteria.new(Person)
70
70
  end
71
71
  end
72
72
 
73
- describe '.where' do
73
+ describe ".where" do
74
+
75
+ let(:criteria) { Person.where("[pattern]") }
74
76
 
77
+ it "should make and return a criteria for the current class" do
78
+ criteria.class.should == Tripod::Criteria
79
+ end
80
+
81
+ it "should apply the where clause" do
82
+ criteria.where_clauses.should include("[pattern]")
83
+ end
84
+
85
+ end
86
+
87
+ describe "count" do
75
88
  before do
76
- # save these into the db
77
- bill
78
- ric
89
+ ric.save!
90
+ bill.save!
79
91
  end
80
92
 
81
- it 'returns an array of resources which match those in the db' do
82
- res = Person.where('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }')
83
- res.length.should == 2
84
- res.first.should == ric
85
- res.last.should == bill
93
+ it "should just call count on the all criteria" do
94
+ all_crit = Tripod::Criteria.new(Person)
95
+ Person.should_receive(:all).and_return(all_crit)
96
+ all_crit.should_receive(:count).and_call_original
97
+ Person.count
98
+ end
86
99
 
87
- res.first.name.should == "ric"
88
- res.first.knows.should == [RDF::URI.new("http://bill")]
100
+ it 'should return the count of all resources of this type' do
101
+ Person.count.should == 2
89
102
  end
103
+ end
90
104
 
91
- it 'uses the uri and graph variables if supplied' do
92
- res = Person.where('SELECT ?bob ?geoff WHERE { GRAPH ?geoff { ?bob ?p ?o } }', :uri_variable => 'bob', :graph_variable => 'geoff')
93
- res.length.should == 2
105
+ describe "first" do
106
+ before do
107
+ ric.save!
108
+ bill.save!
94
109
  end
95
110
 
96
- it "returns non-new records" do
97
- res = Person.where('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }')
98
- res.first.new_record?.should be_false
111
+ it "should just call count on the all criteria" do
112
+ all_crit = Tripod::Criteria.new(Person)
113
+ Person.should_receive(:all).and_return(all_crit)
114
+ all_crit.should_receive(:first).and_call_original
115
+ Person.first
99
116
  end
100
117
 
118
+ it 'should return the first resources of this type' do
119
+ Person.first.should == ric
120
+ end
101
121
  end
102
122
 
103
123
  end
@@ -21,8 +21,10 @@ describe Tripod::Resource do
21
21
  person.graph_uri.should == RDF::URI.new('http://graph')
22
22
  end
23
23
 
24
- it "sets the rdf type from the class" do
25
- person.rdf_type.should == 'http://person'
24
+ context "with rdf_type specified at class level" do
25
+ it "sets the rdf type from the class" do
26
+ person.rdf_type.to_s.should == 'http://person'
27
+ end
26
28
  end
27
29
 
28
30
  it "initialises a repo" do
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe Tripod::SparqlClient do
4
+ describe Data do
5
+ let(:data) { 'some-data-goes-here' }
6
+
7
+ describe "Data#append" do
8
+ it "should add the graph uri to the configured data endpoint" do
9
+ RestClient::Request.should_receive(:execute).with(hash_including(url: 'http://127.0.0.1:3030/tripod-test/data?graph=http://foo'))
10
+ Tripod::SparqlClient::Data.append('http://foo', data)
11
+ end
12
+
13
+ it "should send the data as the payload" do
14
+ RestClient::Request.should_receive(:execute).with(hash_including(payload: data))
15
+ Tripod::SparqlClient::Data.append('http://foo', data)
16
+ end
17
+
18
+ it "should HTTP POST the data" do
19
+ RestClient::Request.should_receive(:execute).with(hash_including(method: :post))
20
+ Tripod::SparqlClient::Data.append('http://foo', data)
21
+ end
22
+
23
+ context "which fails with a 400 error" do
24
+ before do
25
+ WebMock.enable!
26
+ stub_http_request(:post, 'http://127.0.0.1:3030/tripod-test/data?graph=http://foo').to_return(body: 'Error 400: Trousers missing', status: 400)
27
+ end
28
+
29
+ it "should raise a 'parse failed' exception" do
30
+ lambda { Tripod::SparqlClient::Data.append('http://foo', data) }.should raise_error(Tripod::Errors::BadDataRequest)
31
+ end
32
+
33
+ after do
34
+ WebMock.disable!
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "Data#replace" do
40
+ it "should HTTP PUT the data" do
41
+ RestClient::Request.should_receive(:execute).with(hash_including(method: :put))
42
+ Tripod::SparqlClient::Data.replace('http://foo', data)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,133 @@
1
+ require "spec_helper"
2
+
3
+ describe Tripod::SparqlQuery do
4
+
5
+ describe '#initialize' do
6
+ context 'given a query without prefixes' do
7
+ it 'should assign the given query to the body attribute' do
8
+ q = Tripod::SparqlQuery.new('SELECT xyz')
9
+ q.body.should == 'SELECT xyz'
10
+ end
11
+ end
12
+
13
+ context 'given a query with prefixes' do
14
+ it 'should separate the query into prefixes and body' do
15
+ q = Tripod::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
16
+ q.prefixes.should == 'PREFIX e: <http://example.com>'
17
+ q.body.should == 'SELECT xyz'
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "#has_prefixes?" do
23
+
24
+ context "for a query with prefixes" do
25
+ it "should return true" do
26
+ q = Tripod::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
27
+ q.has_prefixes?.should be_true
28
+ end
29
+ end
30
+
31
+ context "for a query without prefixes" do
32
+ it "should return false" do
33
+ q = Tripod::SparqlQuery.new('SELECT xyz')
34
+ q.has_prefixes?.should be_false
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ describe "#query_type" do
41
+
42
+ it 'should return :select given a SELECT query' do
43
+ q = Tripod::SparqlQuery.new('SELECT xyz')
44
+ q.query_type.should == :select
45
+ end
46
+
47
+ it 'should return :construct given a CONSTRUCT query' do
48
+ q = Tripod::SparqlQuery.new('CONSTRUCT <xyz>')
49
+ q.query_type.should == :construct
50
+ end
51
+
52
+ it 'should return :construct given a DESCRIBE query' do
53
+ q = Tripod::SparqlQuery.new('DESCRIBE <xyz>')
54
+ q.query_type.should == :describe
55
+ end
56
+
57
+ it 'should return :ask given an ASK query' do
58
+ q = Tripod::SparqlQuery.new('ASK <xyz>')
59
+ q.query_type.should == :ask
60
+ end
61
+
62
+ it "should return :unknown given an unknown type" do
63
+ q = Tripod::SparqlQuery.new('FOO <xyz>')
64
+ q.query_type.should == :unknown
65
+ end
66
+ end
67
+
68
+ describe '#extract_prefixes' do
69
+ it 'should return the prefixes and query body separately' do
70
+ q = Tripod::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
71
+ p, b = q.extract_prefixes
72
+ p.should == 'PREFIX e: <http://example.com>'
73
+ b.should == 'SELECT xyz'
74
+ end
75
+ end
76
+
77
+ describe '#as_count_query_str' do
78
+ context "for non-selects" do
79
+ it "should throw an exception" do
80
+ lambda {
81
+ q = Tripod::SparqlQuery.new('ASK { ?s ?p ?o }')
82
+ q.as_count_query_str
83
+ }.should raise_error(Tripod::SparqlQueryError)
84
+ end
85
+ end
86
+
87
+ context "for selects" do
88
+ context 'without prefixes' do
89
+ it "should return a new SparqlQuery with the original query wrapped in a count" do
90
+ q = Tripod::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
91
+ q.as_count_query_str.should == 'SELECT COUNT(*) { SELECT ?s WHERE { ?s ?p ?o } }'
92
+ end
93
+ end
94
+
95
+ context 'with prefixes' do
96
+ it "should move the prefixes to the start" do
97
+ q = Tripod::SparqlQuery.new('PREFIX e: <http://example.com> SELECT ?s WHERE { ?s ?p ?o }')
98
+ q.as_count_query_str.should == 'PREFIX e: <http://example.com> SELECT COUNT(*) { SELECT ?s WHERE { ?s ?p ?o } }'
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#as_first_query_str" do
105
+ context "for non-selects" do
106
+ it "should throw an exception" do
107
+ lambda {
108
+ q = Tripod::SparqlQuery.new('ASK { ?s ?p ?o }')
109
+ q.as_first_query_str
110
+ }.should raise_error(Tripod::SparqlQueryError)
111
+ end
112
+ end
113
+
114
+ context "for selects" do
115
+ context 'without prefixes' do
116
+ it "should return a new SparqlQuery with the original query wrapped in a count" do
117
+ q = Tripod::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
118
+ q.as_first_query_str.should == 'SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 1'
119
+ end
120
+ end
121
+
122
+ context 'with prefixes' do
123
+ it "should move the prefixes to the start" do
124
+ q = Tripod::SparqlQuery.new('PREFIX e: <http://example.com> SELECT ?s WHERE { ?s ?p ?o }')
125
+ q.as_first_query_str.should == 'PREFIX e: <http://example.com> SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 1'
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+
133
+ end