albanpeignier-searchapi 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.
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ RAILS_ENV = "test" unless defined?(RAILS_ENV)
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+ require 'search_api'
5
+ require 'active_record_bridge'
6
+ require 'active_record_integration'
7
+ require 'test/mock_model'
8
+
9
+ class ActiveRecordIntegrationTest < Test::Unit::TestCase
10
+
11
+ def setup
12
+ begin
13
+ Searchable.find(:first)
14
+ rescue
15
+ raise "run 'rake searchapi_migrate_test_db' in the application directory before running searchapi tests"
16
+ end
17
+ end
18
+
19
+ def test_integration
20
+ Searchable.class_eval do
21
+ has_search_api
22
+
23
+ search :old do |search|
24
+ if search.old
25
+ { :conditions => ['age > 80'] }
26
+ else
27
+ { :conditions => ['age < 80'] }
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ assert_equivalent_request({:conditions => 'age > 80'},
34
+ {:conditions => {:old => true}})
35
+
36
+ assert_equivalent_request({:conditions => 'age < 80'},
37
+ {:conditions => {:old => false}})
38
+
39
+ end
40
+
41
+ protected
42
+
43
+ def assert_equivalent_request(traditional_find_options, search_options)
44
+ traditional_result_ids = Searchable.find(:all, traditional_find_options).map(&:id).sort
45
+ search_result_ids = Searchable.find(:all, search_options).map(&:id).sort
46
+ assert !traditional_result_ids.empty?
47
+ assert_equal traditional_result_ids, search_result_ids
48
+ end
49
+ end
@@ -0,0 +1,69 @@
1
+ require 'test/unit'
2
+ RAILS_ENV = "test" unless defined?(RAILS_ENV)
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+ require 'search_api'
5
+ require 'active_record_bridge'
6
+ require 'test/mock_model'
7
+
8
+ class BridgteTest < Test::Unit::TestCase
9
+ def test_rewriter_bridge
10
+ # create a search class
11
+ search_class = Class.new(::SearchApi::Search::Base)
12
+
13
+ assert_nothing_raised do
14
+ search_class.class_eval do
15
+ model ModelWithRewriterBridge
16
+ search_accessor :a, :b
17
+ end
18
+ end
19
+
20
+ # assert accessors are there, and store_as option is active
21
+ search = search_class.new(:a => '1', :b=>'2')
22
+ assert_equal 2, search.a
23
+ assert_equal 3, search.b
24
+
25
+ # assert find_options_for_xxx exist, and behave correctly
26
+ assert_equal 3, search.find_options_for_a
27
+ assert_equal 4, search.find_options_for_b
28
+ end
29
+
30
+ def test_automatic_bridge
31
+ # create a search class
32
+ search_class = Class.new(::SearchApi::Search::Base)
33
+
34
+ assert_nothing_raised do
35
+ search_class.class_eval do
36
+ model ModelWithAutomaticBridge
37
+ end
38
+ end
39
+
40
+ # assert automatic search attributes are there
41
+ assert_equal [:a], search_class.search_attributes.sort
42
+
43
+ # assert accessors are there
44
+ search = search_class.new(:a => 'a')
45
+ assert_equal 'a', search.a
46
+
47
+ # assert find_options_for_a exists, and behaves correctly
48
+ assert_equal 'b', search.find_options_for_a
49
+ end
50
+
51
+ def test_merger_bridge
52
+ # create a search class
53
+ search_class = Class.new(::SearchApi::Search::Base)
54
+
55
+ assert_nothing_raised do
56
+ search_class.class_eval do
57
+ model ModelWithMergerBridge
58
+ search_accessor :a do |search| search.a end
59
+ search_accessor :b do |search| search.b end
60
+ end
61
+ end
62
+
63
+ # assert accessors are there, and store_as option is active
64
+ search = search_class.new(:a => 1, :b=>2)
65
+ assert_equal 3, search.find_options
66
+ end
67
+
68
+ end
69
+
@@ -0,0 +1,157 @@
1
+ require 'test/unit'
2
+ RAILS_ENV = "test" unless defined?(RAILS_ENV)
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+ require 'search_api'
5
+ require 'active_record_bridge'
6
+ require 'test/mock_model'
7
+
8
+ class CallbacksTest < Test::Unit::TestCase
9
+ def test_before_find_options_method
10
+ # create a search class
11
+ search_class = Class.new(::SearchApi::Search::Base)
12
+
13
+ search_class.class_eval do
14
+ model Searchable
15
+ end
16
+
17
+ # get some attributes that fills some find_options (should we test the test ?)
18
+ assert_not_equal search_class.new.find_options, search_class.new(:age=>12).find_options
19
+
20
+ # reopen the search class
21
+ search_class.class_eval do
22
+ def before_find_options
23
+ self.class.search_attributes.each do |search_attribute|
24
+ ignore!(search_attribute)
25
+ end
26
+ end
27
+ end
28
+
29
+ # those same attributes should now be ignored
30
+ assert_equal search_class.new.find_options, search_class.new(:age=>12).find_options
31
+ end
32
+
33
+
34
+ def test_before_find_options_symbol
35
+ # create a search class
36
+ search_class = Class.new(::SearchApi::Search::Base)
37
+
38
+ search_class.class_eval do
39
+ model Searchable
40
+ end
41
+
42
+ # get some attributes that fills some find_options (should we test the test ?)
43
+ assert_not_equal search_class.new.find_options, search_class.new(:age=>12).find_options
44
+
45
+ # reopen the search class
46
+ search_class.class_eval do
47
+ before_find_options :ignore_all_attributes
48
+
49
+ def ignore_all_attributes
50
+ self.class.search_attributes.each do |search_attribute|
51
+ ignore!(search_attribute)
52
+ end
53
+ end
54
+ end
55
+
56
+ # those same attributes should now be ignored
57
+ assert_equal search_class.new.find_options, search_class.new(:age=>12).find_options
58
+ end
59
+
60
+
61
+ def test_before_find_options_symbol
62
+ # create a search class
63
+ search_class = Class.new(::SearchApi::Search::Base)
64
+
65
+ search_class.class_eval do
66
+ model Searchable
67
+ end
68
+
69
+ # get some attributes that fills some find_options (should we test the test ?)
70
+ assert_not_equal search_class.new.find_options, search_class.new(:age=>12).find_options
71
+
72
+ # reopen the search class
73
+ search_class.class_eval do
74
+ before_find_options "self.ignore_all_attributes"
75
+
76
+ def ignore_all_attributes
77
+ self.class.search_attributes.each do |search_attribute|
78
+ ignore!(search_attribute)
79
+ end
80
+ end
81
+ end
82
+
83
+ # those same attributes should now be ignored
84
+ assert_equal search_class.new.find_options, search_class.new(:age=>12).find_options
85
+ end
86
+
87
+
88
+ def test_before_find_options_proc
89
+ # create a search class
90
+ search_class = Class.new(::SearchApi::Search::Base)
91
+
92
+ search_class.class_eval do
93
+ model Searchable
94
+ end
95
+
96
+ # get some attributes that fills some find_options (should we test the test ?)
97
+ assert_not_equal search_class.new.find_options, search_class.new(:age=>12).find_options
98
+
99
+ # reopen the search class
100
+ search_class.class_eval do
101
+ before_find_options { |search| search.ignore_all_attributes }
102
+
103
+ def ignore_all_attributes
104
+ self.class.search_attributes.each do |search_attribute|
105
+ ignore!(search_attribute)
106
+ end
107
+ end
108
+ end
109
+
110
+ # those same attributes should now be ignored
111
+ assert_equal search_class.new.find_options, search_class.new(:age=>12).find_options
112
+ end
113
+
114
+
115
+ class BlackHole
116
+ # ignore all attributes of search
117
+ def before_find_options(search)
118
+ search.class.search_attributes.each do |search_attribute|
119
+ search.ignore!(search_attribute)
120
+ end
121
+ end
122
+ end
123
+
124
+ def test_before_find_options_object
125
+ # create a search class
126
+ search_class = Class.new(::SearchApi::Search::Base)
127
+
128
+ search_class.class_eval do
129
+ model Searchable
130
+ end
131
+
132
+ # get some attributes that fills some find_options (should we test the test ?)
133
+ assert_not_equal search_class.new.find_options, search_class.new(:age=>12).find_options
134
+
135
+ # reopen the search class
136
+ search_class.class_eval do
137
+ before_find_options BlackHole.new
138
+ end
139
+
140
+ # those same attributes should now be ignored
141
+ assert_equal search_class.new.find_options, search_class.new(:age=>12).find_options
142
+ end
143
+
144
+ def test_bad_before_find_options
145
+ # create a search class
146
+ search_class = Class.new(::SearchApi::Search::Base)
147
+
148
+ search_class.class_eval do
149
+ model Searchable
150
+ before_find_options 1
151
+ end
152
+
153
+ assert_raise SearchApi::SearchApiError do
154
+ search_class.new.find_options
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,54 @@
1
+ class Searchable < ActiveRecord::Base
2
+ end
3
+
4
+
5
+ # bridge for testing of SearchAttributeBuilder rewriting
6
+ class RewriterBridge < SearchApi::Bridge::Base
7
+ def rewrite_search_attribute_builder(search_attribute_builder)
8
+ search_attribute_builder.options = { :store_as => proc do |x| x.to_i + 1 end }
9
+ search_attribute_builder.block = proc do |search| search.send(search_attribute_builder.name)+1 end
10
+ end
11
+ end
12
+
13
+ # model using RewriterBridge
14
+ class ModelWithRewriterBridge
15
+ class << self
16
+ def search_api_bridge
17
+ RewriterBridge.new
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ # bridge for testing of automatic search attributes
24
+ class AutomaticBridge < SearchApi::Bridge::Base
25
+ def automatic_search_attribute_builders(options)
26
+ [SearchApi::Search::SearchAttributeBuilder.new(:a) do |search| search.a.succ end]
27
+ end
28
+ end
29
+
30
+ # model using AutomaticBridge
31
+ class ModelWithAutomaticBridge
32
+ class << self
33
+ def search_api_bridge
34
+ AutomaticBridge.new
35
+ end
36
+ end
37
+ end
38
+
39
+
40
+ # bridge for testing of find options merging
41
+ class MergerBridge < SearchApi::Bridge::Base
42
+ def merge_find_options(options_array)
43
+ options_array.inject(0) { |sum, x| sum + x}
44
+ end
45
+ end
46
+
47
+ # model using MergerBridge
48
+ class ModelWithMergerBridge
49
+ class << self
50
+ def search_api_bridge
51
+ MergerBridge.new
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,340 @@
1
+ require 'test/unit'
2
+ RAILS_ENV = "test" unless defined?(RAILS_ENV)
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+ require 'search_api'
5
+ require 'active_record_bridge'
6
+ require 'test/mock_model'
7
+
8
+ class SearchTest < Test::Unit::TestCase
9
+ def test_model
10
+ # create a search class
11
+ search_class = Class.new(::SearchApi::Search::Base)
12
+
13
+ # assert model is a public method and that it behaves correctly
14
+ assert_nil search_class.model
15
+
16
+ # bad usage of ::SearchApi::Search.model
17
+ assert_raise ArgumentError do
18
+ search_class.class_eval do
19
+ model Searchable, Searchable
20
+ end
21
+ end
22
+
23
+ # bad model
24
+ assert_raise ArgumentError do
25
+ search_class.class_eval do
26
+ model 1
27
+ end
28
+ end
29
+
30
+ # assert ActiveRecord::Base can be used as a model.
31
+ assert_nothing_raised do
32
+ search_class.class_eval do
33
+ model Searchable
34
+ end
35
+ end
36
+
37
+ # test reader behavior
38
+ assert_equal Searchable, search_class.model
39
+
40
+ # test unicity
41
+ assert_raise RuntimeError do
42
+ search_class.class_eval do
43
+ model Searchable
44
+ end
45
+ end
46
+ end
47
+
48
+ def test_search_accessor
49
+ # create a search class
50
+ search_class = Class.new(::SearchApi::Search::Base)
51
+
52
+ # correct usage of search_accessor
53
+ assert_nothing_raised do
54
+ search_class.class_eval do
55
+ search_accessor :a1
56
+ search_accessor 'a2', {}
57
+ search_accessor :a3, :a4
58
+ search_accessor :a5, 'a6', {}
59
+ end
60
+ end
61
+
62
+ # check bad options
63
+ assert_raise ArgumentError do
64
+ search_class.class_eval do
65
+ search_accessor :a7, :foo => :bar
66
+ end
67
+ end
68
+ end
69
+
70
+ def test_search_attributes
71
+ # create a search class
72
+ search_class = Class.new(::SearchApi::Search::Base)
73
+
74
+ # assert search_attributes is empty
75
+ assert_equal [], search_class.search_attributes
76
+
77
+ # define some search_accessors
78
+ search_class.class_eval do
79
+ search_accessor :a1
80
+ search_accessor 'a2', :a3, 'a4'
81
+ end
82
+
83
+ # assert search_attributes are symbols
84
+ assert search_class.search_attributes.all? { |x| x.is_a?(Symbol) }
85
+
86
+ # assert accessors are there
87
+ assert %w(a1 a2 a3 a4).all? { |search_attribute| search_class.search_attributes.include?(search_attribute.to_sym)}
88
+ end
89
+
90
+ def test_initialize
91
+ # create a search class
92
+ search_class = Class.new(::SearchApi::Search::Base)
93
+
94
+ # assert no instance can be created without a model
95
+ assert_raise RuntimeError do
96
+ search_class.new
97
+ end
98
+
99
+ # define some search_accessors
100
+ search_class.class_eval do
101
+ model Searchable
102
+ search_accessor :a, 'b'
103
+ end
104
+
105
+ # build an instance with an unknown attribute
106
+ assert_raise NoMethodError do
107
+ search_class.new(:foo=>22)
108
+ end
109
+
110
+ # build an instance with an unknown attribute
111
+ assert_raise NoMethodError do
112
+ search_class.new('foo'=>22)
113
+ end
114
+
115
+ # build an instance without attributes
116
+ assert_nothing_raised do
117
+ search_class.new
118
+ end
119
+
120
+ # assert all atributes are ignored for an instance built without attributes
121
+ search = search_class.new
122
+ assert search_class.search_attributes.all? { |search_attribute|
123
+ search.ignored?(search_attribute) &&
124
+ search.send("#{search_attribute}_ignored?")
125
+ }
126
+
127
+ # build an instance with attributes
128
+ assert_nothing_raised do
129
+ search_class.new(:age => 33, :funny => true, :name => 'jesus', :a => [], :b=>{}, :id => nil)
130
+ search_class.new('age' => 33, 'funny' => true, 'name' => 'jesus', 'a' => [], 'b'=>{}, 'id' => nil)
131
+ end
132
+ end
133
+
134
+ def test_default_values
135
+ # create a search class
136
+ search_class = Class.new(::SearchApi::Search::Base)
137
+
138
+ # define some search_accessors
139
+ search_class.class_eval do
140
+ model Searchable
141
+ search_accessor :a, :default => 1
142
+ search_accessor :b
143
+ end
144
+
145
+ search = search_class.new
146
+
147
+ assert !search.ignored?(:a)
148
+ assert !search.a_ignored?
149
+ assert_equal 1, search.a
150
+
151
+ assert search.ignored?(:b)
152
+ assert search.b_ignored?
153
+ assert_equal SearchApi::Search.ignored, search.b
154
+ end
155
+
156
+ def test_accessors
157
+ # create a search class
158
+ search_class = Class.new(::SearchApi::Search::Base)
159
+
160
+ # define some search_accessors
161
+ search_class.class_eval do
162
+ model Searchable
163
+ search_accessor :a
164
+ end
165
+
166
+ # build an instance without attributes
167
+ search = search_class.new
168
+
169
+ # test default instance_methods are defined, and well-behaved
170
+ search_class.search_attributes.each do |attribute|
171
+ search.ignore!(attribute)
172
+ assert_equal true, search.send("#{attribute}?")
173
+ assert search.ignored?(attribute)
174
+ assert search.send("#{attribute}_ignored?")
175
+
176
+ search.send("#{attribute}=", nil)
177
+ assert_nil search.send(attribute)
178
+ assert_equal false, search.send("#{attribute}?")
179
+ assert !search.send("#{attribute}_ignored?")
180
+ assert !search.ignored?(attribute)
181
+
182
+ search.send("#{attribute}=", false)
183
+ assert_equal false, search.send(attribute)
184
+ assert_equal false, search.send("#{attribute}?")
185
+ assert !search.send("#{attribute}_ignored?")
186
+ assert !search.ignored?(attribute)
187
+
188
+ search.send("#{attribute}=", true)
189
+ assert_equal true, search.send(attribute)
190
+ assert_equal true, search.send("#{attribute}?")
191
+ assert !search.send("#{attribute}_ignored?")
192
+ assert !search.ignored?(attribute)
193
+
194
+ search.send("#{attribute}=", 'thing')
195
+ assert_equal 'thing', search.send(attribute)
196
+ assert_equal true, search.send("#{attribute}?")
197
+ assert !search.send("#{attribute}_ignored?")
198
+ assert !search.ignored?(attribute)
199
+ end
200
+ end
201
+
202
+ def test_attributes
203
+ # create a search class
204
+ search_class = Class.new(::SearchApi::Search::Base)
205
+
206
+ # define some search_accessors
207
+ search_class.class_eval do
208
+ model Searchable
209
+ search_accessor :a, 'b'
210
+ end
211
+
212
+ # build an instance without attributes
213
+ search = search_class.new
214
+
215
+ # assert attributes keys are symbols
216
+ assert search.attributes.keys.all? { |x| x.is_a?(Symbol) }
217
+
218
+ # assert attributes keys are search_class.search_attributes
219
+ assert_equal search_class.search_attributes.map(&:to_s).sort, search.attributes.keys.map(&:to_s).sort
220
+
221
+ # build an instance with attributes
222
+ attributes = { 'age' => 33, :funny => true, 'name' => 'jesus', :a => [], 'b'=>{}, :id => nil }
223
+ search = search_class.new(Marshal.load(Marshal.dump(attributes)))
224
+
225
+ # assert set attributes values are what is expected
226
+ attributes.each do |key, value|
227
+ assert_equal value, search.attributes[key.to_sym]
228
+ end
229
+ end
230
+
231
+ def test_attributes=
232
+ # create a search class
233
+ search_class = Class.new(::SearchApi::Search::Base)
234
+
235
+ # define some search_accessors
236
+ search_class.class_eval do
237
+ model Searchable
238
+ search_accessor 'a', :b
239
+ end
240
+
241
+ # build an instance without attributes
242
+ search = search_class.new
243
+
244
+ # assert attributes can be set
245
+ attributes = { :age => 33, 'funny' => true, :name => 'jesus', 'a' => [], :b => {}, 'id' => nil }
246
+ assert_nothing_raised do
247
+ search.attributes = Marshal.load(Marshal.dump(attributes))
248
+ end
249
+
250
+ # assert set attributes values are what is expected
251
+ attributes.each do |key, value|
252
+ assert_equal value, search.attributes[key.to_sym]
253
+ end
254
+
255
+ # assert partial attributes can be set
256
+ search.attributes = nil
257
+ attributes.each do |key, value|
258
+ assert_equal value, search.attributes[key.to_sym]
259
+ end
260
+
261
+ search.attributes = {}
262
+ attributes.each do |key, value|
263
+ assert_equal value, search.attributes[key.to_sym]
264
+ end
265
+
266
+ search.attributes = { :a => 'thing', 'b' => 'other' }
267
+ attributes.update('a' => 'thing', :b => 'other').each do |key, value|
268
+ assert_equal value, search.attributes[key.to_sym]
269
+ end
270
+ end
271
+
272
+ def test_attributes_and_setters_equivalence
273
+ # create a search class
274
+ search_class = Class.new(::SearchApi::Search::Base)
275
+
276
+ # define some search_accessors
277
+ search_class.class_eval do
278
+ model Searchable
279
+ search_accessor :a
280
+ end
281
+
282
+ # build an instance
283
+ search = search_class.new
284
+
285
+ # assert calling a setter alters attributes
286
+ search.a = 'thing'
287
+ assert_equal 'thing', search.attributes[:a]
288
+
289
+ # assert calling attributes= calls setters
290
+ assert_nothing_raised do
291
+ search.attributes = { :a => 12 }
292
+ end
293
+ def search.a=(value)
294
+ raise
295
+ end
296
+ assert_raise RuntimeError do
297
+ search.attributes = { :a => 12 }
298
+ end
299
+ end
300
+
301
+ def test_initialize_and_setters_equivalence
302
+ # create a search class
303
+ search_class = Class.new(::SearchApi::Search::Base)
304
+
305
+ # define some search_accessors
306
+ search_class.class_eval do
307
+ model Searchable
308
+ search_accessor :a
309
+ end
310
+
311
+ assert_nothing_raised do
312
+ search_class.new(:a => 12)
313
+ end
314
+ search_class.class_eval do
315
+ define_method(:a=) do
316
+ raise
317
+ end
318
+ end
319
+ assert_raise RuntimeError do
320
+ search_class.new(:a => 12)
321
+ end
322
+ end
323
+
324
+ def test_store_as_option
325
+ # create a search class
326
+ search_class = Class.new(::SearchApi::Search::Base)
327
+
328
+ # define some search_accessors
329
+ search_class.class_eval do
330
+ model Searchable
331
+ search_accessor :a, :store_as => proc { |value| value+1 }
332
+ end
333
+
334
+ search = search_class.new
335
+
336
+ search.a = 1
337
+ assert_equal 2, search.a
338
+ end
339
+
340
+ end