ansr 0.0.1 → 0.0.3

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.
Files changed (83) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +35 -0
  3. data/ansr.gemspec +2 -1
  4. data/ansr_blacklight/Gemfile +3 -0
  5. data/ansr_blacklight/README.md +37 -0
  6. data/ansr_blacklight/ansr_blacklight.gemspec +28 -0
  7. data/ansr_blacklight/lib/ansr_blacklight.rb +57 -0
  8. data/ansr_blacklight/lib/ansr_blacklight/arel.rb +6 -0
  9. data/ansr_blacklight/lib/ansr_blacklight/arel/big_table.rb +57 -0
  10. data/ansr_blacklight/lib/ansr_blacklight/arel/visitors.rb +6 -0
  11. data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/query_builder.rb +217 -0
  12. data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/to_no_sql.rb +14 -0
  13. data/ansr_blacklight/lib/ansr_blacklight/base.rb +21 -0
  14. data/ansr_blacklight/lib/ansr_blacklight/connection_adapters/no_sql_adapter.rb +38 -0
  15. data/ansr_blacklight/lib/ansr_blacklight/model/querying.rb +29 -0
  16. data/ansr_blacklight/lib/ansr_blacklight/relation.rb +50 -0
  17. data/ansr_blacklight/lib/ansr_blacklight/relation/solr_projection_methods.rb +55 -0
  18. data/ansr_blacklight/lib/ansr_blacklight/request_builders.rb +141 -0
  19. data/ansr_blacklight/lib/ansr_blacklight/solr.rb +4 -0
  20. data/ansr_blacklight/lib/ansr_blacklight/solr/request.rb +46 -0
  21. data/ansr_blacklight/lib/ansr_blacklight/solr/response.rb +94 -0
  22. data/ansr_blacklight/lib/ansr_blacklight/solr/response/group.rb +32 -0
  23. data/ansr_blacklight/lib/ansr_blacklight/solr/response/group_response.rb +50 -0
  24. data/ansr_blacklight/lib/ansr_blacklight/solr/response/more_like_this.rb +14 -0
  25. data/ansr_blacklight/lib/ansr_blacklight/solr/response/pagination_methods.rb +35 -0
  26. data/ansr_blacklight/lib/ansr_blacklight/solr/response/spelling.rb +92 -0
  27. data/ansr_blacklight/spec/fixtures/config.yml +0 -0
  28. data/ansr_blacklight/spec/lib/loaded_relation_spec.rb +223 -0
  29. data/ansr_blacklight/spec/lib/queryable_relation_spec.rb +133 -0
  30. data/ansr_blacklight/spec/lib/relation/faceting_spec.rb +475 -0
  31. data/ansr_blacklight/spec/lib/relation/grouping_spec.rb +159 -0
  32. data/ansr_blacklight/spec/spec_helper.rb +72 -0
  33. data/ansr_dpla/Gemfile +3 -0
  34. data/ansr_dpla/Gemfile.lock +138 -0
  35. data/ansr_dpla/README.md +2 -2
  36. data/ansr_dpla/ansr_dpla.gemspec +2 -2
  37. data/ansr_dpla/lib/ansr_dpla.rb +3 -0
  38. data/ansr_dpla/lib/ansr_dpla/api.rb +3 -3
  39. data/ansr_dpla/lib/ansr_dpla/arel.rb +1 -2
  40. data/ansr_dpla/lib/ansr_dpla/arel/big_table.rb +4 -0
  41. data/ansr_dpla/lib/ansr_dpla/arel/visitors.rb +6 -0
  42. data/ansr_dpla/lib/ansr_dpla/arel/visitors/query_builder.rb +188 -0
  43. data/ansr_dpla/lib/ansr_dpla/arel/visitors/to_no_sql.rb +9 -0
  44. data/ansr_dpla/lib/ansr_dpla/connection_adapters/no_sql_adapter.rb +58 -0
  45. data/ansr_dpla/lib/ansr_dpla/model/base.rb +7 -0
  46. data/ansr_dpla/lib/ansr_dpla/model/querying.rb +6 -10
  47. data/ansr_dpla/lib/ansr_dpla/relation.rb +61 -0
  48. data/ansr_dpla/lib/ansr_dpla/request.rb +5 -0
  49. data/ansr_dpla/spec/lib/api_spec.rb +8 -5
  50. data/ansr_dpla/spec/lib/item_spec.rb +2 -2
  51. data/ansr_dpla/spec/lib/relation/facet_spec.rb +27 -19
  52. data/ansr_dpla/spec/lib/relation/select_spec.rb +10 -8
  53. data/ansr_dpla/spec/lib/relation/where_spec.rb +1 -1
  54. data/ansr_dpla/spec/lib/relation_spec.rb +31 -29
  55. data/ansr_dpla/test/system.rb +4 -2
  56. data/lib/ansr.rb +7 -0
  57. data/lib/ansr/arel.rb +3 -0
  58. data/lib/ansr/arel/big_table.rb +43 -3
  59. data/lib/ansr/arel/configured_field.rb +19 -0
  60. data/lib/ansr/arel/nodes.rb +41 -0
  61. data/lib/ansr/arel/visitors.rb +7 -0
  62. data/lib/ansr/arel/visitors/context.rb +13 -0
  63. data/lib/ansr/arel/visitors/query_builder.rb +47 -0
  64. data/lib/ansr/arel/visitors/to_no_sql.rb +41 -0
  65. data/lib/ansr/base.rb +29 -1
  66. data/lib/ansr/configurable.rb +6 -12
  67. data/lib/ansr/connection_adapters.rb +5 -0
  68. data/lib/ansr/connection_adapters/no_sql_adapter.rb +80 -0
  69. data/lib/ansr/dummy_associations.rb +105 -0
  70. data/lib/ansr/facets.rb +103 -0
  71. data/lib/ansr/model.rb +17 -107
  72. data/lib/ansr/model/connection_handler.rb +6 -0
  73. data/lib/ansr/relation.rb +40 -23
  74. data/lib/ansr/relation/group.rb +31 -0
  75. data/lib/ansr/relation/predicate_builder.rb +106 -0
  76. data/lib/ansr/relation/query_methods.rb +192 -45
  77. data/lib/ansr/sanitization.rb +5 -18
  78. data/lib/ansr/utils.rb +89 -0
  79. data/lib/ansr/version.rb +1 -1
  80. metadata +73 -25
  81. data/ansr_dpla/lib/ansr_dpla/arel/connection.rb +0 -81
  82. data/ansr_dpla/lib/ansr_dpla/arel/query_builder.rb +0 -131
  83. data/lib/ansr/model/connection.rb +0 -103
