tripod 0.2.3 → 0.3.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/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