publish_my_data 0.0.1
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/MIT-LICENSE +20 -0
- data/README.md +37 -0
- data/Rakefile +41 -0
- data/app/assets/javascripts/publish_my_data/application.js +15 -0
- data/app/assets/javascripts/publish_my_data/resources.js +2 -0
- data/app/assets/stylesheets/publish_my_data/application.css +13 -0
- data/app/assets/stylesheets/publish_my_data/resources.css +4 -0
- data/app/controllers/publish_my_data/application_controller.rb +49 -0
- data/app/controllers/publish_my_data/datasets_controller.rb +48 -0
- data/app/controllers/publish_my_data/errors_controller.rb +9 -0
- data/app/controllers/publish_my_data/home_controller.rb +4 -0
- data/app/controllers/publish_my_data/resources_controller.rb +103 -0
- data/app/controllers/publish_my_data/sparql_controller.rb +50 -0
- data/app/helpers/publish_my_data/application_helper.rb +4 -0
- data/app/helpers/publish_my_data/resources_helper.rb +28 -0
- data/app/helpers/publish_my_data/sparql_helper.rb +7 -0
- data/app/models/publish_my_data/concept_scheme.rb +5 -0
- data/app/models/publish_my_data/dataset.rb +61 -0
- data/app/models/publish_my_data/ontology.rb +5 -0
- data/app/models/publish_my_data/rdf_type.rb +6 -0
- data/app/models/publish_my_data/resource.rb +21 -0
- data/app/views/layouts/publish_my_data/application.html.erb +14 -0
- data/app/views/layouts/publish_my_data/error.html.erb +3 -0
- data/app/views/publish_my_data/datasets/index.html.erb +20 -0
- data/app/views/publish_my_data/datasets/show.html.erb +18 -0
- data/app/views/publish_my_data/datasets/themes.html.erb +3 -0
- data/app/views/publish_my_data/errors/not_found.html.erb +1 -0
- data/app/views/publish_my_data/resources/_predicates_table.html.erb +22 -0
- data/app/views/publish_my_data/resources/_predicates_table_head.html.erb +6 -0
- data/app/views/publish_my_data/resources/_resource_formats.html.erb +11 -0
- data/app/views/publish_my_data/resources/_uri_and_label.html.erb +3 -0
- data/app/views/publish_my_data/resources/index.html.erb +39 -0
- data/app/views/publish_my_data/resources/show.html.erb +3 -0
- data/app/views/publish_my_data/sparql/_ask_formats.html.erb +3 -0
- data/app/views/publish_my_data/sparql/_construct_formats.html.erb +3 -0
- data/app/views/publish_my_data/sparql/_describe_formats.html.erb +1 -0
- data/app/views/publish_my_data/sparql/_error_message.html.erb +3 -0
- data/app/views/publish_my_data/sparql/_form.html.erb +4 -0
- data/app/views/publish_my_data/sparql/_formats.html.erb +6 -0
- data/app/views/publish_my_data/sparql/_pagination.html.erb +6 -0
- data/app/views/publish_my_data/sparql/_results.html.erb +5 -0
- data/app/views/publish_my_data/sparql/_results_data.html.erb +4 -0
- data/app/views/publish_my_data/sparql/_select_formats.html.erb +3 -0
- data/app/views/publish_my_data/sparql/endpoint.html.erb +10 -0
- data/config/initializers/tripod.rb +5 -0
- data/config/initializers/vocabularies.rb +1 -0
- data/config/routes.rb +33 -0
- data/lib/publish_my_data.rb +43 -0
- data/lib/publish_my_data/engine.rb +9 -0
- data/lib/publish_my_data/renderers.rb +44 -0
- data/lib/publish_my_data/sparql_query.rb +117 -0
- data/lib/publish_my_data/sparql_query_result.rb +49 -0
- data/lib/publish_my_data/version.rb +3 -0
- data/lib/tasks/publish_my_data_tasks.rake +4 -0
- data/spec/controllers/publish_my_data/datasets_controller_spec.rb +190 -0
- data/spec/controllers/publish_my_data/resources_controller_spec.rb +399 -0
- data/spec/controllers/publish_my_data/sparql_controller_spec.rb +172 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +68 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +38 -0
- data/spec/dummy/config/environments/production.rb +65 -0
- data/spec/dummy/config/environments/test.rb +41 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +10 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/log/development.log +211 -0
- data/spec/dummy/log/test.log +105012 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/dataset_factories.rb +12 -0
- data/spec/factories/property_factories.rb +13 -0
- data/spec/factories/resource_factories.rb +37 -0
- data/spec/features/running_a_sparql_query_spec.rb +324 -0
- data/spec/features/uri_dereferencing_flow_spec.rb +61 -0
- data/spec/features/uri_dereferencing_spec.rb +89 -0
- data/spec/features/viewing_a_def_spec.rb +45 -0
- data/spec/features/viewing_a_doc_spec.rb +124 -0
- data/spec/features/viewing_resource_not_in_our_domain_spec.rb +31 -0
- data/spec/lib/publish_my_data/sparql_query_spec.rb +495 -0
- data/spec/models/publish_my_data/dataset_spec.rb +29 -0
- data/spec/models/publish_my_data/resource_spec.rb +23 -0
- data/spec/renderers/publish_my_data/renderers_spec.rb +79 -0
- data/spec/spec_helper.rb +53 -0
- metadata +242 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "A visitor dereferences a uri then asks for a format" do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
@resource = FactoryGirl.create(:yuri_unicorn_resource)
|
|
7
|
+
visit @resource.uri.to_s
|
|
8
|
+
click_link 'RDF/XML'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should show the right serlialisation, on the doc page url (+format)" do
|
|
12
|
+
page.source.should == @resource.to_rdf
|
|
13
|
+
page.current_url.should == @resource.uri.to_s.sub(/\/id\//,'/doc/') + ".rdf"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "A visitor dereferences a uri then clicks on a link for another resource" do
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
@yuri = FactoryGirl.create(:yuri_unicorn_resource)
|
|
22
|
+
@boris = FactoryGirl.create(:boris_unicorn_resource)
|
|
23
|
+
@foo_county = FactoryGirl.build(:foreign_resource)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "in our domain" do
|
|
27
|
+
before do
|
|
28
|
+
visit @boris.uri.to_s
|
|
29
|
+
click_link "Yuri The Unicorn" # via the knows association
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should render the doc page for that uri" do
|
|
33
|
+
page.current_url.should == @yuri.uri.to_s.sub(/\/id\//,'/doc/')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "not in our domain" do
|
|
38
|
+
|
|
39
|
+
context "where we have data" do
|
|
40
|
+
before do
|
|
41
|
+
@foo_county.save!
|
|
42
|
+
visit @boris.uri.to_s
|
|
43
|
+
click_link @foo_county.label # via the resides-in association
|
|
44
|
+
end
|
|
45
|
+
it "should render the show page for that uri" do
|
|
46
|
+
page.current_url.should == "http://pmdtest.dev/resource?uri=#{CGI.escape(@foo_county.uri.to_s)}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "where we don't have data" do
|
|
51
|
+
before do
|
|
52
|
+
visit @boris.uri.to_s
|
|
53
|
+
click_link @foo_county.uri.to_s # via the resides-in association
|
|
54
|
+
end
|
|
55
|
+
it "should redirect away" do
|
|
56
|
+
page.current_url.should == @foo_county.uri.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "A visitor dereferencing a URI" do
|
|
4
|
+
|
|
5
|
+
context "where a resource exists in the database for that URI" do
|
|
6
|
+
before do
|
|
7
|
+
@resource = FactoryGirl.create(:yuri_unicorn_resource)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'for HTML format' do
|
|
11
|
+
it "should redirect to the doc page for that URI" do
|
|
12
|
+
visit @resource.uri.to_s
|
|
13
|
+
page.current_url.should == @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
14
|
+
page.should have_content @resource.uri.to_s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'with a JSON accept header' do
|
|
19
|
+
before do
|
|
20
|
+
page.driver.header 'Accept','application/json'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should return the json serialisation of the resource" do
|
|
24
|
+
visit @resource.uri.to_s
|
|
25
|
+
page.source.should == @resource.to_json
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'with a turtle accept header' do
|
|
30
|
+
before do
|
|
31
|
+
page.driver.header 'Accept','text/turtle'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should return the turtle serialisation of the resource" do
|
|
35
|
+
visit @resource.uri.to_s
|
|
36
|
+
page.source.should == @resource.to_ttl
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'with an n-triples accept header' do
|
|
41
|
+
before do
|
|
42
|
+
page.driver.header 'Accept','application/n-triples'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should return the ntriples serialisation of the resource" do
|
|
46
|
+
visit @resource.uri.to_s
|
|
47
|
+
page.source.should == @resource.to_nt
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'with an RDF/XML accept header' do
|
|
52
|
+
before do
|
|
53
|
+
page.driver.header 'Accept','application/rdf+xml'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should return the rdf serialisation of the resource" do
|
|
57
|
+
visit @resource.uri.to_s
|
|
58
|
+
page.source.should == @resource.to_rdf
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "where a resource doesn't exist in the database for that URI" do
|
|
64
|
+
|
|
65
|
+
context 'for HTML format' do
|
|
66
|
+
|
|
67
|
+
it "should render the 404 page with the right status" do
|
|
68
|
+
visit 'http://pmdtest.dev/foo/'
|
|
69
|
+
page.status_code.should == 404
|
|
70
|
+
page.should have_content 'Not found'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'for data format' do
|
|
76
|
+
before do
|
|
77
|
+
page.driver.header 'Accept','application/rdf+xml'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should 404, with blank response" do
|
|
81
|
+
visit 'http://pmdtest.dev/foo/'
|
|
82
|
+
page.status_code.should == 404
|
|
83
|
+
page.source.should be_blank
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "A visitor viewing a def" do
|
|
4
|
+
|
|
5
|
+
context "where a resource exists in the database for that URI" do
|
|
6
|
+
before do
|
|
7
|
+
@resource = FactoryGirl.create(:mean_result)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'for HTML format' do
|
|
11
|
+
it "should render a page about it (no redirect)" do
|
|
12
|
+
visit @resource.uri.to_s
|
|
13
|
+
page.current_url.should eq(@resource.uri.to_s)
|
|
14
|
+
page.should have_content @resource.uri.to_s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'for an alternative format' do
|
|
19
|
+
|
|
20
|
+
context 'with accept header' do
|
|
21
|
+
|
|
22
|
+
before do
|
|
23
|
+
page.driver.header 'Accept','application/n-triples'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should respond with the right format' do
|
|
27
|
+
visit @resource.uri.to_s
|
|
28
|
+
page.source.should == @resource.to_nt
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'with format extension' do
|
|
34
|
+
|
|
35
|
+
it 'should respond with the right format' do
|
|
36
|
+
visit @resource.uri.to_s + '.rdf'
|
|
37
|
+
page.source.should == @resource.to_rdf
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "A visitor navigating straight to the /doc/ page" do
|
|
4
|
+
|
|
5
|
+
context "where a resource exists in the database for the corresponding URI" do
|
|
6
|
+
before do
|
|
7
|
+
@resource = FactoryGirl.create(:yuri_unicorn_resource)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'for HTML format' do
|
|
11
|
+
|
|
12
|
+
it "should render the doc page succesfully" do
|
|
13
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
14
|
+
page.should have_content @resource.uri.to_s
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'for JSON format' do
|
|
20
|
+
|
|
21
|
+
context 'with accept header' do
|
|
22
|
+
|
|
23
|
+
before do
|
|
24
|
+
page.driver.header 'Accept','application/json'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should respond with JSON' do
|
|
28
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
29
|
+
page.source.should == @resource.to_json
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'with format extension' do
|
|
35
|
+
|
|
36
|
+
it 'should respond with JSON' do
|
|
37
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/') + '.json'
|
|
38
|
+
page.source.should == @resource.to_json
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'for turtle format' do
|
|
46
|
+
|
|
47
|
+
context 'with accept header' do
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
page.driver.header 'Accept','text/turtle'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'should respond with turtle' do
|
|
54
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
55
|
+
page.source.should == @resource.to_ttl
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'with format extension' do
|
|
61
|
+
|
|
62
|
+
it 'should respond with turtle' do
|
|
63
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/') + '.ttl'
|
|
64
|
+
page.source.should == @resource.to_ttl
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'for n-triples format' do
|
|
72
|
+
|
|
73
|
+
context 'with accept header' do
|
|
74
|
+
|
|
75
|
+
before do
|
|
76
|
+
page.driver.header 'Accept','application/n-triples'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'should respond with n-triples' do
|
|
80
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
81
|
+
page.source.should == @resource.to_nt
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'with format extension' do
|
|
87
|
+
|
|
88
|
+
it 'should respond with turtle' do
|
|
89
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/') + '.nt'
|
|
90
|
+
page.source.should == @resource.to_nt
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context 'for rdf/xml format' do
|
|
98
|
+
|
|
99
|
+
context 'with accept header' do
|
|
100
|
+
|
|
101
|
+
before do
|
|
102
|
+
page.driver.header 'Accept','application/rdf+xml'
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should respond with rdf' do
|
|
106
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/')
|
|
107
|
+
page.source.should == @resource.to_rdf
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context 'with format extension' do
|
|
113
|
+
|
|
114
|
+
it 'should respond with rdf' do
|
|
115
|
+
visit @resource.uri.to_s.sub(/\/id\//,'/doc/') + '.rdf'
|
|
116
|
+
page.source.should == @resource.to_rdf
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "A visitor viewing a resource not in our domain" do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
@foreign_resource = FactoryGirl.build(:foreign_resource)
|
|
7
|
+
@url = "http://pmdtest.dev/resource?uri=#{CGI.escape(@foreign_resource.uri.to_s)}"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'where we have data about it' do
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
@foreign_resource.save!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should show a page about that resource" do
|
|
17
|
+
visit @url
|
|
18
|
+
page.current_url.should eq(@url)
|
|
19
|
+
page.should have_content @foreign_resource.uri.to_s
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "where we don't have data about it" do
|
|
24
|
+
|
|
25
|
+
it "should redirect away" do
|
|
26
|
+
visit @url
|
|
27
|
+
page.current_url.should eq(@foreign_resource.uri.to_s)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module PublishMyData
|
|
4
|
+
|
|
5
|
+
describe SparqlQuery do
|
|
6
|
+
|
|
7
|
+
describe '#initialize' do
|
|
8
|
+
context 'given a query without prefixes' do
|
|
9
|
+
it 'should assign the given query to the body attribute' do
|
|
10
|
+
q = PublishMyData::SparqlQuery.new('SELECT xyz')
|
|
11
|
+
q.body.should == 'SELECT xyz'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'given a query with prefixes' do
|
|
16
|
+
it 'should separate the query into prefixes and body' do
|
|
17
|
+
q = PublishMyData::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
|
|
18
|
+
q.prefixes.should == 'PREFIX e: <http://example.com>'
|
|
19
|
+
q.body.should == 'SELECT xyz'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#has_prefixes?" do
|
|
25
|
+
|
|
26
|
+
context "for a query with prefixes" do
|
|
27
|
+
it "should return true" do
|
|
28
|
+
q = PublishMyData::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
|
|
29
|
+
q.has_prefixes?.should be_true
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "for a query without prefixes" do
|
|
34
|
+
it "should return false" do
|
|
35
|
+
q = PublishMyData::SparqlQuery.new('SELECT xyz')
|
|
36
|
+
q.has_prefixes?.should be_false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#query_type" do
|
|
43
|
+
|
|
44
|
+
it 'should return :select given a SELECT query' do
|
|
45
|
+
q = PublishMyData::SparqlQuery.new('SELECT xyz')
|
|
46
|
+
q.query_type.should == :select
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'should return :construct given a CONSTRUCT query' do
|
|
50
|
+
q = PublishMyData::SparqlQuery.new('CONSTRUCT <xyz>')
|
|
51
|
+
q.query_type.should == :construct
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should return :construct given a DESCRIBE query' do
|
|
55
|
+
q = PublishMyData::SparqlQuery.new('DESCRIBE <xyz>')
|
|
56
|
+
q.query_type.should == :describe
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'should return :ask given an ASK query' do
|
|
60
|
+
q = PublishMyData::SparqlQuery.new('ASK <xyz>')
|
|
61
|
+
q.query_type.should == :ask
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should return :unknown given an unknown type" do
|
|
65
|
+
q = PublishMyData::SparqlQuery.new('FOO <xyz>')
|
|
66
|
+
q.query_type.should == :unknown
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '#extract_prefixes' do
|
|
71
|
+
it 'should return the prefixes and query body separately' do
|
|
72
|
+
q = PublishMyData::SparqlQuery.new('PREFIX e: <http://example.com> SELECT xyz')
|
|
73
|
+
p, b = q.extract_prefixes
|
|
74
|
+
p.should == 'PREFIX e: <http://example.com>'
|
|
75
|
+
b.should == 'SELECT xyz'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "#execute" do
|
|
80
|
+
|
|
81
|
+
# load some data
|
|
82
|
+
before do
|
|
83
|
+
@yuri = FactoryGirl.create(:yuri_unicorn_resource)
|
|
84
|
+
@boris = FactoryGirl.create(:boris_unicorn_resource)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "with a SELECT query" do
|
|
88
|
+
|
|
89
|
+
before do
|
|
90
|
+
@query_str = 'SELECT * WHERE {?s ?p ?o}'
|
|
91
|
+
@q = PublishMyData::SparqlQuery.new(@query_str)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should call Tripod::SparqlClient::Query.select with the right args" do
|
|
95
|
+
Tripod::SparqlClient::Query.should_receive(:select).with(@query_str, @q.send(:select_format_str)).and_call_original
|
|
96
|
+
@q.execute
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should return some data in a SparqlQueryResult object" do
|
|
100
|
+
result = @q.execute
|
|
101
|
+
result.class.should == SparqlQueryResult
|
|
102
|
+
result.to_s.should_not be_blank
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "with an ASK query" do
|
|
108
|
+
|
|
109
|
+
before do
|
|
110
|
+
@query_str = 'ASK {?s ?p ?o}'
|
|
111
|
+
@q = PublishMyData::SparqlQuery.new(@query_str)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should call Tripod::SparqlClient::Query.ask with the right args" do
|
|
115
|
+
Tripod::SparqlClient::Query.should_receive(:ask).with(@query_str, @q.send(:ask_format_str)).and_call_original
|
|
116
|
+
@q.execute
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should return some data in a SparqlQueryResult object" do
|
|
120
|
+
result = @q.execute
|
|
121
|
+
result.class.should == SparqlQueryResult
|
|
122
|
+
result.to_s.should_not be_blank
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "with a construct query" do
|
|
128
|
+
|
|
129
|
+
before do
|
|
130
|
+
@query_str = 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'
|
|
131
|
+
@q = PublishMyData::SparqlQuery.new(@query_str)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should call Tripod::SparqlClient::Query.construct with the right args" do
|
|
135
|
+
Tripod::SparqlClient::Query.should_receive(:construct).with(@query_str, @q.send(:construct_or_describe_header)).and_call_original
|
|
136
|
+
@q.execute
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should return some data in a SparqlQueryResult object" do
|
|
140
|
+
result = @q.execute
|
|
141
|
+
result.class.should == SparqlQueryResult
|
|
142
|
+
result.to_s.should_not be_blank
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context "with a DESCRIBE query" do
|
|
148
|
+
|
|
149
|
+
before do
|
|
150
|
+
@query_str = "DESCRIBE <#{@yuri.uri.to_s}>"
|
|
151
|
+
@q = PublishMyData::SparqlQuery.new(@query_str)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "should call Tripod::SparqlClient::Query.select with the right args" do
|
|
155
|
+
Tripod::SparqlClient::Query.should_receive(:describe).with(@query_str, @q.send(:construct_or_describe_header)).and_call_original
|
|
156
|
+
@q.execute
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should return some data in a SparqlQueryResult object" do
|
|
160
|
+
result = @q.execute
|
|
161
|
+
result.class.should == SparqlQueryResult
|
|
162
|
+
result.to_s.should_not be_blank
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
context "with an unknown query type" do
|
|
167
|
+
before do
|
|
168
|
+
@query_str = "FOOBAR <#{@yuri.uri.to_s}>"
|
|
169
|
+
@q = PublishMyData::SparqlQuery.new(@query_str)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should raise an exception" do
|
|
173
|
+
lambda { @q.execute }.should raise_error( SparqlQueryExecutionException )
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "where data is too large to return" do
|
|
178
|
+
before do
|
|
179
|
+
PublishMyData::SparqlQueryResult.any_instance.should_receive(:length).at_least(:once).and_return(5.megabytes)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should raise a SparqlResponseTooLargeException" do
|
|
183
|
+
query_str = 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'
|
|
184
|
+
q = PublishMyData::SparqlQuery.new(query_str)
|
|
185
|
+
lambda {
|
|
186
|
+
q.execute
|
|
187
|
+
}.should raise_error PublishMyData::SparqlQueryResultTooLargeException
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context "with a syntax error in the query" do
|
|
192
|
+
|
|
193
|
+
context "for query without a parent" do
|
|
194
|
+
it "should return the error from this query" do
|
|
195
|
+
query_str = "SELECT * WHERE ?s ?p ?o}"
|
|
196
|
+
q = PublishMyData::SparqlQuery.new(query_str)
|
|
197
|
+
lambda {
|
|
198
|
+
q.execute
|
|
199
|
+
}.should raise_error(
|
|
200
|
+
PublishMyData::SparqlQueryExecutionException, /line 1, column 16/
|
|
201
|
+
)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "for a query with a parent" do
|
|
206
|
+
it "should return the error from the original query" do
|
|
207
|
+
query_str = "SELECT * WHERE ?s ?p ?o}"
|
|
208
|
+
q = PublishMyData::SparqlQuery.new(query_str)
|
|
209
|
+
lambda {
|
|
210
|
+
q.count
|
|
211
|
+
}.should raise_error(
|
|
212
|
+
PublishMyData::SparqlQueryExecutionException, /line 1, column 16/
|
|
213
|
+
)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "#select_format_str" do
|
|
221
|
+
|
|
222
|
+
before do
|
|
223
|
+
@query_str = 'SELECT xyz'
|
|
224
|
+
end
|
|
225
|
+
context "where the request format is not specified" do
|
|
226
|
+
it "should return 'text'" do
|
|
227
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
228
|
+
q.send(:select_format_str).should == "text"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
context "where the request format is html" do
|
|
233
|
+
it "should return 'text'" do
|
|
234
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
235
|
+
q.send(:select_format_str).should == "text"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
context "where the request format is text" do
|
|
240
|
+
it "should return 'csv'" do
|
|
241
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :text)
|
|
242
|
+
q.send(:select_format_str).should == "text"
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context "where the request format is json" do
|
|
247
|
+
it "should return 'json'" do
|
|
248
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :json)
|
|
249
|
+
q.send(:select_format_str).should == "json"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
context "where the request format is csv" do
|
|
254
|
+
it "should return 'csv'" do
|
|
255
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :csv)
|
|
256
|
+
q.send(:select_format_str).should == "csv"
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
context "where the request format is xml" do
|
|
261
|
+
it "should return 'xml'" do
|
|
262
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :xml)
|
|
263
|
+
q.send(:select_format_str).should == "xml"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
context "where the request format is something random" do
|
|
268
|
+
it "should return 'text'" do
|
|
269
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :bananas)
|
|
270
|
+
q.send(:select_format_str).should == "text"
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
describe "#ask_format_str" do
|
|
276
|
+
|
|
277
|
+
before do
|
|
278
|
+
@query_str = 'ASK xyz'
|
|
279
|
+
end
|
|
280
|
+
context "where the request format is not specified" do
|
|
281
|
+
it "should return 'text'" do
|
|
282
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
283
|
+
q.send(:ask_format_str).should == "text"
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context "where the request format is html" do
|
|
288
|
+
it "should return 'text'" do
|
|
289
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
290
|
+
q.send(:ask_format_str).should == "text"
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
context "where the request format is csv" do
|
|
295
|
+
it "should return 'csv'" do
|
|
296
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :text)
|
|
297
|
+
q.send(:ask_format_str).should == "text"
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
context "where the request format is json" do
|
|
302
|
+
it "should return 'json'" do
|
|
303
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :json)
|
|
304
|
+
q.send(:ask_format_str).should == "json"
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
context "where the request format is xml" do
|
|
309
|
+
it "should return 'xml'" do
|
|
310
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :xml)
|
|
311
|
+
q.send(:ask_format_str).should == "xml"
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
context "where the request format is something random" do
|
|
316
|
+
it "should return 'text'" do
|
|
317
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :bananas)
|
|
318
|
+
q.send(:ask_format_str).should == "text"
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
describe "#construct_or_describe_header" do
|
|
324
|
+
|
|
325
|
+
before do
|
|
326
|
+
@query_str = 'CONSTRUCT xyz'
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
context "where the request format is not specified" do
|
|
330
|
+
it "should return nt header" do
|
|
331
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
332
|
+
q.send(:construct_or_describe_header).should == Mime::NT
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
context "where the request format is html" do
|
|
337
|
+
it "should return nt header'" do
|
|
338
|
+
q = PublishMyData::SparqlQuery.new(@query_str)
|
|
339
|
+
q.send(:construct_or_describe_header).should == Mime::NT
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
context "where the request format is ttl" do
|
|
345
|
+
it "should return ttl header" do
|
|
346
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :ttl)
|
|
347
|
+
q.send(:construct_or_describe_header).should == Mime::TTL
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
context "where the request format is rdf" do
|
|
352
|
+
it "should return rdf header" do
|
|
353
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :rdf)
|
|
354
|
+
q.send(:construct_or_describe_header).should == Mime::RDF
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
context "where the request format is something random" do
|
|
359
|
+
it "should return ntriples header" do
|
|
360
|
+
q = PublishMyData::SparqlQuery.new(@query_str, :bananas)
|
|
361
|
+
q.send(:construct_or_describe_header).should == Mime::NT
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
describe "#as_count_query" do
|
|
367
|
+
context "for non-selects" do
|
|
368
|
+
it "should throw an exception" do
|
|
369
|
+
lambda {
|
|
370
|
+
q = PublishMyData::SparqlQuery.new('ASK { ?s ?p ?o }')
|
|
371
|
+
q.as_count_query
|
|
372
|
+
}.should raise_error(Tripod::SparqlQueryError, "Can't turn this into a subquery")
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
context "for selects" do
|
|
377
|
+
|
|
378
|
+
it "should return a new Sparql query with the original query as the parent" do
|
|
379
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
380
|
+
q.as_count_query.parent_query.query.should == 'SELECT ?s WHERE { ?s ?p ?o }'
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
context 'without prefixes' do
|
|
384
|
+
it "should return a new SparqlQuery with the original query wrapped in a count" do
|
|
385
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
386
|
+
q.as_count_query.class.should == SparqlQuery
|
|
387
|
+
q.as_count_query.query.should == 'SELECT COUNT(*) { SELECT ?s WHERE { ?s ?p ?o } }'
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
context 'with prefixes' do
|
|
392
|
+
it "should move the prefixes to the start" do
|
|
393
|
+
q = PublishMyData::SparqlQuery.new('PREFIX e: <http://example.com> SELECT ?s WHERE { ?s ?p ?o }')
|
|
394
|
+
q.as_count_query.query.should == 'PREFIX e: <http://example.com> SELECT COUNT(*) { SELECT ?s WHERE { ?s ?p ?o } }'
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe "#paginate" do
|
|
401
|
+
|
|
402
|
+
it "should execute the query as a pagination query" do
|
|
403
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
404
|
+
pagination_q = double("SparqlQuery")
|
|
405
|
+
q.should_receive(:as_pagination_query).and_return(pagination_q)
|
|
406
|
+
pagination_q.should_receive(:execute)
|
|
407
|
+
q.paginate(1,20,0)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it "should pass the parameters through to as_pagination_query" do
|
|
411
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
412
|
+
q.should_receive(:as_pagination_query).with(3,40,1).and_call_original
|
|
413
|
+
q.paginate(3,40,1)
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
describe "#count" do
|
|
418
|
+
before do
|
|
419
|
+
@q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
420
|
+
count_q = double("SparqlQuery")
|
|
421
|
+
@q.should_receive(:as_count_query).and_return(count_q)
|
|
422
|
+
count_q.should_receive(:execute).and_return('{
|
|
423
|
+
"head": {
|
|
424
|
+
"vars": [ ".1" ]
|
|
425
|
+
} ,
|
|
426
|
+
"results": {
|
|
427
|
+
"bindings": [
|
|
428
|
+
{
|
|
429
|
+
".1": { "datatype": "http://www.w3.org/2001/XMLSchema#integer" , "type": "typed-literal" , "value": "2" }
|
|
430
|
+
}
|
|
431
|
+
]
|
|
432
|
+
}
|
|
433
|
+
}')
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
it "should execute the query as a count query and return an integer" do
|
|
437
|
+
@q.count.class.should == Fixnum
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
describe "#as_pagination_query" do
|
|
443
|
+
|
|
444
|
+
context "for non-selects" do
|
|
445
|
+
it "should throw an exception" do
|
|
446
|
+
lambda {
|
|
447
|
+
q = PublishMyData::SparqlQuery.new('ASK { ?s ?p ?o }')
|
|
448
|
+
q.as_pagination_query(1, 20, 0)
|
|
449
|
+
}.should raise_error(Tripod::SparqlQueryError, "Can't turn this into a subquery")
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
context "for selects" do
|
|
454
|
+
|
|
455
|
+
it "should return a new Sparql query with the original query as the parent" do
|
|
456
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
457
|
+
q.as_pagination_query(1, 20, 0).parent_query.query.should == 'SELECT ?s WHERE { ?s ?p ?o }'
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
context "without prefixes" do
|
|
461
|
+
|
|
462
|
+
it "should return a new SparqlQuery with the original query wrapped in a pagination subquery" do
|
|
463
|
+
q = PublishMyData::SparqlQuery.new('SELECT ?s WHERE { ?s ?p ?o }')
|
|
464
|
+
q.as_pagination_query(1, 20, 0).class.should == SparqlQuery
|
|
465
|
+
# try a couple of different combos of pagination params
|
|
466
|
+
q.as_pagination_query(1, 20, 0).query.should == 'SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 20 OFFSET 0'
|
|
467
|
+
q.as_pagination_query(1, 20, 1).query.should == 'SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 21 OFFSET 0'
|
|
468
|
+
q.as_pagination_query(2, 10, 0).query.should == 'SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 10 OFFSET 10'
|
|
469
|
+
q.as_pagination_query(3, 10, 1).query.should == 'SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 11 OFFSET 20'
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
context "with prefixes" do
|
|
474
|
+
it "should move the prefixes to the start" do
|
|
475
|
+
q = PublishMyData::SparqlQuery.new('PREFIX e: <http://example.com> SELECT ?s WHERE { ?s ?p ?o }')
|
|
476
|
+
q.as_pagination_query(1, 20, 0).query.should == 'PREFIX e: <http://example.com> SELECT * { SELECT ?s WHERE { ?s ?p ?o } } LIMIT 20 OFFSET 0'
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
context "with an existing subselect" do
|
|
481
|
+
it "should wrap the select as for a normal select" do
|
|
482
|
+
q = PublishMyData::SparqlQuery.new('SELECT * { SELECT ?s WHERE { ?s ?p ?o } }')
|
|
483
|
+
# try a couple of different combos of pagination params
|
|
484
|
+
q.as_pagination_query(1, 20, 0).query.should == 'SELECT * { SELECT * { SELECT ?s WHERE { ?s ?p ?o } } } LIMIT 20 OFFSET 0'
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
end
|