@@ -0,0 +1,159 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # check the methods that do solr requests. Note that we are not testing if
5
+ # solr gives "correct" responses, as that's out of scope (it's a part of
6
+ # testing the solr code itself). We *are* testing if blacklight code sends
7
+ # queries to solr such that it gets appropriate results. When a user does a search,
8
+ # do we get data back from solr (i.e. did we properly configure blacklight code
9
+ # to talk with solr and get results)? when we do a document request, does
10
+ # blacklight code get a single document returned?)
11
+ #
12
+ describe Ansr::Blacklight do
13
+
14
+ class TestTable < Ansr::Arel::BigTable
15
+
16
+ def [](val)
17
+ key = (Arel::Attributes::Attribute === val) ? val.name.to_sym : val.to_sym
18
+ key == :configured ? Ansr::Arel::ConfiguredField.new(key, {:property => 'test', :escape => 'tes"t'}) : super(val)
19
+ end
20
+
21
+ def fields
22
+ [:id]
23
+ end
24
+
25
+ end
26
+
27
+ before do
28
+ Object.const_set('GroupModel', Class.new(TestModel))
29
+ GroupModel.solr = stub_solr(sample_response)
30
+ GroupModel.configure do |config|
31
+ config[:table_class] = TestTable
32
+ end
33
+ end
34
+
35
+ after do
36
+ Object.send(:remove_const, :GroupModel)
37
+ end
38
+
39
+ let(:response) do
40
+ create_response(sample_response)
41
+ end
42
+
43
+ let(:group) do
44
+ response.grouped(GroupModel).select { |x| x.key == "result_group_ssi" }.first
45
+ end
46
+
47
+ subject do
48
+ group.groups.first
49
+ end
50
+
51
+ describe Ansr::Blacklight::Solr::Response::Group do
52
+ describe "#doclist" do
53
+ it "should be the raw list of documents from solr" do
54
+ expect(subject.doclist).to be_a Hash
55
+ expect(subject.doclist['docs'].first[:id]).to eq 1
56
+ end
57
+ end
58
+
59
+ describe "#total" do
60
+ it "should be the number of results found in a group" do
61
+ expect(subject.total).to eq 2
62
+ end
63
+ end
64
+
65
+ describe "#start" do
66
+ it "should be the offset for the results in the group" do
67
+ expect(subject.start).to eq 0
68
+ end
69
+ end
70
+
71
+ describe "#docs" do
72
+ it "should be a list of GroupModels" do
73
+ subject.docs.each do |doc|
74
+ expect(doc).to be_a_kind_of GroupModel
75
+ end
76
+
77
+ expect(subject.docs.first.id).to eq 1
78
+ end
79
+ end
80
+
81
+ describe "#field" do
82
+ it "should be the field the group belongs to" do
83
+ expect(subject.field).to eq "result_group_ssi"
84
+ end
85
+ end
86
+ end
87
+
88
+ describe Ansr::Blacklight::Solr::Response do
89
+ let(:response) do
90
+ create_response(sample_response)
91
+ end
92
+
93
+ let(:group) do
94
+ response.grouped(GroupModel).select { |x| x.key == "result_group_ssi" }.first
95
+ end
96
+
97
+ describe "groups" do
98
+ it "should return an array of Groups" do
99
+ response.grouped(GroupModel).should be_a Array
100
+
101
+ expect(group.groups).to have(2).items
102
+ group.groups.each do |group|
103
+ expect(group).to be_a Ansr::Blacklight::Solr::Response::Group
104
+ end
105
+ end
106
+ it "should include a list of SolrDocuments" do
107
+
108
+ group.groups.each do |group|
109
+ group.docs.each do |doc|
110
+ expect(doc).to be_a GroupModel
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ describe "total" do
117
+ it "should return the ngroups value" do
118
+ expect(group.total).to eq 3
119
+ end
120
+ end
121
+
122
+ describe "facets" do
123
+ it "should exist in the response object (not testing, we just extend the module)" do
124
+ expect(group).to respond_to :facets
125
+ end
126
+ end
127
+
128
+ describe "rows" do
129
+ it "should get the rows from the response" do
130
+ expect(group.rows).to eq 3
131
+ end
132
+ end
133
+
134
+ describe "group_field" do
135
+ it "should be the field name for the current group" do
136
+ expect(group.group_field).to eq "result_group_ssi"
137
+ end
138
+ end
139
+
140
+ describe "group_limit" do
141
+ it "should be the number of documents to return for a group" do
142
+ expect(group.group_limit).to eq 5
143
+ end
144
+ end
145
+ end
146
+
147
+ def sample_response
148
+ {"responseHeader" => {"params" =>{"rows" => 3, "group.limit" => 5}},
149
+ "grouped" =>
150
+ {'result_group_ssi' =>
151
+ {'groups' => [{'groupValue'=>"Group 1", 'doclist'=>{'numFound'=>2, 'start' => 0, 'docs'=>[{:id=>1}, {:id => 'x'}]}},
152
+ {'groupValue'=>"Group 2", 'doclist'=>{'numFound'=>3, 'docs'=>[{:id=>2}, :id=>3]}}
153
+ ],
154
+ 'ngroups' => "3"
155
+ }
156
+ }
157
+ }
158
+ end
159
+ end
@@ -0,0 +1,72 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app/models'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ ENV["RAILS_ENV"] ||= 'test'
7
+ require 'ansr'
8
+ require 'rails/all'
9
+ require 'rspec/rails'
10
+ require 'loggable'
11
+ require 'ansr_blacklight'
12
+ #require 'blacklight'
13
+
14
+ RSpec.configure do |config|
15
+ # == Mock Framework
16
+ #
17
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
18
+ #
19
+ # config.mock_with :mocha
20
+ # config.mock_with :flexmock
21
+ # config.mock_with :rr
22
+ config.mock_with :rspec
23
+
24
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
25
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
26
+
27
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
28
+ # examples within a transaction, remove the following line or assign false
29
+ # instead of true.
30
+ #config.use_transactional_fixtures = true
31
+ end
32
+
33
+ def fixture_path(path)
34
+ File.join(File.dirname(__FILE__), '..', 'fixtures', path)
35
+ end
36
+
37
+ def fixture path, &block
38
+ if block_given?
39
+ open(fixture_path(path)) &block
40
+ else
41
+ open(fixture_path(path))
42
+ end
43
+ end
44
+
45
+ def read_fixture(path)
46
+ _f = fixture(path)
47
+ _f.read
48
+ ensure
49
+ _f and _f.close
50
+ end
51
+
52
+ def stub_solr(response='')
53
+ solr = double('Solr')
54
+ solr.stub(:send_and_receive).and_return(response)
55
+ solr
56
+ end
57
+
58
+ def create_response(response, params = {})
59
+ Ansr::Blacklight::Solr::Response.new(response, params)
60
+ end
61
+
62
+ class TestModel < Ansr::Blacklight::Base
63
+ configure do |config|
64
+ config[:unique_key] = 'id'
65
+ end
66
+ def self.solr=(solr)
67
+ @solr = solr
68
+ end
69
+ def self.solr
70
+ @solr
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,138 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ansr_dpla (0.0.1)
5
+ ansr (= 0.0.1)
6
+ blacklight (>= 5.1.0)
7
+ json-ld
8
+ loggable
9
+ rest-client
10
+ sass-rails
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ actionmailer (4.0.3)
16
+ actionpack (= 4.0.3)
17
+ mail (~> 2.5.4)
18
+ actionpack (4.0.3)
19
+ activesupport (= 4.0.3)
20
+ builder (~> 3.1.0)
21
+ erubis (~> 2.7.0)
22
+ rack (~> 1.5.2)
23
+ rack-test (~> 0.6.2)
24
+ activemodel (4.0.3)
25
+ activesupport (= 4.0.3)
26
+ builder (~> 3.1.0)
27
+ activerecord (4.0.3)
28
+ activemodel (= 4.0.3)
29
+ activerecord-deprecated_finders (~> 1.0.2)
30
+ activesupport (= 4.0.3)
31
+ arel (~> 4.0.0)
32
+ activerecord-deprecated_finders (1.0.3)
33
+ activesupport (4.0.3)
34
+ i18n (~> 0.6, >= 0.6.4)
35
+ minitest (~> 4.2)
36
+ multi_json (~> 1.3)
37
+ thread_safe (~> 0.1)
38
+ tzinfo (~> 0.3.37)
39
+ ansr (0.0.1)
40
+ blacklight (>= 5.1.0)
41
+ loggable
42
+ arel (4.0.2)
43
+ atomic (1.1.15)
44
+ blacklight (5.2.0)
45
+ bootstrap-sass (~> 3.0)
46
+ deprecation
47
+ kaminari (~> 0.13)
48
+ nokogiri (~> 1.6)
49
+ rails (>= 3.2.6, < 5)
50
+ rsolr (~> 1.0.6)
51
+ bootstrap-sass (3.1.1.0)
52
+ sass (~> 3.2)
53
+ builder (3.1.4)
54
+ deprecation (0.1.0)
55
+ activesupport
56
+ diff-lcs (1.2.5)
57
+ erubis (2.7.0)
58
+ hike (1.2.3)
59
+ i18n (0.6.9)
60
+ json-ld (1.1.1)
61
+ rdf (>= 1.0.8)
62
+ kaminari (0.15.1)
63
+ actionpack (>= 3.0.0)
64
+ activesupport (>= 3.0.0)
65
+ loggable (0.3.0)
66
+ mail (2.5.4)
67
+ mime-types (~> 1.16)
68
+ treetop (~> 1.4.8)
69
+ mime-types (1.25.1)
70
+ mini_portile (0.5.2)
71
+ minitest (4.7.5)
72
+ multi_json (1.9.0)
73
+ nokogiri (1.6.1)
74
+ mini_portile (~> 0.5.0)
75
+ polyglot (0.3.4)
76
+ rack (1.5.2)
77
+ rack-test (0.6.2)
78
+ rack (>= 1.0)
79
+ rails (4.0.3)
80
+ actionmailer (= 4.0.3)
81
+ actionpack (= 4.0.3)
82
+ activerecord (= 4.0.3)
83
+ activesupport (= 4.0.3)
84
+ bundler (>= 1.3.0, < 2.0)
85
+ railties (= 4.0.3)
86
+ sprockets-rails (~> 2.0.0)
87
+ railties (4.0.3)
88
+ actionpack (= 4.0.3)
89
+ activesupport (= 4.0.3)
90
+ rake (>= 0.8.7)
91
+ thor (>= 0.18.1, < 2.0)
92
+ rake (10.1.1)
93
+ rdf (1.1.2.1)
94
+ rest-client (1.6.7)
95
+ mime-types (>= 1.16)
96
+ rsolr (1.0.9)
97
+ builder (>= 2.1.2)
98
+ rspec (2.14.1)
99
+ rspec-core (~> 2.14.0)
100
+ rspec-expectations (~> 2.14.0)
101
+ rspec-mocks (~> 2.14.0)
102
+ rspec-core (2.14.8)
103
+ rspec-expectations (2.14.5)
104
+ diff-lcs (>= 1.1.3, < 2.0)
105
+ rspec-mocks (2.14.6)
106
+ sass (3.3.2)
107
+ sass-rails (4.0.1)
108
+ railties (>= 4.0.0, < 5.0)
109
+ sass (>= 3.1.10)
110
+ sprockets-rails (~> 2.0.0)
111
+ sprockets (2.12.0)
112
+ hike (~> 1.2)
113
+ multi_json (~> 1.0)
114
+ rack (~> 1.0)
115
+ tilt (~> 1.1, != 1.3.0)
116
+ sprockets-rails (2.0.1)
117
+ actionpack (>= 3.0)
118
+ activesupport (>= 3.0)
119
+ sprockets (~> 2.8)
120
+ thor (0.18.1)
121
+ thread_safe (0.2.0)
122
+ atomic (>= 1.1.7, < 2)
123
+ tilt (1.4.1)
124
+ treetop (1.4.15)
125
+ polyglot
126
+ polyglot (>= 0.3.1)
127
+ tzinfo (0.3.39)
128
+ yard (0.8.7.3)
129
+
130
+ PLATFORMS
131
+ ruby
132
+
133
+ DEPENDENCIES
134
+ ansr_dpla!
135
+ bundler (>= 1.0.14)
136
+ rake
137
+ rspec
138
+ yard
@@ -1,9 +1,9 @@
1
- adpla
1
+ Ansr::Dpla
2
2
  =====
