mini-fast-sys 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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/mini-fast-sys.gemspec +12 -0
  3. data/ransack-4.4.1/LICENSE +20 -0
  4. data/ransack-4.4.1/README.md +101 -0
  5. data/ransack-4.4.1/lib/polyamorous/activerecord/join_association.rb +70 -0
  6. data/ransack-4.4.1/lib/polyamorous/activerecord/join_association_7_2.rb +55 -0
  7. data/ransack-4.4.1/lib/polyamorous/activerecord/join_dependency.rb +102 -0
  8. data/ransack-4.4.1/lib/polyamorous/activerecord/reflection.rb +11 -0
  9. data/ransack-4.4.1/lib/polyamorous/join.rb +70 -0
  10. data/ransack-4.4.1/lib/polyamorous/polyamorous.rb +27 -0
  11. data/ransack-4.4.1/lib/polyamorous/swapping_reflection_class.rb +11 -0
  12. data/ransack-4.4.1/lib/polyamorous/tree_node.rb +7 -0
  13. data/ransack-4.4.1/lib/ransack/active_record.rb +14 -0
  14. data/ransack-4.4.1/lib/ransack/adapters/active_record/base.rb +152 -0
  15. data/ransack-4.4.1/lib/ransack/adapters/active_record/context.rb +373 -0
  16. data/ransack-4.4.1/lib/ransack/configuration.rb +209 -0
  17. data/ransack-4.4.1/lib/ransack/constants.rb +176 -0
  18. data/ransack-4.4.1/lib/ransack/context.rb +190 -0
  19. data/ransack-4.4.1/lib/ransack/helpers/form_builder.rb +277 -0
  20. data/ransack-4.4.1/lib/ransack/helpers/form_helper.rb +311 -0
  21. data/ransack-4.4.1/lib/ransack/helpers.rb +2 -0
  22. data/ransack-4.4.1/lib/ransack/invalid_search_error.rb +3 -0
  23. data/ransack-4.4.1/lib/ransack/locale/ar.yml +70 -0
  24. data/ransack-4.4.1/lib/ransack/locale/az.yml +70 -0
  25. data/ransack-4.4.1/lib/ransack/locale/bg.yml +70 -0
  26. data/ransack-4.4.1/lib/ransack/locale/ca.yml +70 -0
  27. data/ransack-4.4.1/lib/ransack/locale/cs.yml +70 -0
  28. data/ransack-4.4.1/lib/ransack/locale/da.yml +70 -0
  29. data/ransack-4.4.1/lib/ransack/locale/de.yml +70 -0
  30. data/ransack-4.4.1/lib/ransack/locale/el.yml +70 -0
  31. data/ransack-4.4.1/lib/ransack/locale/en.yml +70 -0
  32. data/ransack-4.4.1/lib/ransack/locale/es.yml +70 -0
  33. data/ransack-4.4.1/lib/ransack/locale/fa.yml +70 -0
  34. data/ransack-4.4.1/lib/ransack/locale/fi.yml +71 -0
  35. data/ransack-4.4.1/lib/ransack/locale/fr.yml +70 -0
  36. data/ransack-4.4.1/lib/ransack/locale/hu.yml +70 -0
  37. data/ransack-4.4.1/lib/ransack/locale/id.yml +70 -0
  38. data/ransack-4.4.1/lib/ransack/locale/it.yml +70 -0
  39. data/ransack-4.4.1/lib/ransack/locale/ja.yml +70 -0
  40. data/ransack-4.4.1/lib/ransack/locale/ko.yml +70 -0
  41. data/ransack-4.4.1/lib/ransack/locale/nl.yml +70 -0
  42. data/ransack-4.4.1/lib/ransack/locale/pt-BR.yml +70 -0
  43. data/ransack-4.4.1/lib/ransack/locale/ro.yml +70 -0
  44. data/ransack-4.4.1/lib/ransack/locale/ru.yml +70 -0
  45. data/ransack-4.4.1/lib/ransack/locale/sk.yml +70 -0
  46. data/ransack-4.4.1/lib/ransack/locale/sv.yml +70 -0
  47. data/ransack-4.4.1/lib/ransack/locale/tr.yml +70 -0
  48. data/ransack-4.4.1/lib/ransack/locale/uk.yml +72 -0
  49. data/ransack-4.4.1/lib/ransack/locale/zh-CN.yml +70 -0
  50. data/ransack-4.4.1/lib/ransack/locale/zh-TW.yml +70 -0
  51. data/ransack-4.4.1/lib/ransack/naming.rb +58 -0
  52. data/ransack-4.4.1/lib/ransack/nodes/attribute.rb +59 -0
  53. data/ransack-4.4.1/lib/ransack/nodes/bindable.rb +52 -0
  54. data/ransack-4.4.1/lib/ransack/nodes/condition.rb +399 -0
  55. data/ransack-4.4.1/lib/ransack/nodes/grouping.rb +206 -0
  56. data/ransack-4.4.1/lib/ransack/nodes/node.rb +34 -0
  57. data/ransack-4.4.1/lib/ransack/nodes/sort.rb +54 -0
  58. data/ransack-4.4.1/lib/ransack/nodes/value.rb +115 -0
  59. data/ransack-4.4.1/lib/ransack/predicate.rb +75 -0
  60. data/ransack-4.4.1/lib/ransack/ransacker.rb +24 -0
  61. data/ransack-4.4.1/lib/ransack/search.rb +195 -0
  62. data/ransack-4.4.1/lib/ransack/translate.rb +156 -0
  63. data/ransack-4.4.1/lib/ransack/version.rb +3 -0
  64. data/ransack-4.4.1/lib/ransack/visitor.rb +87 -0
  65. data/ransack-4.4.1/lib/ransack.rb +33 -0
  66. data/ransack-4.4.1/spec/console.rb +13 -0
  67. data/ransack-4.4.1/spec/factories/articles.rb +7 -0
  68. data/ransack-4.4.1/spec/factories/comments.rb +7 -0
  69. data/ransack-4.4.1/spec/factories/notes.rb +13 -0
  70. data/ransack-4.4.1/spec/factories/people.rb +10 -0
  71. data/ransack-4.4.1/spec/factories/tags.rb +5 -0
  72. data/ransack-4.4.1/spec/helpers/polyamorous_helper.rb +13 -0
  73. data/ransack-4.4.1/spec/helpers/ransack_helper.rb +9 -0
  74. data/ransack-4.4.1/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
  75. data/ransack-4.4.1/spec/polyamorous/join_association_spec.rb +29 -0
  76. data/ransack-4.4.1/spec/polyamorous/join_dependency_spec.rb +80 -0
  77. data/ransack-4.4.1/spec/polyamorous/join_spec.rb +19 -0
  78. data/ransack-4.4.1/spec/ransack/adapters/active_record/base_spec.rb +943 -0
  79. data/ransack-4.4.1/spec/ransack/adapters/active_record/context_spec.rb +219 -0
  80. data/ransack-4.4.1/spec/ransack/configuration_spec.rb +201 -0
  81. data/ransack-4.4.1/spec/ransack/helpers/form_builder_spec.rb +169 -0
  82. data/ransack-4.4.1/spec/ransack/helpers/form_helper_spec.rb +1075 -0
  83. data/ransack-4.4.1/spec/ransack/invalid_search_error_spec.rb +27 -0
  84. data/ransack-4.4.1/spec/ransack/nodes/condition_spec.rb +333 -0
  85. data/ransack-4.4.1/spec/ransack/nodes/grouping_spec.rb +111 -0
  86. data/ransack-4.4.1/spec/ransack/nodes/value_spec.rb +126 -0
  87. data/ransack-4.4.1/spec/ransack/predicate_spec.rb +504 -0
  88. data/ransack-4.4.1/spec/ransack/ransacker_spec.rb +69 -0
  89. data/ransack-4.4.1/spec/ransack/search_spec.rb +821 -0
  90. data/ransack-4.4.1/spec/ransack/translate_spec.rb +16 -0
  91. data/ransack-4.4.1/spec/spec_helper.rb +52 -0
  92. data/ransack-4.4.1/spec/support/en.yml +18 -0
  93. data/ransack-4.4.1/spec/support/schema.rb +419 -0
  94. metadata +133 -0
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ describe InvalidSearchError do
5
+ it 'inherits from ArgumentError' do
6
+ expect(InvalidSearchError.superclass).to eq(ArgumentError)
7
+ end
8
+
9
+ it 'can be instantiated with a message' do
10
+ error = InvalidSearchError.new('Test error message')
11
+ expect(error.message).to eq('Test error message')
12
+ end
13
+
14
+ it 'can be instantiated without a message' do
15
+ error = InvalidSearchError.new
16
+ expect(error.message).to eq('Ransack::InvalidSearchError')
17
+ end
18
+
19
+ it 'can be raised and caught' do
20
+ expect { raise InvalidSearchError.new('Test') }.to raise_error(InvalidSearchError, 'Test')
21
+ end
22
+
23
+ it 'can be raised and caught as ArgumentError' do
24
+ expect { raise InvalidSearchError.new('Test') }.to raise_error(ArgumentError, 'Test')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,333 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ module Nodes
5
+ describe Condition do
6
+ context 'bug report #1245' do
7
+ it 'preserves tuple behavior' do
8
+ ransack_hash = {
9
+ m: 'and',
10
+ g: [
11
+ { title_type_in: ['["title 1", ""]'] }
12
+ ]
13
+ }
14
+
15
+ sql = Article.ransack(ransack_hash).result.to_sql
16
+ expect(sql).to include("IN (('title 1', ''))")
17
+ end
18
+ end
19
+
20
+ context 'with an alias' do
21
+ subject {
22
+ Condition.extract(
23
+ Context.for(Person), 'term_start', Person.first(2).map(&:name)
24
+ )
25
+ }
26
+
27
+ specify { expect(subject.combinator).to eq 'or' }
28
+ specify { expect(subject.predicate.name).to eq 'start' }
29
+
30
+ it 'converts the alias to the correct attributes' do
31
+ expect(subject.attributes.map(&:name)).to eq(['name', 'email'])
32
+ end
33
+ end
34
+
35
+ context 'with multiple values and an _any predicate' do
36
+ subject {
37
+ Condition.extract(
38
+ Context.for(Person), 'name_eq_any', Person.first(2).map(&:name)
39
+ )
40
+ }
41
+
42
+ specify { expect(subject.values.size).to eq(2) }
43
+ end
44
+
45
+ describe '#negative?' do
46
+ let(:context) { Context.for(Person) }
47
+ let(:eq) { Condition.extract(context, 'name_eq', 'A') }
48
+ let(:not_eq) { Condition.extract(context, 'name_not_eq', 'A') }
49
+
50
+ specify { expect(not_eq.negative?).to be true }
51
+ specify { expect(eq.negative?).to be false }
52
+ end
53
+
54
+ context 'with an invalid predicate' do
55
+ subject {
56
+ Condition.extract(
57
+ Context.for(Person), 'name_invalid', Person.first.name
58
+ )
59
+ }
60
+
61
+ context "when ignore_unknown_conditions is false" do
62
+ before do
63
+ Ransack.configure { |c| c.ignore_unknown_conditions = false }
64
+ end
65
+
66
+ specify { expect { subject }.to raise_error ArgumentError }
67
+ specify { expect { subject }.to raise_error InvalidSearchError }
68
+ end
69
+
70
+ context "when ignore_unknown_conditions is true" do
71
+ before do
72
+ Ransack.configure { |c| c.ignore_unknown_conditions = true }
73
+ end
74
+
75
+ specify { expect(subject).to be_nil }
76
+ end
77
+ end
78
+
79
+ context 'with an empty predicate' do
80
+ subject {
81
+ Condition.extract(
82
+ Context.for(Person), 'full_name', Person.first.name
83
+ )
84
+ }
85
+
86
+ context "when default_predicate = nil" do
87
+ before do
88
+ Ransack.configure { |c| c.default_predicate = nil }
89
+ end
90
+
91
+ specify { expect(subject).to be_nil }
92
+ end
93
+
94
+ context "when default_predicate = 'eq'" do
95
+ before do
96
+ Ransack.configure { |c| c.default_predicate = 'eq' }
97
+ end
98
+
99
+ specify { expect(subject).to eq Condition.extract(Context.for(Person), 'full_name_eq', Person.first.name) }
100
+ end
101
+ end
102
+
103
+ context 'with wildcard string values' do
104
+ it 'properly quotes values with wildcards for LIKE predicates' do
105
+ ransack_hash = { name_cont: 'test%' }
106
+ sql = Person.ransack(ransack_hash).result.to_sql
107
+
108
+ # The % should be properly quoted in the SQL
109
+ case ActiveRecord::Base.connection.adapter_name
110
+ when "Mysql2"
111
+ expect(sql).to include("LIKE '%test\\\\%%'")
112
+ expect(sql).not_to include("NOT LIKE '%test\\\\%%'")
113
+ when "PostGIS", "PostgreSQL"
114
+ expect(sql).to include("ILIKE '%test\\%%'")
115
+ expect(sql).not_to include("NOT ILIKE '%test\\%%'")
116
+ else
117
+ expect(sql).to include("LIKE '%test%%'")
118
+ expect(sql).not_to include("NOT LIKE '%test%%'")
119
+ end
120
+ end
121
+
122
+ it 'properly quotes values with wildcards for NOT LIKE predicates' do
123
+ ransack_hash = { name_not_cont: 'test%' }
124
+ sql = Person.ransack(ransack_hash).result.to_sql
125
+
126
+ # The % should be properly quoted in the SQL
127
+ case ActiveRecord::Base.connection.adapter_name
128
+ when "Mysql2"
129
+ expect(sql).to include("NOT LIKE '%test\\\\%%'")
130
+ when "PostGIS", "PostgreSQL"
131
+ expect(sql).to include("NOT ILIKE '%test\\%%'")
132
+ else
133
+ expect(sql).to include("NOT LIKE '%test%%'")
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'with negative conditions on associations' do
139
+ it 'handles not_null predicate with true value correctly' do
140
+ ransack_hash = { comments_id_not_null: true }
141
+ sql = Person.ransack(ransack_hash).result.to_sql
142
+
143
+ # Should generate an IN query with IS NOT NULL condition
144
+ expect(sql).to include('IN (')
145
+ expect(sql).to include('IS NOT NULL')
146
+ expect(sql).not_to include('IS NULL')
147
+ end
148
+
149
+ it 'handles not_null predicate with false value correctly' do
150
+ ransack_hash = { comments_id_not_null: false }
151
+ sql = Person.ransack(ransack_hash).result.to_sql
152
+
153
+ # Should generate a NOT IN query with IS NULL condition
154
+ expect(sql).to include('NOT IN (')
155
+ expect(sql).to include('IS NULL')
156
+ expect(sql).not_to include('IS NOT NULL')
157
+ end
158
+
159
+ it 'handles not_cont predicate correctly' do
160
+ ransack_hash = { comments_body_not_cont: 'test' }
161
+ sql = Person.ransack(ransack_hash).result.to_sql
162
+
163
+ # Should generate a NOT IN query with LIKE condition (not NOT LIKE)
164
+ expect(sql).to include('NOT IN (')
165
+ expect(sql).to include("LIKE '%test%'")
166
+ expect(sql).not_to include("NOT LIKE '%test%'")
167
+ end
168
+ end
169
+
170
+ context 'with nested conditions' do
171
+ it 'correctly identifies non-nested conditions' do
172
+ condition = Condition.extract(
173
+ Context.for(Person), 'name_eq', 'Test'
174
+ )
175
+
176
+ # Create a mock parent table
177
+ parent_table = Person.arel_table
178
+
179
+ # Get the attribute name and make sure it starts with the table name
180
+ attribute = condition.attributes.first
181
+ expect(attribute.name).to eq('name')
182
+ expect(parent_table.name).to eq('people')
183
+
184
+ # The method should return false because 'name' doesn't start with 'people'
185
+ result = condition.send(:not_nested_condition, attribute, parent_table)
186
+ expect(result).to be false
187
+ end
188
+
189
+ it 'correctly identifies truly non-nested conditions when attribute name starts with table name' do
190
+ # Create a condition with an attribute that starts with the table name
191
+ condition = Condition.extract(
192
+ Context.for(Person), 'name_eq', 'Test'
193
+ )
194
+
195
+ # Modify the attribute name to start with the table name for testing purposes
196
+ attribute = condition.attributes.first
197
+ allow(attribute).to receive(:name).and_return('people_name')
198
+
199
+ # Create a parent table
200
+ parent_table = Person.arel_table
201
+
202
+ # Now the method should return true because 'people_name' starts with 'people'
203
+ result = condition.send(:not_nested_condition, attribute, parent_table)
204
+ expect(result).to be true
205
+ end
206
+
207
+ it 'correctly identifies nested conditions' do
208
+ condition = Condition.extract(
209
+ Context.for(Person), 'articles_title_eq', 'Test'
210
+ )
211
+
212
+ # Create a mock table alias
213
+ parent_table = Arel::Nodes::TableAlias.new(
214
+ Article.arel_table,
215
+ Article.arel_table
216
+ )
217
+
218
+ # Access the private method using send
219
+ result = condition.send(:not_nested_condition, condition.attributes.first, parent_table)
220
+
221
+ # Should return false for nested condition
222
+ expect(result).to be false
223
+ end
224
+ end
225
+
226
+ context 'with polymorphic associations and not_in predicate' do
227
+ before do
228
+ # Define test models for polymorphic associations
229
+ class ::TestTask < ActiveRecord::Base
230
+ self.table_name = 'tasks'
231
+ has_many :follows, primary_key: :uid, inverse_of: :followed, foreign_key: :followed_uid, class_name: 'TestFollow'
232
+ has_many :users, through: :follows, source: :follower, source_type: 'TestUser'
233
+
234
+ # Add ransackable_attributes method
235
+ def self.ransackable_attributes(auth_object = nil)
236
+ ["created_at", "id", "name", "uid", "updated_at"]
237
+ end
238
+
239
+ # Add ransackable_associations method
240
+ def self.ransackable_associations(auth_object = nil)
241
+ ["follows", "users"]
242
+ end
243
+ end
244
+
245
+ class ::TestFollow < ActiveRecord::Base
246
+ self.table_name = 'follows'
247
+ belongs_to :follower, polymorphic: true, foreign_key: :follower_uid, primary_key: :uid
248
+ belongs_to :followed, polymorphic: true, foreign_key: :followed_uid, primary_key: :uid
249
+
250
+ # Add ransackable_attributes method
251
+ def self.ransackable_attributes(auth_object = nil)
252
+ ["created_at", "followed_type", "followed_uid", "follower_type", "follower_uid", "id", "updated_at"]
253
+ end
254
+
255
+ # Add ransackable_associations method
256
+ def self.ransackable_associations(auth_object = nil)
257
+ ["followed", "follower"]
258
+ end
259
+ end
260
+
261
+ class ::TestUser < ActiveRecord::Base
262
+ self.table_name = 'users'
263
+ has_many :follows, primary_key: :uid, inverse_of: :follower, foreign_key: :follower_uid, class_name: 'TestFollow'
264
+ has_many :tasks, through: :follows, source: :followed, source_type: 'TestTask'
265
+
266
+ # Add ransackable_attributes method
267
+ def self.ransackable_attributes(auth_object = nil)
268
+ ["created_at", "id", "name", "uid", "updated_at"]
269
+ end
270
+
271
+ # Add ransackable_associations method
272
+ def self.ransackable_associations(auth_object = nil)
273
+ ["follows", "tasks"]
274
+ end
275
+ end
276
+
277
+ # Create tables if they don't exist
278
+ ActiveRecord::Base.connection.create_table(:tasks, force: true) do |t|
279
+ t.string :uid
280
+ t.string :name
281
+ t.timestamps null: false
282
+ end
283
+
284
+ ActiveRecord::Base.connection.create_table(:follows, force: true) do |t|
285
+ t.string :followed_uid, null: false
286
+ t.string :followed_type, null: false
287
+ t.string :follower_uid, null: false
288
+ t.string :follower_type, null: false
289
+ t.timestamps null: false
290
+ t.index [:followed_uid, :followed_type]
291
+ t.index [:follower_uid, :follower_type]
292
+ end
293
+
294
+ ActiveRecord::Base.connection.create_table(:users, force: true) do |t|
295
+ t.string :uid
296
+ t.string :name
297
+ t.timestamps null: false
298
+ end
299
+ end
300
+
301
+ after do
302
+ # Clean up test models and tables
303
+ Object.send(:remove_const, :TestTask)
304
+ Object.send(:remove_const, :TestFollow)
305
+ Object.send(:remove_const, :TestUser)
306
+
307
+ ActiveRecord::Base.connection.drop_table(:tasks, if_exists: true)
308
+ ActiveRecord::Base.connection.drop_table(:follows, if_exists: true)
309
+ ActiveRecord::Base.connection.drop_table(:users, if_exists: true)
310
+ end
311
+
312
+ it 'correctly handles not_in predicate with polymorphic associations' do
313
+ # Create the search
314
+ search = TestTask.ransack(users_uid_not_in: ['uid_example'])
315
+ sql = search.result.to_sql
316
+
317
+ # Verify the SQL contains the expected NOT IN clause
318
+ expect(sql).to include('NOT IN')
319
+ expect(sql).to include("follower_uid")
320
+ expect(sql).to include("followed_uid")
321
+ expect(sql).to include("'uid_example'")
322
+
323
+ # The SQL should include a reference to tasks.uid
324
+ expect(sql).to include("tasks")
325
+ expect(sql).to include("uid")
326
+
327
+ # The SQL should include a reference to follows table
328
+ expect(sql).to include("follows")
329
+ end
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ module Nodes
5
+ describe Grouping do
6
+ before do
7
+ @g = 1
8
+ end
9
+
10
+ let(:context) { Context.for(Person) }
11
+
12
+ subject { described_class.new(context) }
13
+
14
+ describe '#attribute_method?' do
15
+ context 'for attributes of the context' do
16
+ it 'is true' do
17
+ expect(subject.attribute_method?('name')).to be true
18
+ end
19
+
20
+ context "when the attribute contains '_and_'" do
21
+ it 'is true' do
22
+ expect(subject.attribute_method?('terms_and_conditions')).to be true
23
+ end
24
+ end
25
+
26
+ context "when the attribute contains '_or_'" do
27
+ it 'is true' do
28
+ expect(subject.attribute_method?('true_or_false')).to be true
29
+ end
30
+ end
31
+
32
+ context "when the attribute ends with '_start'" do
33
+ it 'is true' do
34
+ expect(subject.attribute_method?('life_start')).to be true
35
+ end
36
+ end
37
+
38
+ context "when the attribute ends with '_end'" do
39
+ it 'is true' do
40
+ expect(subject.attribute_method?('stop_end')).to be true
41
+ end
42
+ end
43
+ end
44
+
45
+ context 'for unknown attributes' do
46
+ it 'is false' do
47
+ expect(subject.attribute_method?('not_an_attribute')).to be false
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#conditions=' do
53
+ context 'when conditions are identical' do
54
+ let(:conditions) do
55
+ {
56
+ '0' => {
57
+ 'a' => { '0'=> { 'name' => 'name', 'ransacker_args' => '' } },
58
+ 'p' => 'cont',
59
+ 'v' => { '0' => { 'value' => 'John' } }
60
+ },
61
+ '1' => {
62
+ 'a' => { '0' => { 'name' => 'name', 'ransacker_args' => '' } },
63
+ 'p' => 'cont',
64
+ 'v' => { '0' => { 'value' => 'John' } }
65
+ }
66
+ }
67
+ end
68
+
69
+ before { subject.conditions = conditions }
70
+
71
+ it 'expect duplicates to be removed' do
72
+ expect(subject.conditions.count).to eq 1
73
+ end
74
+ end
75
+
76
+ context 'when conditions differ only by ransacker_args' do
77
+ let(:conditions) do
78
+ {
79
+ '0' => {
80
+ 'a' => {
81
+ '0' => {
82
+ 'name' => 'with_arguments',
83
+ 'ransacker_args' => [1, 2]
84
+ }
85
+ },
86
+ 'p' => 'eq',
87
+ 'v' => { '0' => { 'value' => '10' } }
88
+ },
89
+ '1' => {
90
+ 'a' => {
91
+ '0' => {
92
+ 'name' => 'with_arguments',
93
+ 'ransacker_args' => [3, 4]
94
+ }
95
+ },
96
+ 'p' => 'eq',
97
+ 'v' => { '0' => { 'value' => '10' } }
98
+ }
99
+ }
100
+ end
101
+
102
+ before { subject.conditions = conditions }
103
+
104
+ it 'expect them to be parsed as different and not as duplicates' do
105
+ expect(subject.conditions.count).to eq 2
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ module Nodes
5
+ describe Value do
6
+ let(:context) { Context.for(Person) }
7
+
8
+ subject do
9
+ Value.new(context, raw_value)
10
+ end
11
+
12
+ context "with a date value" do
13
+ let(:raw_value) { "2022-05-23" }
14
+
15
+ [:date].each do |type|
16
+ it "should cast #{type} correctly" do
17
+ result = subject.cast(type)
18
+
19
+ expect(result).to be_a_kind_of(Date)
20
+ expect(result).to eq(Date.parse(raw_value))
21
+ end
22
+ end
23
+ end
24
+
25
+ context "with a timestamp value" do
26
+ let(:raw_value) { "2022-05-23 10:40:02 -0400" }
27
+
28
+ [:datetime, :timestamp, :time, :timestamptz].each do |type|
29
+ it "should cast #{type} correctly" do
30
+ result = subject.cast(type)
31
+
32
+ expect(result).to be_a_kind_of(Time)
33
+ expect(result).to eq(Time.zone.parse(raw_value))
34
+ end
35
+ end
36
+ end
37
+
38
+ Constants::TRUE_VALUES.each do |value|
39
+ context "with a true boolean value (#{value})" do
40
+ let(:raw_value) { value.to_s }
41
+
42
+ it "should cast boolean correctly" do
43
+ result = subject.cast(:boolean)
44
+ expect(result).to eq(true)
45
+ end
46
+ end
47
+ end
48
+
49
+ Constants::FALSE_VALUES.each do |value|
50
+ context "with a false boolean value (#{value})" do
51
+ let(:raw_value) { value.to_s }
52
+
53
+ it "should cast boolean correctly" do
54
+ result = subject.cast(:boolean)
55
+
56
+ expect(result).to eq(false)
57
+ end
58
+ end
59
+ end
60
+
61
+ ["12", "101.5"].each do |value|
62
+ context "with an integer value (#{value})" do
63
+ let(:raw_value) { value }
64
+
65
+ it "should cast #{value} to integer correctly" do
66
+ result = subject.cast(:integer)
67
+
68
+ expect(result).to be_an(Integer)
69
+ expect(result).to eq(value.to_i)
70
+ end
71
+ end
72
+ end
73
+
74
+ [[], ["12"], ["101.5"]].each do |value|
75
+ context "with an array value (#{value.inspect})" do
76
+ let(:raw_value) { value }
77
+
78
+ it "should cast to integer as nil" do
79
+ result = subject.cast(:integer)
80
+
81
+ expect(result).to be nil
82
+ end
83
+ end
84
+ end
85
+
86
+ ["12", "101.5"].each do |value|
87
+ context "with a float value (#{value})" do
88
+ let(:raw_value) { value }
89
+
90
+ it "should cast #{value} to float correctly" do
91
+ result = subject.cast(:float)
92
+
93
+ expect(result).to be_an(Float)
94
+ expect(result).to eq(value.to_f)
95
+ end
96
+ end
97
+ end
98
+
99
+ ["12", "101.5"].each do |value|
100
+ context "with a decimal value (#{value})" do
101
+ let(:raw_value) { value }
102
+
103
+ it "should cast #{value} to decimal correctly" do
104
+ result = subject.cast(:decimal)
105
+
106
+ expect(result).to be_a(BigDecimal)
107
+ expect(result).to eq(value.to_d)
108
+ end
109
+ end
110
+ end
111
+
112
+ ["12", "101.513"].each do |value|
113
+ context "with a money value (#{value})" do
114
+ let(:raw_value) { value }
115
+
116
+ it "should cast #{value} to money correctly" do
117
+ result = subject.cast(:money)
118
+
119
+ expect(result).to be_a(String)
120
+ expect(result).to eq(value.to_f.to_s)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end