3
3
 
4
4
  DPLA + ActiveRecord::Relation + Blacklight
5
5
 
6
- This project creates a Rails model that can be used to search the DPLA's public REST API (http://dp.la/info/developers/codex/).
6
+ This project creates a Rails model that can be used to search the DPLA's public REST API (http://dp.la/info/developers/codex/). The goal of this project is to provide an avenue by which data from the DPLA REST API might be explored via a [Blacklight](https://github.com/projectblacklight/blacklight) application. It is proof-of-concept for a broader proposal described at (https://github.com/barmintor/ansr)
7
7
 
8
8
  To use the Item and Collection models, they must first be configured with a DPLA API key:
9
9
 
@@ -7,8 +7,8 @@ Gem::Specification.new do |spec|
7
7
  spec.authors = ["Benjamin Armintor"]
8
8
  spec.email = ["armintor@gmail.com"]
9
9
  spec.summary = 'ActiveRecord-style models and relations for DPLA APIs'
10
- spec.description = 'Wrapping the DPLA APIs in Rails-like models and '
11
- spec.homepage = 'http://github.com/barmintor/ansr/ansr_dpla'
10
+ spec.description = 'Wrapping the DPLA APIs in Rails-like models and relations'
11
+ spec.homepage = 'https://github.com/barmintor/ansr/tree/master/ansr_dpla'
12
12
  spec.files = `git ls-files`.split("\n")
13
13
  spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
14
  spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -1,6 +1,9 @@
1
1
  require 'ansr'
2
2
  module Ansr::Dpla
3
3
  require 'ansr_dpla/api'
4
+ require 'ansr_dpla/request'
5
+ require 'ansr_dpla/connection_adapters/no_sql_adapter'
4
6
  require 'ansr_dpla/arel'
7
+ require 'ansr_dpla/relation'
5
8
  require 'ansr_dpla/model'
6
9
  end
@@ -3,8 +3,8 @@ module Ansr::Dpla
3
3
  class Api
4
4
  include Ansr::Configurable
5
5
 
6
- def config(yaml=nil)
7
- super
6
+ def config &block
7
+ super &block
8
8
  raise "DPLA clients must be configured with an API key" unless @config[:api_key]
9
9
  @config
10
10
  end
@@ -13,7 +13,7 @@ module Ansr::Dpla
13
13
  API_PARAM_KEYS = [:api_key, :callback, :facets, :fields, :page, :page_size, :sort_by, :sort_by_pin, :sort_order]
14
14
 
15
15
  def initialize(config=nil)
16
- self.config(config) if config
16
+ self.config{|x| x.merge!(config)} if config
17
17
  end
18
18
 
19
19
  def api_key
@@ -2,7 +2,6 @@ require 'active_record'
2
2
  module Ansr::Dpla
3
3
  module Arel
4
4
  require 'ansr_dpla/arel/big_table'
5
- require 'ansr_dpla/arel/connection'
6
- require 'ansr_dpla/arel/query_builder'
5
+ require 'ansr_dpla/arel/visitors'
7
6
  end
8
7
  end
@@ -93,12 +93,16 @@ module Ansr::Dpla
93
93
 
94
94
  def initialize(klass, opts={})
95
95
  super(klass.model())
96
+ self.name = klass.name.downcase.pluralize
96
97
  @fields += (opts[:fields] || FIELDS)
97
98
  @facets += (opts[:facets] || FACETS)
98
99
  @sorts += (opts[:sorts] || SORTS)
99
100
  self.config(opts[:config]) if opts[:config]
100
101
  end
101
102
 
103
+ def name
104
+ super.pluralize.downcase
105
+ end
102
106
  end
103
107
  end
104
108
  end