arel_extensions 2.0.21 → 2.2.2

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -2
  3. data/.github/workflows/publish.yml +29 -0
  4. data/.github/workflows/release.yml +30 -0
  5. data/.github/workflows/ruby.yml +377 -80
  6. data/.gitignore +7 -6
  7. data/.rubocop.yml +62 -1
  8. data/CONTRIBUTING.md +102 -0
  9. data/Gemfile +2 -23
  10. data/NEWS.md +89 -0
  11. data/README.md +228 -84
  12. data/Rakefile +11 -4
  13. data/TODO +0 -1
  14. data/appveyor.yml +60 -22
  15. data/arel_extensions.gemspec +11 -12
  16. data/bin/build +15 -0
  17. data/bin/compose +6 -0
  18. data/bin/publish +8 -0
  19. data/dev/arelx.dockerfile +44 -0
  20. data/dev/compose.yaml +71 -0
  21. data/dev/postgres.dockerfile +5 -0
  22. data/dev/rbenv +189 -0
  23. data/gemfiles/rails3.gemfile +10 -10
  24. data/gemfiles/rails4_2.gemfile +38 -0
  25. data/gemfiles/rails5.gemfile +29 -0
  26. data/gemfiles/rails5_1_4.gemfile +13 -13
  27. data/gemfiles/rails5_2.gemfile +16 -14
  28. data/gemfiles/rails6.gemfile +18 -15
  29. data/gemfiles/rails6_1.gemfile +18 -15
  30. data/gemfiles/rails7.gemfile +33 -0
  31. data/gemfiles/rails7_1.gemfile +33 -0
  32. data/gemfiles/rails7_2.gemfile +33 -0
  33. data/gemspecs/arel_extensions-v1.gemspec +12 -13
  34. data/gemspecs/arel_extensions-v2.gemspec +11 -12
  35. data/init/mssql.sql +0 -0
  36. data/init/mysql.sql +0 -0
  37. data/init/oracle.sql +0 -0
  38. data/init/postgresql.sql +0 -0
  39. data/init/sqlite.sql +0 -0
  40. data/lib/arel_extensions/aliases.rb +14 -0
  41. data/lib/arel_extensions/attributes.rb +10 -2
  42. data/lib/arel_extensions/boolean_functions.rb +2 -4
  43. data/lib/arel_extensions/common_sql_functions.rb +12 -12
  44. data/lib/arel_extensions/comparators.rb +14 -14
  45. data/lib/arel_extensions/date_duration.rb +14 -9
  46. data/lib/arel_extensions/helpers.rb +62 -0
  47. data/lib/arel_extensions/insert_manager.rb +19 -17
  48. data/lib/arel_extensions/math.rb +48 -45
  49. data/lib/arel_extensions/math_functions.rb +18 -18
  50. data/lib/arel_extensions/nodes/abs.rb +0 -0
  51. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
  52. data/lib/arel_extensions/nodes/blank.rb +1 -1
  53. data/lib/arel_extensions/nodes/case.rb +10 -12
  54. data/lib/arel_extensions/nodes/cast.rb +6 -6
  55. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  56. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  57. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  58. data/lib/arel_extensions/nodes/collate.rb +9 -9
  59. data/lib/arel_extensions/nodes/concat.rb +2 -2
  60. data/lib/arel_extensions/nodes/date_diff.rb +33 -14
  61. data/lib/arel_extensions/nodes/duration.rb +0 -0
  62. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  63. data/lib/arel_extensions/nodes/floor.rb +0 -0
  64. data/lib/arel_extensions/nodes/format.rb +3 -2
  65. data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
  66. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  67. data/lib/arel_extensions/nodes/function.rb +22 -26
  68. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  69. data/lib/arel_extensions/nodes/json.rb +15 -9
  70. data/lib/arel_extensions/nodes/length.rb +6 -0
  71. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  72. data/lib/arel_extensions/nodes/locate.rb +1 -1
  73. data/lib/arel_extensions/nodes/log10.rb +0 -0
  74. data/lib/arel_extensions/nodes/matches.rb +1 -1
  75. data/lib/arel_extensions/nodes/md5.rb +0 -0
  76. data/lib/arel_extensions/nodes/power.rb +0 -0
  77. data/lib/arel_extensions/nodes/rand.rb +0 -0
  78. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  79. data/lib/arel_extensions/nodes/replace.rb +2 -10
  80. data/lib/arel_extensions/nodes/rollup.rb +36 -0
  81. data/lib/arel_extensions/nodes/round.rb +0 -0
  82. data/lib/arel_extensions/nodes/select.rb +10 -0
  83. data/lib/arel_extensions/nodes/soundex.rb +2 -2
  84. data/lib/arel_extensions/nodes/std.rb +0 -0
  85. data/lib/arel_extensions/nodes/substring.rb +1 -1
  86. data/lib/arel_extensions/nodes/sum.rb +0 -0
  87. data/lib/arel_extensions/nodes/then.rb +1 -1
  88. data/lib/arel_extensions/nodes/trim.rb +2 -2
  89. data/lib/arel_extensions/nodes/union.rb +5 -5
  90. data/lib/arel_extensions/nodes/union_all.rb +4 -4
  91. data/lib/arel_extensions/nodes/wday.rb +0 -0
  92. data/lib/arel_extensions/nodes.rb +0 -0
  93. data/lib/arel_extensions/null_functions.rb +16 -0
  94. data/lib/arel_extensions/predications.rb +10 -10
  95. data/lib/arel_extensions/railtie.rb +1 -1
  96. data/lib/arel_extensions/set_functions.rb +3 -3
  97. data/lib/arel_extensions/string_functions.rb +19 -10
  98. data/lib/arel_extensions/tasks.rb +2 -2
  99. data/lib/arel_extensions/version.rb +1 -1
  100. data/lib/arel_extensions/visitors/convert_format.rb +0 -0
  101. data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
  102. data/lib/arel_extensions/visitors/mssql.rb +394 -169
  103. data/lib/arel_extensions/visitors/mysql.rb +238 -151
  104. data/lib/arel_extensions/visitors/oracle.rb +170 -131
  105. data/lib/arel_extensions/visitors/oracle12.rb +16 -16
  106. data/lib/arel_extensions/visitors/postgresql.rb +170 -140
  107. data/lib/arel_extensions/visitors/sqlite.rb +88 -87
  108. data/lib/arel_extensions/visitors/to_sql.rb +185 -156
  109. data/lib/arel_extensions/visitors.rb +73 -60
  110. data/lib/arel_extensions.rb +173 -36
  111. data/test/arelx_test_helper.rb +49 -1
  112. data/test/database.yml +13 -7
  113. data/test/real_db_test.rb +101 -83
  114. data/test/support/fake_record.rb +8 -2
  115. data/test/test_comparators.rb +5 -5
  116. data/test/visitors/test_bulk_insert_oracle.rb +5 -5
  117. data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
  118. data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
  119. data/test/visitors/test_oracle.rb +14 -14
  120. data/test/visitors/test_to_sql.rb +121 -93
  121. data/test/with_ar/all_agnostic_test.rb +630 -320
  122. data/test/with_ar/insert_agnostic_test.rb +25 -18
  123. data/test/with_ar/test_bulk_sqlite.rb +11 -7
  124. data/test/with_ar/test_math_sqlite.rb +18 -14
  125. data/test/with_ar/test_string_mysql.rb +26 -22
  126. data/test/with_ar/test_string_sqlite.rb +26 -22
  127. data/version_v1.rb +1 -1
  128. data/version_v2.rb +1 -1
  129. metadata +24 -26
  130. data/.travis/oracle/download.js +0 -152
  131. data/.travis/oracle/download.sh +0 -30
  132. data/.travis/oracle/download_ojdbc.js +0 -116
  133. data/.travis/oracle/install.sh +0 -34
  134. data/.travis/setup_accounts.sh +0 -9
  135. data/.travis/sqlite3/extension-functions.sh +0 -6
  136. data/.travis.yml +0 -193
  137. data/gemfiles/rails4.gemfile +0 -29
  138. data/gemfiles/rails5_0.gemfile +0 -29
@@ -2,19 +2,22 @@ require 'arelx_test_helper'
2
2
  require 'date'
3
3
 
4
4
  module ArelExtensions
5
- module WthAr
5
+ module WithAr
6
6
  class ListTest < Minitest::Test
7
- require 'minitest/pride'
8
7
  def connect_db
9
8
  ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
10
- if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
11
- @env_db = (RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
12
- skip "Platform not supported"
9
+ if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx') || (RUBY_PLATFORM == 'java')) # not supported
10
+ @env_db = (RUBY_PLATFORM == 'java' ? 'jdbc-sqlite' : 'sqlite')
11
+ skip "Platform not supported (DB: #{ENV['DB']}, RUBY_ENGINE: #{RUBY_ENGINE}, RUBY_PLATFORM: #{RUBY_PLATFORM})"
13
12
  else
14
13
  @env_db = ENV['DB']
15
14
  end
16
15
  ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
17
- ActiveRecord::Base.default_timezone = :utc
16
+ if ActiveRecord::VERSION::MAJOR >= 7
17
+ ActiveRecord.default_timezone = :utc
18
+ else
19
+ ActiveRecord::Base.default_timezone = :utc
20
+ end
18
21
  @cnx = ActiveRecord::Base.connection
19
22
  $sqlite = @cnx.adapter_name =~ /sqlite/i
20
23
  $load_extension_disabled ||= false
@@ -29,14 +32,14 @@ module ArelExtensions
29
32
  t.column :name, :string
30
33
  t.column :comments, :text
31
34
  t.column :created_at, :date
32
- t.column :updated_at, :datetime
35
+ t.column :updated_at, :datetime, precision: nil
33
36
  t.column :duration, :time
34
37
  t.column :other, :string
35
- t.column :score, :decimal, :precision => 20, :scale => 10
38
+ t.column :score, :decimal, precision: 20, scale: 10
36
39
  end
37
40
  @cnx.drop_table(:product_tests) rescue nil
38
41
  @cnx.create_table :product_tests do |t|
39
- t.column :price, :decimal, :precision => 20, :scale => 10
42
+ t.column :price, :decimal, precision: 20, scale: 10
40
43
  end
41
44
  end
42
45
 
@@ -51,24 +54,26 @@ module ArelExtensions
51
54
  d = Date.new(2016, 5, 23)
52
55
  connect_db
53
56
  setup_db
54
- u = User.create :age => 5, :name => "Lucas", :created_at => d, :score => 20.16, :updated_at => Time.utc(2014, 3, 3, 12, 42, 0)
55
- @lucas = User.where(:id => u.id)
56
- u = User.create :age => 15, :name => "Sophie", :created_at => d, :score => 20.16
57
- @sophie = User.where(:id => u.id)
58
- u = User.create :age => 20, :name => "Camille", :created_at => d, :score => -20.16, :comments => ''
59
- @camille = User.where(:id => u.id)
60
- u = User.create :age => 21, :name => "Arthur", :created_at => d, :score => 65.62, :comments => 'arrêté'
61
- @arthur = User.where(:id => u.id)
62
- u = User.create :age => 23, :name => "Myung", :created_at => d, :score => 20.16, :comments => ' '
63
- @myung = User.where(:id => u.id)
64
- u = User.create :age => 25, :name => "Laure", :created_at => d, :score => 20.16, :duration => Time.utc(2001, 1, 1, 12, 42, 21),:updated_at => Time.utc(2014, 3, 3, 12, 42, 0)
65
- @laure = User.where(:id => u.id)
66
- u = User.create :age => nil, :name => "Test", :created_at => d, :score => 1.62, :other => 'toto'
67
- @test = User.where(:id => u.id)
68
- u = User.create :age => -42, :name => "Negatif", :comments => '1,22,3,42,2', :created_at => d, :updated_at => d.to_time, :score => 0.17
69
- @neg = User.where(:id => u.id)
70
- u = User.create :age => 15, :name => "Justin", :created_at => d, :score => 11.0
71
- @justin = User.where(:id => u.id)
57
+ u = User.create age: 5, name: 'Lucas', created_at: d, score: 20.16, updated_at: Time.utc(2014, 3, 3, 12, 42, 0)
58
+ @lucas = User.where(id: u.id)
59
+ u = User.create age: 15, name: 'Sophie', created_at: d, score: 20.16
60
+ @sophie = User.where(id: u.id)
61
+ u = User.create age: 20, name: 'Camille', created_at: d, score: -20.16, comments: ''
62
+ @camille = User.where(id: u.id)
63
+ u = User.create age: 21, name: 'Arthur', created_at: d, score: 65.62, comments: 'arrêté'
64
+ @arthur = User.where(id: u.id)
65
+ u = User.create age: 23, name: 'Myung', created_at: d, score: 20.16, comments: ' '
66
+ @myung = User.where(id: u.id)
67
+ u = User.create age: 25, name: 'Laure', created_at: d, score: 20.16, duration: Time.utc(2001, 1, 1, 12, 42, 21), updated_at: Time.utc(2014, 3, 3, 12, 42, 0)
68
+ @laure = User.where(id: u.id)
69
+ u = User.create age: nil, name: 'Test', created_at: d, score: 1.62, other: 'toto'
70
+ @test = User.where(id: u.id)
71
+ u = User.create age: -42, name: 'Negatif', comments: '1,22,3,42,2', created_at: d, updated_at: d.to_time, score: 0.17
72
+ @neg = User.where(id: u.id)
73
+ u = User.create age: 15, name: 'Justin', created_at: d, score: 11.0
74
+ @justin = User.where(id: u.id)
75
+ u = User.create age: nil, name: 'nilly', created_at: nil, score: nil
76
+ @nilly = User.where(id: u.id)
72
77
 
73
78
  @age = User.arel_table[:age]
74
79
  @name = User.arel_table[:name]
@@ -103,6 +108,14 @@ module ArelExtensions
103
108
  end
104
109
  end
105
110
 
111
+ # Connection and column info
112
+ def test_column_of
113
+ assert_nil Arel.column_of('chupa', 'maflavla'), 'Non-existent table and column should return nil'
114
+ assert_nil Arel.column_of('chupa', 'updated_at'), 'Non-existent table but existent column should return nil'
115
+ assert_nil Arel.column_of('user_tests', 'maflavla'), 'Existent table but non-existent column should return nil'
116
+ assert_equal 'updated_at', Arel.column_of('user_tests', 'updated_at').name, 'An existing column name should be returned'
117
+ end
118
+
106
119
  # Math Functions
107
120
  def test_classical_arel
108
121
  assert_in_epsilon 42.16, t(@laure, @score + 22), 0.01
@@ -137,7 +150,7 @@ module ArelExtensions
137
150
  def test_rand
138
151
  assert 42 != User.select(Arel.rand.as('res')).first.res
139
152
  assert 0 <= User.select(Arel.rand.abs.as('res')).first.res
140
- assert_equal 9, User.order(Arel.rand).limit(50).count
153
+ assert_equal 10, User.order(Arel.rand).limit(50).count
141
154
  end
142
155
 
143
156
  def test_round
@@ -149,16 +162,16 @@ module ArelExtensions
149
162
 
150
163
  def test_sum
151
164
  if @env_db == 'mssql'
152
- skip "SQL Server forces order?" # TODO
153
- assert_equal 83, User.select((@age.sum + 1).as("res"), User.arel_table[:id].sum).take(50).reorder(@age).first.res
154
- assert_equal 164, User.reorder(nil).select((@age.sum + @age.sum).as("res"), User.arel_table[:id].sum).take(50).first.res
155
- assert_equal 246, User.reorder(nil).select(((@age * 3).sum).as("res"), User.arel_table[:id].sum).take(50).first.res
156
- assert_equal 4234, User.reorder(nil).select(((@age * @age).sum).as("res"), User.arel_table[:id].sum).take(50).first.res
165
+ skip 'SQL Server forces order?' # TODO
166
+ assert_equal 83, User.select((@age.sum + 1).as('res'), User.arel_table[:id].sum).take(50).reorder(@age).first.res
167
+ assert_equal 164, User.reorder(nil).select((@age.sum + @age.sum).as('res'), User.arel_table[:id].sum).take(50).first.res
168
+ assert_equal 246, User.reorder(nil).select(((@age * 3).sum).as('res'), User.arel_table[:id].sum).take(50).first.res
169
+ assert_equal 4234, User.reorder(nil).select(((@age * @age).sum).as('res'), User.arel_table[:id].sum).take(50).first.res
157
170
  else
158
- assert_equal 83, User.select((@age.sum + 1).as("res")).take(50).first.res
159
- assert_equal 164, User.select((@age.sum + @age.sum).as("res")).take(50).first.res
160
- assert_equal 246, User.select((@age * 3).sum.as("res")).take(50).first.res
161
- assert_equal 4234, User.select(((@age * @age).sum).as("res")).take(50).first.res
171
+ assert_equal 83, User.select((@age.sum + 1).as('res')).take(50).first.res
172
+ assert_equal 164, User.select((@age.sum + @age.sum).as('res')).take(50).first.res
173
+ assert_equal 246, User.select((@age * 3).sum.as('res')).take(50).first.res
174
+ assert_equal 4234, User.select(((@age * @age).sum).as('res')).take(50).first.res
162
175
  end
163
176
  end
164
177
 
@@ -166,25 +179,74 @@ module ArelExtensions
166
179
  # Since Arel10 (Rails6.1), some unwanted behaviors on aggregated calculation were present.
167
180
  # This should works no matter which version of rails is used
168
181
  assert User.group(:score).average(:id).values.all?{|e| !e.nil?}
182
+
183
+ # Since Rails 7, a patch to calculations.rb has tirggered a double
184
+ # quoting of the alias name. See https://github.com/rails/rails/commit/7e6e9091e55c3357b0162d44b6ab955ed0c718d5
185
+ # Before the patch that fixed this the following error would occur:
186
+ # ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: zero-length delimited identifier at or near """"
187
+ assert User.group(:score).count(:id).values.all?{|e| !e.nil?}
188
+ end
189
+
190
+ def test_rollup
191
+ skip "sqlite not supported" if $sqlite
192
+ at = User.arel_table
193
+ # single
194
+ q = User.select(at[:name], at[:age].sum).group(Arel::Nodes::RollUp.new([at[:name]]))
195
+ assert q.to_a.length > 0
196
+
197
+ # multi
198
+ q = User.select(at[:name], at[:score], at[:age].sum).group(Arel::Nodes::RollUp.new([at[:score], at[:name]]))
199
+ assert q.to_a.length > 0
200
+
201
+ # hybrid
202
+ q = User.select(at[:name], at[:score], at[:age].sum).group(at[:score], Arel::Nodes::RollUp.new([at[:name]]))
203
+ assert q.to_a.length > 0
204
+
205
+ ## Using Arel.rollup which is less verbose than the original way
206
+
207
+ # simple
208
+ q = User.select(at[:name], at[:age].sum).group(Arel.rollup(at[:name]))
209
+ assert q.to_a.length > 0
210
+
211
+ # multi
212
+ q = User.select(at[:name], at[:score], at[:age].sum).group(Arel.rollup([at[:score], at[:name]]))
213
+ assert q.to_a.length > 0
214
+
215
+ # hybrid
216
+ q = User.select(at[:name], at[:score], at[:age].sum).group(at[:score], Arel.rollup([at[:name]]))
217
+ assert q.to_a.length > 0
218
+
219
+ ## Using at[:col].rollup which is handy for single column rollups
220
+
221
+ # simple
222
+ q = User.select(at[:name], at[:age].sum).group(at[:name].rollup)
223
+ assert q.to_a.length > 0
224
+
225
+ q = User.select(at[:name], at[:score], at[:age].sum).group(at[:name].rollup, at[:score].rollup)
226
+ assert q.to_a.length > 0
227
+
228
+ # hybrid
229
+ q = User.select(at[:name], at[:score], at[:age].sum).group(at[:name], at[:score].rollup)
230
+ assert q.to_a.length > 0
169
231
  end
170
232
 
171
233
  # String Functions
172
234
  def test_concat
173
235
  assert_equal 'Camille Camille', t(@camille, @name + ' ' + @name)
174
236
  assert_equal 'Laure 2', t(@laure, @name + ' ' + 2)
175
- assert_equal 'Test Laure', t(@laure, Arel::Nodes.build_quoted('Test ') + @name)
176
-
177
- skip "No group_concat in SqlServer before 2017" if @env_db == 'mssql'
178
- assert_equal "Lucas Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat(' '))
179
- assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat(','))
180
- assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat)
181
-
182
- skip "No order in group_concat in SqlLite" if $sqlite
183
- assert_equal "Arthur,Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@name.asc))
184
- assert_equal "Sophie,Lucas,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@name.desc))
185
- assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',[@score.asc,@name.asc]))
186
- assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@score.asc,@name.asc))
187
- assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',order: [@score.asc,@name.asc]))
237
+ assert_equal 'Test Laure', t(@laure, Arel.quoted('Test ') + @name)
238
+
239
+ skip 'No group_concat in SqlServer before 2017' if @env_db == 'mssql'
240
+ assert_equal 'Lucas Sophie', t(User.where(name: %w[Lucas Sophie]), @name.group_concat(' '))
241
+ assert_equal 'Lucas,Sophie', t(User.where(name: %w[Lucas Sophie]), @name.group_concat(','))
242
+ assert_equal 'Lucas,Sophie', t(User.where(name: %w[Lucas Sophie]), @name.group_concat)
243
+
244
+ skip 'No order in group_concat in SqlLite' if $sqlite
245
+ assert_equal 'Arthur,Lucas,Sophie', t(User.where(name: %w[Lucas Sophie Arthur]), @name.group_concat(',', @name.asc))
246
+ assert_equal 'Sophie,Lucas,Arthur', t(User.where(name: %w[Lucas Sophie Arthur]), @name.group_concat(',', @name.desc))
247
+ assert_equal 'Lucas,Sophie,Arthur', t(User.where(name: %w[Lucas Sophie Arthur]), @name.group_concat(',', [@score.asc, @name.asc]))
248
+ assert_equal 'Lucas,Sophie,Arthur', t(User.where(name: %w[Lucas Sophie Arthur]), @name.group_concat(',', @score.asc, @name.asc))
249
+ assert_equal 'Lucas,Sophie,Arthur', t(User.where(name: %w[Lucas Sophie Arthur]), @name.group_concat(',', order: [@score.asc, @name.asc]))
188
250
  end
189
251
 
190
252
  def test_length
@@ -195,15 +257,15 @@ module ArelExtensions
195
257
 
196
258
  def test_md5
197
259
  skip "Sqlite can't do md5" if $sqlite
198
- assert_equal "e2cf99ca82a7e829d2a4ac85c48154d0", t(@camille, @name.md5)
199
- assert_equal "c3d41bf5efb468a1bcce53bd53726c85", t(@lucas, @name.md5)
260
+ assert_equal 'e2cf99ca82a7e829d2a4ac85c48154d0', t(@camille, @name.md5)
261
+ assert_equal 'c3d41bf5efb468a1bcce53bd53726c85', t(@lucas, @name.md5)
200
262
  end
201
263
 
202
264
  def test_locate
203
265
  skip "Sqlite version can't load extension for locate" if $sqlite && $load_extension_disabled
204
- assert_equal 1, t(@camille, @name.locate("C"))
205
- assert_equal 0, t(@lucas, @name.locate("z"))
206
- assert_equal 5, t(@lucas, @name.locate("s"))
266
+ assert_equal 1, t(@camille, @name.locate('C'))
267
+ assert_equal 0, t(@lucas, @name.locate('z'))
268
+ assert_equal 5, t(@lucas, @name.locate('s'))
207
269
  end
208
270
 
209
271
  def test_substring
@@ -213,7 +275,7 @@ module ArelExtensions
213
275
  else
214
276
  assert_equal('', t(@lucas, @name.substring(42)))
215
277
  end
216
- assert_equal 'Lu', t(@lucas, @name.substring(1,2))
278
+ assert_equal 'Lu', t(@lucas, @name.substring(1, 2))
217
279
 
218
280
  assert_equal 'C', t(@camille, @name[0, 1])
219
281
  assert_equal 'C', t(@camille, @name[0])
@@ -222,17 +284,17 @@ module ArelExtensions
222
284
  else
223
285
  assert_equal('', t(@lucas, @name[42]))
224
286
  end
225
- assert_equal 'Lu', t(@lucas, @name[0,2])
287
+ assert_equal 'Lu', t(@lucas, @name[0, 2])
226
288
  assert_equal 'Lu', t(@lucas, @name[0..1])
227
289
 
228
290
  # substring should accept string function
229
291
  assert_equal 'Ce', t(@camille, @name.substring(1, 1).concat('e'))
230
- assert_equal 'Ce', t(@camille, @name.substring(1, 1)+'e')
292
+ assert_equal 'Ce', t(@camille, @name.substring(1, 1) + 'e')
231
293
  end
232
294
 
233
295
  def test_find_in_set
234
296
  skip "Sqlite version can't load extension for find_in_set" if $sqlite && $load_extension_disabled
235
- skip "SQL Server does not know about FIND_IN_SET" if @env_db == 'mssql'
297
+ skip 'SQL Server does not know about FIND_IN_SET' if @env_db == 'mssql'
236
298
  assert_equal 5, t(@neg, @comments & 2)
237
299
  assert_equal 0, t(@neg, @comments & 6) # not found
238
300
  end
@@ -244,10 +306,10 @@ module ArelExtensions
244
306
  assert t(@neg, @name >= 'Mest') == true || t(@neg, @name >= 'Mest') == 't' # depends of ar version
245
307
  assert t(@neg, @name <= (@name + 'Z')) == true || t(@neg, @name <= (@name + 'Z')) == 't'
246
308
  elsif @env_db == 'oracle'
247
- assert_equal 1, t(@neg, ArelExtensions::Nodes::Case.new.when(@name >= 'Mest').then(1).else(0))
248
- assert_equal 1, t(@neg, ArelExtensions::Nodes::Case.new.when(@name <= (@name + 'Z')).then(1).else(0))
249
- assert_equal 1, t(@neg, ArelExtensions::Nodes::Case.new.when(@name > 'Mest').then(1).else(0))
250
- assert_equal 1, t(@neg, ArelExtensions::Nodes::Case.new.when(@name < (@name + 'Z')).then(1).else(0))
309
+ assert_equal 1, t(@neg, Arel.when(@name >= 'Mest').then(1).else(0))
310
+ assert_equal 1, t(@neg, Arel.when(@name <= (@name + 'Z')).then(1).else(0))
311
+ assert_equal 1, t(@neg, Arel.when(@name > 'Mest').then(1).else(0))
312
+ assert_equal 1, t(@neg, Arel.when(@name < (@name + 'Z')).then(1).else(0))
251
313
  else
252
314
  assert_equal 1, t(@neg, @name >= 'Mest')
253
315
  assert_equal 1, t(@neg, @name <= (@name + 'Z'))
@@ -260,74 +322,74 @@ module ArelExtensions
260
322
  skip "Sqlite can't compare time" if $sqlite
261
323
  skip "Oracle can't compare time" if @env_db == 'oracle'
262
324
  # @created_at == 2016-05-23
263
- assert_includes [true,'t',1], t(@laure, ArelExtensions::Nodes::Case.new.when(@created_at >= '2014-01-01').then(1).else(0))
264
- assert_includes [false,'f',0], t(@laure, ArelExtensions::Nodes::Case.new.when(@created_at >= '2018-01-01').then(1).else(0))
325
+ assert_includes [true, 't', 1], t(@laure, Arel.when(@created_at >= '2014-01-01').then(1).else(0))
326
+ assert_includes [false, 'f', 0], t(@laure, Arel.when(@created_at >= '2018-01-01').then(1).else(0))
265
327
  # @updated_at == 2014-03-03 12:42:00
266
- assert_includes [true,'t',1], t(@laure, ArelExtensions::Nodes::Case.new.when(@updated_at >= '2014-03-03 10:10:10').then(1).else(0))
267
- assert_includes [false,'f',0], t(@laure, ArelExtensions::Nodes::Case.new.when(@updated_at >= '2014-03-03 13:10:10').then(1).else(0))
328
+ assert_includes [true, 't', 1], t(@laure, Arel.when(@updated_at >= '2014-03-03 10:10:10').then(1).else(0))
329
+ assert_includes [false, 'f', 0], t(@laure, Arel.when(@updated_at >= '2014-03-03 13:10:10').then(1).else(0))
268
330
  # @duration == 12:42:21
269
- # puts @laure.select(ArelExtensions::Nodes::Case.new.when(@duration >= '10:10:10').then(1).else(0)).to_sql
270
- # puts @laure.select(ArelExtensions::Nodes::Case.new.when(@duration >= '14:10:10').then(1).else(0)).to_sql
271
- assert_includes [true,'t',1], t(@laure, ArelExtensions::Nodes::Case.new.when(@duration >= '10:10:10').then(1).else(0))
272
- assert_includes [false,'f',0], t(@laure, ArelExtensions::Nodes::Case.new.when(@duration >= '14:10:10').then(1).else(0))
331
+ # puts @laure.select(Arel.when(@duration >= '10:10:10').then(1).else(0)).to_sql
332
+ # puts @laure.select(Arel.when(@duration >= '14:10:10').then(1).else(0)).to_sql
333
+ assert_includes [true, 't', 1], t(@laure, Arel.when(@duration >= '10:10:10').then(1).else(0))
334
+ assert_includes [false, 'f', 0], t(@laure, Arel.when(@duration >= '14:10:10').then(1).else(0))
273
335
  end
274
336
 
275
337
  def test_regexp_not_regexp
276
338
  skip "Sqlite version can't load extension for regexp" if $sqlite && $load_extension_disabled
277
- skip "SQL Server does not know about REGEXP without extensions" if @env_db == 'mssql'
339
+ skip 'SQL Server does not know about REGEXP without extensions' if @env_db == 'mssql'
278
340
  assert_equal 1, User.where(@name =~ '^M').count
279
- assert_equal 7, User.where(@name !~ '^L').count
341
+ assert_equal 8, User.where(@name !~ '^L').count
280
342
  assert_equal 1, User.where(@name =~ /^M/).count
281
- assert_equal 7, User.where(@name !~ /^L/).count
343
+ assert_equal 8, User.where(@name !~ /^L/).count
282
344
  end
283
345
 
284
346
  def test_imatches
285
347
  # puts User.where(@name.imatches('m%')).to_sql
286
348
  assert_equal 1, User.where(@name.imatches('m%')).count
287
349
  assert_equal 4, User.where(@name.imatches_any(['L%', '%e'])).count
288
- assert_equal 7, User.where(@name.idoes_not_match('L%')).count
350
+ assert_equal 8, User.where(@name.idoes_not_match('L%')).count
289
351
  end
290
352
 
291
353
  def test_replace
292
- assert_equal "LucaX", t(@lucas, @name.replace("s", "X"))
293
- assert_equal "replace", t(@lucas, @name.replace(@name, "replace"))
294
-
295
- skip "Sqlite does not seem to support regexp_replace" if $sqlite
296
- skip "SQL Server does not know about REGEXP without extensions" if @env_db == 'mssql'
297
- skip "Travis mysql version does not support REGEXP_REPLACE" if @env_db == 'mysql'
298
- assert_equal "LXcXs", t(@lucas, @name.replace(/[ua]/, "X"))
299
- assert_equal "LXcXs", t(@lucas, @name.regexp_replace(/[ua]/, "X"))
300
- assert_equal "LXcXs", t(@lucas, @name.regexp_replace('[ua]', "X"))
354
+ assert_equal 'LucaX', t(@lucas, @name.replace('s', 'X'))
355
+ assert_equal 'replace', t(@lucas, @name.replace(@name, 'replace'))
356
+
357
+ skip 'Sqlite does not seem to support regexp_replace' if $sqlite
358
+ skip 'SQL Server does not know about REGEXP without extensions' if @env_db == 'mssql'
359
+ skip 'Travis mysql version does not support REGEXP_REPLACE' if @env_db == 'mysql'
360
+ assert_equal 'LXcXs', t(@lucas, @name.replace(/[ua]/, 'X'))
361
+ assert_equal 'LXcXs', t(@lucas, @name.regexp_replace(/[ua]/, 'X'))
362
+ assert_equal 'LXcXs', t(@lucas, @name.regexp_replace('[ua]', 'X'))
301
363
  end
302
364
 
303
365
  def test_replace_once
304
- skip "TODO"
366
+ skip 'TODO'
305
367
  # skip "Sqlite version can't load extension for locate" if $sqlite && $load_extension_disabled
306
- assert_equal "LuCas", t(@lucas, @name.substring(1, @name.locate('c') - 1) + 'C' + @name.substring(@name.locate('c') + 1, @name.length))
368
+ assert_equal 'LuCas', t(@lucas, @name.substring(1, @name.locate('c') - 1) + 'C' + @name.substring(@name.locate('c') + 1, @name.length))
307
369
  end
308
370
 
309
371
  def test_soundex
310
372
  skip "Sqlite version can't load extension for soundex" if $sqlite && $load_extension_disabled
311
373
  skip "PostgreSql version can't load extension for soundex" if @env_db == 'postgresql'
312
- assert_equal "C540", t(@camille, @name.soundex)
313
- assert_equal 9, User.where(@name.soundex.eq(@name.soundex)).count
314
- assert_equal 9, User.where(@name.soundex == @name.soundex).count
374
+ assert_equal 'C540', t(@camille, @name.soundex)
375
+ assert_equal 10, User.where(@name.soundex.eq(@name.soundex)).count
376
+ assert_equal 10, User.where(@name.soundex == @name.soundex).count
315
377
  end
316
378
 
317
379
  def test_change_case
318
- assert_equal "myung", t(@myung, @name.downcase)
319
- assert_equal "MYUNG", t(@myung, @name.upcase)
320
- assert_equal "myung", t(@myung, @name.upcase.downcase)
380
+ assert_equal 'myung', t(@myung, @name.downcase)
381
+ assert_equal 'MYUNG', t(@myung, @name.upcase)
382
+ assert_equal 'myung', t(@myung, @name.upcase.downcase)
321
383
  end
322
384
 
323
385
  def test_trim
324
- assert_equal "Myung", t(@myung, @name.trim)
325
- assert_equal "Myung", t(@myung, @name.trim.ltrim.rtrim)
326
- assert_equal "Myun", t(@myung, @name.rtrim("g"))
327
- assert_equal "yung", t(@myung, @name.ltrim("M"))
328
- assert_equal "yung", t(@myung, (@name + "M").trim("M"))
329
- skip "Oracle does not accept multi char trim" if @env_db == 'oracle'
330
- assert_equal "", t(@myung, @name.rtrim(@name))
386
+ assert_equal 'Myung', t(@myung, @name.trim)
387
+ assert_equal 'Myung', t(@myung, @name.trim.ltrim.rtrim)
388
+ assert_equal 'Myun', t(@myung, @name.rtrim('g'))
389
+ assert_equal 'yung', t(@myung, @name.ltrim('M'))
390
+ assert_equal 'yung', t(@myung, (@name + 'M').trim('M'))
391
+ skip 'Oracle does not accept multi char trim' if @env_db == 'oracle'
392
+ assert_equal '', t(@myung, @name.rtrim(@name))
331
393
  end
332
394
 
333
395
  def test_blank
@@ -356,33 +418,244 @@ module ArelExtensions
356
418
  assert_equal 'true', t(@neg, @comments.not_blank.then('true', 'false'))
357
419
  end
358
420
 
421
+ # This test repeats a lot of `test_blank` cases.
422
+ def test_present
423
+ if @env_db == 'postgresql'
424
+ assert_includes [true, 't'], t(@myung, @name.present) # depends of adapter
425
+ assert_includes [false, 'f'], t(@myung, @comments.present)
426
+ end
427
+ assert_equal 1, @myung.where(@name.present).count
428
+ assert_equal 0, @myung.where(@comments.present).count
429
+ assert_equal 0, @sophie.where(@comments.present).count
430
+ assert_equal 0, @camille.where(@comments.present).count
431
+
432
+ assert_equal 1, @neg.where(@comments.present).count
433
+ assert_equal 'true', t(@myung, @name.present.then('true', 'false'))
434
+ assert_equal 'false', t(@myung, @comments.present.then('true', 'false'))
435
+ assert_equal 'true', t(@neg, @comments.present.then('true', 'false'))
436
+ end
437
+
359
438
  def test_format
360
- assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
361
- skip "SQL Server does not accept any format" if @env_db == 'mssql'
362
- assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
363
- assert_equal '12:42%', t(@lucas, @updated_at.format('%R%%'))
439
+ %i[format format_date].each do |method|
440
+ assert_equal '2016-05-23', t(@lucas, @created_at.send(method, '%Y-%m-%d'))
441
+ assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S'))
442
+ assert_equal '12:42%', t(@lucas, @updated_at.send(method, '%R%%'))
443
+
444
+ # The following tests will ensure proper conversion of timestamps to
445
+ # requested timezones.
446
+ #
447
+ # The names of the timezones is highly dependant on the underlying
448
+ # operating system, and this is why we need to handle each database
449
+ # separately: the images we're using to test these databases are
450
+ # different. So don't rely on the provided examples. Your setup is your
451
+ # reference.
452
+ #
453
+ # One could always have portable code if s/he uses standard
454
+ # abbreviations, like:
455
+ #
456
+ # 1. CET => Central European Time
457
+ # 2. CEST => Central European Summer Time
458
+ #
459
+ # Which implies that the caller should handle daylight saving detection.
460
+ # In fact, CET will handle daylight saving in MySQL but not Postgres.
461
+ #
462
+ # It looks like the posix convention is supported by mysql and
463
+ # postgresql, e.g.:
464
+ #
465
+ # posix/Europe/Paris
466
+ # posix/America/Nipigon
467
+ #
468
+ # so it looks like a more reliably portable way of specifying it.
469
+ time_zones = {
470
+ 'mssql' => {
471
+ 'utc' => 'UTC',
472
+ 'sao_paulo' => 'Argentina Standard Time',
473
+ 'tahiti' => 'Hawaiian Standard Time',
474
+ 'paris' => 'Central European Standard Time'
475
+ },
476
+ 'posix' => {
477
+ 'utc' => 'UTC',
478
+ 'sao_paulo' => 'America/Sao_Paulo',
479
+ 'tahiti' => 'Pacific/Tahiti',
480
+ 'paris' => 'Europe/Paris'
481
+ }
482
+ }
483
+
484
+ skip "Unsupported timezone conversion for DB=#{ENV['DB']}" if !%w[mssql mysql oracle postgresql].include?(ENV['DB'])
485
+ # TODO: Standarize timezone conversion across all databases.
486
+ # This test case will be refactored and should work the same across all vendors.
487
+ if ENV['DB'] == 'mssql' && /Microsoft SQL Server (\d+)/.match(ActiveRecord::Base.connection.select_value('SELECT @@version'))[1].to_i < 2016
488
+ skip "SQL Server < 2016 is not currently supported"
489
+ end
490
+
491
+ tz = ENV['DB'] == 'mssql' ? time_zones['mssql'] : time_zones['posix']
492
+
493
+ assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['utc']))
494
+ assert_equal '2014/03/03 09:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['sao_paulo']}))
495
+ assert_equal '2014/03/03 02:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['tahiti']}))
496
+
497
+ # Skipping conversion from UTC to the desired timezones fails in SQL
498
+ # Server and Postgres. This is mainly due to the fact that timezone
499
+ # information is not preserved in the column itself.
500
+ #
501
+ # MySQL is happy to consider that times by default are in UTC.
502
+ assert_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
503
+ refute_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['paris'])) if !%w[mysql postgresql].include?(ENV['DB'])
504
+
505
+ # Winter/Summer time
506
+ assert_equal '2014/08/03 14:42:00', t(@lucas, (@updated_at + 5.months).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
507
+ if ENV['DB'] == 'mssql'
508
+ assert_equal '2022/02/01 11:42:00', t(@lucas, Arel.quoted('2022-02-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
509
+ assert_equal '2022/08/01 12:42:00', t(@lucas, Arel.quoted('2022-08-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
510
+ else
511
+ assert_equal '2022/02/01 11:42:00', t(@lucas, Arel.quoted('2022-02-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', tz['paris']))
512
+ assert_equal '2022/08/01 12:42:00', t(@lucas, Arel.quoted('2022-08-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', tz['paris']))
513
+ end
514
+ end
515
+ end
516
+
517
+ def test_format_iso_week
518
+ %i[format format_date].each do |method|
519
+ skip "Unsupported ISO week number for DB=#{ENV['DB']}" if ['sqlite'].include?(ENV['DB'])
520
+ assert_equal '10', t(@lucas, @updated_at.send(method, '%V'))
521
+ {
522
+ '2024-01-01 10:42:00' => '01', # Monday
523
+ '2030-01-01 10:42:00' => '01', # Tuesday
524
+ '2025-01-01 10:42:00' => '01', # Wednesday
525
+ '2026-01-01 10:42:00' => '01', # Thursday
526
+ '2027-01-01 10:42:00' => '53', # Friday
527
+ '2028-01-01 10:42:00' => '52', # Saturday
528
+ '2034-01-01 10:42:00' => '52', # Sunday
529
+ }.each do |date, exp|
530
+ assert_equal exp, t(@lucas, Arel.quoted(date).cast(:datetime).send(method, '%V'))
531
+ end
532
+ end
533
+ end
534
+
535
+ def test_format_iso_year_of_week
536
+ skip "Unsupported ISO year of week for DB=#{ENV['DB']}" if %w[mssql sqlite].include?(ENV['DB'])
537
+ %i[format format_date].each do |method|
538
+ assert_equal '2014', t(@lucas, @updated_at.send(method, '%G'))
539
+
540
+ {
541
+ '2024-01-01 10:42:00' => '2024', # Monday
542
+ '2030-01-01 10:42:00' => '2030', # Tuesday
543
+ '2025-01-01 10:42:00' => '2025', # Wednesday
544
+ '2026-01-01 10:42:00' => '2026', # Thursday
545
+ '2027-01-01 10:42:00' => '2026', # Friday
546
+ '2028-01-01 10:42:00' => '2027', # Saturday
547
+ '2034-01-01 10:42:00' => '2033', # Sunday
548
+ }.each do |date, exp|
549
+ assert_equal exp, t(@lucas, Arel.quoted(date).cast(:datetime).send(method, '%G'))
550
+ end
551
+ end
552
+ end
553
+
554
+ def test_format_date_with_names
555
+ skip "#{ENV['DB']} does not support a variety of word-based formatting for month and day names" if %w[mssql sqlite].include?(ENV['DB'])
556
+ %i[format format_date].each do |method|
557
+ assert_equal 'Mon, 03 Mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
558
+ assert_equal 'Monday, 03 March 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
559
+ end
560
+
561
+ skip "#{ENV['DB']} does not support ALLCAPS month and day names" if ['mysql'].include?(ENV['DB'])
562
+ %i[format format_date].each do |method|
563
+
564
+ assert_equal 'Mon, 03 MAR 14', t(@lucas, @updated_at.send(method, '%a, %d %^b %y'))
565
+ assert_equal 'Monday, 03 MARCH 14', t(@lucas, @updated_at.send(method, '%A, %d %^B %y'))
566
+ end
567
+ end
568
+
569
+ def switch_to_lang(lang)
570
+ languages = {
571
+ 'mssql' => {en: 'English', fr: 'French'},
572
+ 'mysql' => {en: 'en_US', fr: 'fr_FR'},
573
+ 'postgresql' => {en: 'en_US.utf8', fr: 'fr_FR.utf8'}
574
+ }
575
+
576
+ sql = {
577
+ 'mssql' => ->(l) { "SET LANGUAGE #{l};" },
578
+ 'mysql' => ->(l) { "SET lc_time_names = '#{l}';" },
579
+ 'postgresql' => ->(l) { "SET lc_time to '#{l}';" }
580
+ }
581
+
582
+ User.connection.execute(sql[ENV['DB']][languages[ENV['DB']][lang]])
583
+ end
584
+
585
+ def test_format_date_with_names_and_lang_switch
586
+ skip "#{ENV['DB']} does not support word-based formatting for month and day names" if ['sqlite'].include?(ENV['DB'])
587
+
588
+ # the begin-rescue block is here to make sure we set the db back to en_US
589
+ # if we fail, so that other tests don't get contaminated.
590
+ #
591
+ # Tests should assert one single thing in principle, but until we
592
+ # refactor this whole thing, we'll have to do tricks of this sort.
593
+ %i[format format_date].each do |method|
594
+ begin
595
+ switch_to_lang(:en)
596
+ case ENV['DB']
597
+ when 'mysql', 'postgresql'
598
+ assert_equal 'Mon, 03 Mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
599
+ assert_equal 'Monday, 03 March 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
600
+ when 'mssql'
601
+ assert_equal 'Monday, 03 March 2014', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
602
+ end
603
+ switch_to_lang(:fr)
604
+ case ENV['DB']
605
+ when 'mysql'
606
+ assert_equal 'lun, 03 mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
607
+ assert_equal 'lundi, 03 mars 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
608
+ when 'postgresql'
609
+ assert_equal 'Lun., 03 Mars 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
610
+ assert_equal 'Lundi, 03 Mars 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
611
+ when 'mssql'
612
+ assert_equal 'lundi, 03 mars 2014', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
613
+ end
614
+ ensure
615
+ switch_to_lang(:en)
616
+ end
617
+ end
364
618
  end
365
619
 
366
620
  def test_coalesce
367
- assert_equal 'Camille concat', t(@camille, @name.coalesce(nil, "default") + ' concat')
621
+ assert_equal 'Camille concat', t(@camille, @name.coalesce(nil, 'default') + ' concat')
368
622
 
369
- assert_equal 'toto', t(@test, @other.coalesce(""))
623
+ assert_equal 'toto', t(@test, @other.coalesce(''))
370
624
 
371
- assert_equal ' ', t(@myung, @comments.coalesce("Myung").coalesce('ignored'))
372
- assert_equal 'Laure', t(@laure, @comments.coalesce("Laure"))
625
+ assert_equal ' ', t(@myung, @comments.coalesce('Myung').coalesce('ignored'))
626
+ assert_equal 'Laure', t(@laure, @comments.coalesce('Laure'))
373
627
  if @env_db == 'oracle'
374
- assert_nil t(@laure, @comments.coalesce(""))
375
- assert_nil t(@camille, @other.coalesce(""))
628
+ assert_nil t(@laure, @comments.coalesce(''))
629
+ assert_nil t(@camille, @other.coalesce(''))
376
630
  else
377
- assert_equal('', t(@laure, @comments.coalesce("")))
378
- assert_equal '', t(@camille, @other.coalesce(""))
631
+ assert_equal('', t(@laure, @comments.coalesce('')))
632
+ assert_equal '', t(@camille, @other.coalesce(''))
379
633
  end
380
634
  assert_equal 100, t(@test, @age.coalesce(100))
381
- assert_equal "Camille", t(@camille, @name.coalesce(nil, "default"))
635
+ assert_equal 'Camille', t(@camille, @name.coalesce(nil, 'default'))
382
636
  assert_equal 20, t(@test, @age.coalesce(nil, 20))
383
637
 
384
- assert_equal 20, t(@test, @age.coalesce(10)+10)
385
- assert_equal 'Laure10', t(@laure, @comments.coalesce("Laure") + 10)
638
+ assert_equal 20, t(@test, @age.coalesce(10) + 10)
639
+ assert_equal 'Laure10', t(@laure, @comments.coalesce('Laure') + 10)
640
+ end
641
+
642
+ def test_coalesce_blank
643
+ assert_equal 'Myung', t(@myung, @comments.coalesce_blank('Myung').coalesce_blank('ignored'))
644
+ assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ').coalesce_blank('Myung'))
645
+ assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ', 'Myung'))
646
+ assert_equal '2016-05-23', t(@myung, @created_at.coalesce_blank(Date.new(2022, 1, 1)).format('%Y-%m-%d'))
647
+ assert_equal '2016-05-23', t(@myung, @created_at.coalesce_blank(Date.new(2022, 1, 1)).format_date('%Y-%m-%d'))
648
+ assert_equal 'Laure', t(@laure, @comments.coalesce_blank('Laure'))
649
+ assert_equal 100, t(@test, @age.coalesce_blank(100))
650
+ assert_equal 20, t(@test, @age.coalesce_blank(20))
651
+ assert_equal 20, t(@test, @age.coalesce_blank(10) + 10)
652
+ assert_equal 'Laure10', t(@laure, @comments.coalesce_blank('Laure') + 10)
653
+
654
+ skip 'mssql does not support null in case results' if @env_db == 'mssql'
655
+
656
+ assert_equal 'Camille concat', t(@camille, @name.coalesce_blank(Arel.null, 'default') + ' concat')
657
+ assert_equal 'Myung', t(@myung, @comments.coalesce_blank(Arel.null, 'Myung'))
658
+ assert_equal 'Camille', t(@camille, @name.coalesce_blank(Arel.null, 'default'))
386
659
  end
387
660
 
388
661
  # Comparators
@@ -397,22 +670,31 @@ module ArelExtensions
397
670
  def test_date_comparator
398
671
  d = Date.new(2016, 5, 23)
399
672
  assert_equal 0, User.where(@created_at < d).count
400
- assert_equal 9, User.where(@created_at >= d).count
673
+ assert_equal 10, User.where(@created_at >= d).count
401
674
  end
402
675
 
403
676
  def test_date_duration
677
+ # When user `nilly` is created, with an explicit `created_at: nil`,
678
+ # activerecord will give it the current date.
679
+ #
680
+ # So depending on the month when we run this test, we will get different
681
+ # results for `User.where(@created_at.month.eq('05'))`.
682
+ count_for_may = Date.today.month == 5 ? 10 : 9
683
+ count_for_day = Date.today.day == 5 ? 1 : 0
684
+
404
685
  # Year
405
686
  assert_equal 2016, t(@lucas, @created_at.year).to_i
406
- assert_equal 0, User.where(@created_at.year.eq("2012")).count
687
+ assert_equal 0, User.where(@created_at.year.eq('2012')).count
407
688
  # Month
408
689
  assert_equal 5, t(@camille, @created_at.month).to_i
409
- assert_equal 9, User.where(@created_at.month.eq("05")).count
690
+ assert_equal count_for_may, User.where(@created_at.month.eq('05')).count
410
691
  # Week
411
692
  assert_equal(@env_db == 'mssql' ? 22 : 21, t(@arthur, @created_at.week).to_i)
412
- assert_equal 9, User.where(@created_at.month.eq("05")).count
693
+ assert_equal count_for_may, User.where(@created_at.month.eq('05')).count
413
694
  # Day
414
695
  assert_equal 23, t(@laure, @created_at.day).to_i
415
- assert_equal 0, User.where(@created_at.day.eq("05")).count
696
+ # Make sure we get the correct count on the date we run the test.
697
+ assert_equal count_for_day, User.where(@created_at.day.eq('05')).count
416
698
 
417
699
  # skip "manage DATE" if @env_db == 'oracle'
418
700
  # Hour
@@ -429,8 +711,8 @@ module ArelExtensions
429
711
  def test_datetime_diff
430
712
  assert_equal 0, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 12, 42)).to_i
431
713
  if @env_db == 'oracle' && Arel::VERSION.to_i > 6 # in rails 5, result is multiplied by 24*60*60 = 86400...
432
- assert_equal 42 * 86400, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 12, 41, 18)).to_i
433
- assert_equal(-3600 * 86400, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 13, 42)).to_i)
714
+ assert_equal 42 * 86_400, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 12, 41, 18)).to_i
715
+ assert_equal(-3600 * 86_400, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 13, 42)).to_i)
434
716
  else
435
717
  assert_equal 42, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 12, 41, 18)).to_i
436
718
  assert_equal(-3600, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 13, 42)).to_i)
@@ -442,7 +724,7 @@ module ArelExtensions
442
724
  end
443
725
 
444
726
 
445
- skip "not yet implemented" if $sqlite
727
+ skip 'not yet implemented' if $sqlite
446
728
 
447
729
  date1 = Date.new(2016, 5, 23)
448
730
  durPos = 10.years
@@ -455,27 +737,29 @@ module ArelExtensions
455
737
  datetime1 = Time.utc(2014, 3, 3, 12, 42, 0)
456
738
  # Pull Request #5 tests
457
739
  # puts (@created_at + durPos).cast(:date).to_sql
458
- assert_includes [date2,"2026-05-23"], t(@test,(@created_at + durPos).cast(:date))
459
- assert_includes [date3,"2006-05-23"], t(@test,(@created_at + durNeg).cast(:date))
740
+ assert_includes [date2, '2026-05-23'], t(@test, (@created_at + durPos).cast(:date))
741
+ assert_includes [date3, '2006-05-23'], t(@test, (@created_at + durNeg).cast(:date))
460
742
 
461
743
  # puts (@created_at + @created_at.day).cast(:date).to_sql
462
- assert_includes [date4,"2016-06-15"], t(@test,(@created_at + @created_at.day).cast(:date))
744
+ assert_includes [date4, '2016-06-15'], t(@test, (@created_at + @created_at.day).cast(:date))
463
745
  # puts (@created_at - @created_at.day).cast(:date).to_sql
464
- assert_includes [date5,"2016-04-30"], t(@test,(@created_at - @created_at.day).cast(:date))
746
+ assert_includes [date5, '2016-04-30'], t(@test, (@created_at - @created_at.day).cast(:date))
465
747
 
466
- assert_includes [datetime1 + 42.seconds,"2014-03-03 12:42:42 UTC"], t(@lucas,(@updated_at + @updated_at.minute))
467
- assert_includes [datetime1 - 42.seconds,"2014-03-03 12:41:18 UTC"], t(@lucas,(@updated_at - @updated_at.minute))
748
+ assert_includes [datetime1 + 42.seconds, '2014-03-03 12:42:42 UTC'], t(@lucas, (@updated_at + @updated_at.minute))
749
+ assert_includes [datetime1 - 42.seconds, '2014-03-03 12:41:18 UTC'], t(@lucas, (@updated_at - @updated_at.minute))
468
750
 
469
751
  # (@updated_at + Arel.duration('s',(@updated_at.hour*60 + @updated_at.minute))).to_sql
470
- assert_includes [datetime1 + (12*60+42).seconds,"2014-03-03 12:54:42 UTC"],
471
- t(@lucas,(@updated_at + Arel.duration('s',(@updated_at.hour*60 + @updated_at.minute))))
752
+ assert_includes [datetime1 + (12 * 60 + 42).seconds, '2014-03-03 12:54:42 UTC'],
753
+ t(@lucas, (@updated_at + Arel.duration('s', (@updated_at.hour * 60 + @updated_at.minute))))
472
754
 
473
- assert_includes [datetime1 + (12*60+42).minutes,"2014-03-04 01:24:00 UTC"],
474
- t(@lucas,(@updated_at + Arel.duration('mn',(@updated_at.hour*60 + @updated_at.minute))))
755
+ assert_includes [datetime1 + (12 * 60 + 42).minutes, '2014-03-04 01:24:00 UTC'],
756
+ t(@lucas, (@updated_at + Arel.duration('mn', (@updated_at.hour * 60 + @updated_at.minute))))
475
757
 
476
- assert_includes ["2024-03-03"], t(@lucas,(@updated_at + durPos).format('%Y-%m-%d'))
758
+ assert_includes ['2024-03-03'], t(@lucas, (@updated_at + durPos).format('%Y-%m-%d'))
759
+ assert_includes ['2024-03-03'], t(@lucas, (@updated_at + durPos).format_date('%Y-%m-%d'))
477
760
  # puts (@updated_at - durPos).to_sql
478
- assert_includes ["2004-03-03"], t(@lucas,(@updated_at - durPos).format('%Y-%m-%d'))
761
+ assert_includes ['2004-03-03'], t(@lucas, (@updated_at - durPos).format('%Y-%m-%d'))
762
+ assert_includes ['2004-03-03'], t(@lucas, (@updated_at - durPos).format_date('%Y-%m-%d'))
479
763
 
480
764
 
481
765
  # we test with the ruby object or the string because some adapters don't return an object Date
@@ -484,28 +768,53 @@ module ArelExtensions
484
768
 
485
769
  # TODO; cast types
486
770
  def test_cast_types
487
- assert_equal "5", t(@lucas, @age.cast(:string))
488
- skip "jdbc adapters does not work properly here (v52 works fine)" if RUBY_PLATFORM =~ /java/i
771
+ assert_equal '5', t(@lucas, @age.cast(:string))
772
+ skip 'jdbc adapters does not work properly here (v52 works fine)' if RUBY_PLATFORM.match?(/java/i)
489
773
  if @env_db == 'mysql' || @env_db == 'postgresql' || @env_db == 'oracle' || @env_db == 'mssql'
490
- assert_equal 1, t(@laure,Arel.when(@duration.cast(:time).cast(:string).eq("12:42:21")).then(1).else(0)) unless @env_db == 'oracle' || @env_db == 'mssql'
491
- assert_equal 1, t(@laure,Arel.when(@duration.cast(:time).eq("12:42:21")).then(1).else(0)) unless @env_db == 'oracle'
492
- assert_equal "20.16", t(@laure,@score.cast(:string)).gsub(/[0]*\z/,'')
493
- assert_equal "20.161", t(@laure,@score.cast(:string)+1).gsub(/[0]*1\z/,'1')
494
- assert_equal 21.16, t(@laure,@score.cast(:string).cast(:decimal)+1)
495
- assert_equal 21, t(@laure,@score.cast(:string).cast(:int)+1)
496
-
497
- assert_equal String, t(@lucas,@updated_at.cast(:string)).class
498
-
499
- assert_equal Date, t(@lucas,@updated_at.cast(:date)).class unless @env_db == 'oracle' # DateTime
500
- assert_equal Time, t(@lucas,@updated_at.cast(:string).cast(:datetime)).class
501
- assert_equal Time, t(@lucas,@updated_at.cast(:time)).class
502
-
503
- assert_equal "2014-03-03 12:42:00", t(@lucas,@updated_at.cast(:string)) unless @env_db == 'mssql' # locale dependent
504
- assert_equal Date.parse("2014-03-03"), t(@lucas,Arel::Nodes.build_quoted('2014-03-03').cast(:date))
505
- assert_equal Date.parse("5014-03-03"), t(@lucas,(@age.cast(:string) + '014-03-03').cast(:date))
506
- assert_equal Time.parse("2014-03-03 12:42:00 UTC"), t(@lucas,@updated_at.cast(:string).cast(:datetime))
507
- assert_equal Date.parse("2014-03-03"), t(@lucas,@updated_at.cast(:date))
508
- assert_equal "12:42:00", t(@lucas,@updated_at.cast(:time).cast(:string)).split('.').first unless @env_db == 'oracle' # DateTime
774
+ assert_equal 1, t(@laure, Arel.when(@duration.cast(:time).cast(:string).eq('12:42:21')).then(1).else(0)) unless @env_db == 'oracle' || @env_db == 'mssql'
775
+ assert_equal 1, t(@laure, Arel.when(@duration.cast(:time).eq('12:42:21')).then(1).else(0)) unless @env_db == 'oracle'
776
+ assert_equal '20.16', t(@laure, @score.cast(:string)).gsub(/0*\z/, '')
777
+ assert_equal '20.161', t(@laure, @score.cast(:string) + 1).gsub(/0*1\z/, '1')
778
+ assert_equal 21.16, t(@laure, @score.cast(:string).cast(:decimal) + 1)
779
+ assert_equal 21, t(@laure, @score.cast(:string).cast(:int) + 1)
780
+
781
+ assert_equal String, t(@lucas, @updated_at.cast(:string)).class
782
+
783
+ assert_equal Date, t(@lucas, @updated_at.cast(:date)).class unless @env_db == 'oracle' # DateTime
784
+ assert_equal Time, t(@lucas, @updated_at.cast(:string).cast(:datetime)).class
785
+ assert_equal Time, t(@lucas, @updated_at.cast(:time)).class
786
+
787
+ # mysql adapter in rails7 adds some infos we just squeeze here
788
+ assert_equal '2014-03-03 12:42:00', t(@lucas, @updated_at.cast(:string)).split('.').first unless @env_db == 'mssql' # locale dependent
789
+ assert_equal Date.parse('2014-03-03'), t(@lucas, Arel.quoted('2014-03-03').cast(:date))
790
+ assert_equal Date.parse('5014-03-03'), t(@lucas, (@age.cast(:string) + '014-03-03').cast(:date))
791
+ assert_equal Time.parse('2014-03-03 12:42:00 UTC'), t(@lucas, @updated_at.cast(:string).cast(:datetime))
792
+ assert_equal Date.parse('2014-03-03'), t(@lucas, @updated_at.cast(:date))
793
+ assert_equal '12:42:00', t(@lucas, @updated_at.cast(:time).cast(:string)).split('.').first unless @env_db == 'oracle' # DateTime
794
+ end
795
+ end
796
+
797
+ def test_if_present
798
+ assert_nil t(@myung, @comments.if_present)
799
+ assert_equal 0, t(@myung, @comments.if_present.count)
800
+ assert_equal 20.16, t(@myung, @score.if_present)
801
+ assert_equal '2016-05-23', t(@myung, @created_at.if_present.format('%Y-%m-%d'))
802
+ assert_equal '2016-05-23', t(@myung, @created_at.if_present.format_date('%Y-%m-%d'))
803
+ assert_nil t(@laure, @comments.if_present)
804
+
805
+ assert_nil t(@nilly, @duration.if_present.format('%Y-%m-%d'))
806
+ assert_nil t(@nilly, @duration.if_present.format_date('%Y-%m-%d'))
807
+
808
+ # NOTE: here we're testing the capacity to format a nil value,
809
+ # however, @comments is a text field, and not a date/datetime field,
810
+ # so Postgres will rightfully complain when we format the text:
811
+ # we need to cast it first.
812
+ if @env_db == 'postgresql'
813
+ assert_nil t(@laure, @comments.cast(:date).if_present.format('%Y-%m-%d'))
814
+ assert_nil t(@laure, @comments.cast(:date).if_present.format_date('%Y-%m-%d'))
815
+ else
816
+ assert_nil t(@laure, @comments.if_present.format('%Y-%m-%d'))
817
+ assert_nil t(@laure, @comments.if_present.format_date('%Y-%m-%d'))
509
818
  end
510
819
  end
511
820
 
@@ -515,42 +824,42 @@ module ArelExtensions
515
824
  # puts @age.is_null.inspect
516
825
  # puts @age.is_null.to_sql
517
826
  # puts @age=='34'
518
- assert_equal "Test", User.select(@name).where(@age.is_null.to_sql).first.name
827
+ assert_equal 'Test', User.select(@name).where(@age.is_null).first.name
519
828
  end
520
829
 
521
830
  def test_math_plus
522
831
  d = Date.new(1997, 6, 15)
523
832
  # Concat String
524
- assert_equal "SophiePhan", t(@sophie, @name + "Phan")
525
- assert_equal "Sophie2", t(@sophie, @name + 2)
526
- assert_equal "Sophie1997-06-15", t(@sophie, @name + d)
527
- assert_equal "Sophie15", t(@sophie, @name + @age)
528
- assert_equal "SophieSophie", t(@sophie, @name + @name)
529
- assert_equal "SophieSophieSophie", t(@sophie, @name + @name + @name)
530
- assert_equal "SophieSophieSophie", t(@sophie, @name.concat(@name.concat(@name)))
531
- assert_equal "SophieSophieSophie", t(@sophie, @name.concat(@name).concat(@name))
833
+ assert_equal 'SophiePhan', t(@sophie, @name + 'Phan')
834
+ assert_equal 'Sophie2', t(@sophie, @name + 2)
835
+ assert_equal 'Sophie1997-06-15', t(@sophie, @name + d)
836
+ assert_equal 'Sophie15', t(@sophie, @name + @age)
837
+ assert_equal 'SophieSophie', t(@sophie, @name + @name)
838
+ assert_equal 'SophieSophieSophie', t(@sophie, @name + @name + @name)
839
+ assert_equal 'SophieSophieSophie', t(@sophie, @name.concat(@name.concat(@name)))
840
+ assert_equal 'SophieSophieSophie', t(@sophie, @name.concat(@name).concat(@name))
532
841
  # FIXME: should work as expected in Oracle
533
- assert_equal "Sophie2016-05-23", t(@sophie, @name + @created_at) unless @env_db == 'oracle'
842
+ assert_equal 'Sophie2016-05-23', t(@sophie, @name + @created_at) unless @env_db == 'oracle'
534
843
  # concat Integer
535
844
  assert_equal 1, User.where((@age + 10).eq(33)).count
536
- assert_equal 1, User.where((@age + "1").eq(6)).count
845
+ assert_equal 1, User.where((@age + '1').eq(6)).count
537
846
  assert_equal 1, User.where((@age + @age).eq(10)).count
538
847
  # concat Date
539
848
  # puts((User.arel_table[:created_at] + 1).as("res").to_sql.inspect)
540
- assert_equal "2016-05-24", t(@myung, @created_at + 1).to_date.to_s
541
- assert_equal "2016-05-25", t(@myung, @created_at + 2.day).to_date.to_s
849
+ assert_equal '2016-05-24', t(@myung, @created_at + 1).to_date.to_s
850
+ assert_equal '2016-05-25', t(@myung, @created_at + 2.day).to_date.to_s
542
851
  end
543
852
 
544
853
  def test_math_minus
545
854
  d = Date.new(2016, 5, 20)
546
855
  # Datediff
547
- assert_equal 9, User.where((@created_at - @created_at).eq(0)).count
548
- assert_equal 3, @laure.select((@created_at - d).as("res")).first.res.abs.to_i
856
+ assert_equal 10, User.where((@created_at - @created_at).eq(0)).count
857
+ assert_equal 3, @laure.select((@created_at - d).as('res')).first.res.abs.to_i
549
858
  # Substraction
550
859
  assert_equal 0, User.where((@age - 10).eq(50)).count
551
- assert_equal 0, User.where((@age - "10").eq(50)).count
860
+ assert_equal 0, User.where((@age - '10').eq(50)).count
552
861
  # assert_equal 0, User.where((@age - 9.5).eq(50.5)).count # should work: TODO
553
- assert_equal 0, User.where((@age - "9.5").eq(50.5)).count
862
+ assert_equal 0, User.where((@age - '9.5').eq(50.5)).count
554
863
  end
555
864
 
556
865
  def test_wday
@@ -573,8 +882,8 @@ module ArelExtensions
573
882
  assert_equal 3, User.select('*').from((@ut.project(@age).where(@age.eq(20)) + @ut.project(@age).where(@age.eq(23)) + @ut.project(@age).where(@age.eq(21))).as('my_union')).length
574
883
  assert_equal 2, User.select('*').from((@ut.project(@age).where(@age.eq(20)) + @ut.project(@age).where(@age.eq(20)) + @ut.project(@age).where(@age.eq(21))).as('my_union')).length
575
884
 
576
- assert_equal 3, User.find_by_sql((@ut.project(@age).where(@age.gt(22)).union_all(@ut.project(@age).where(@age.lt(0)))).to_sql).length
577
- assert_equal 3, User.find_by_sql((@ut.project(@age).where(@age.eq(20)).union_all(@ut.project(@age).where(@age.eq(20))).union_all(@ut.project(@age).where(@age.eq(21)))).to_sql).length
885
+ assert_equal 3, User.find_by_sql(@ut.project(@age).where(@age.gt(22)).union_all(@ut.project(@age).where(@age.lt(0))).to_sql).length
886
+ assert_equal 3, User.find_by_sql(@ut.project(@age).where(@age.eq(20)).union_all(@ut.project(@age).where(@age.eq(20))).union_all(@ut.project(@age).where(@age.eq(21))).to_sql).length
578
887
  assert_equal 3, User.select('*').from((@ut.project(@age).where(@age.gt(22)).union_all(@ut.project(@age).where(@age.lt(0)))).as('my_union')).length
579
888
  assert_equal 3, User.select('*').from((@ut.project(@age).where(@age.eq(20)).union_all(@ut.project(@age).where(@age.eq(23))).union_all(@ut.project(@age).where(@age.eq(21)))).as('my_union')).length
580
889
  assert_equal 3, User.select('*').from((@ut.project(@age).where(@age.eq(20)).union_all(@ut.project(@age).where(@age.eq(20))).union_all(@ut.project(@age).where(@age.eq(21)))).as('my_union')).length
@@ -586,116 +895,117 @@ module ArelExtensions
586
895
  def test_case
587
896
  assert_equal 4, User.find_by_sql(@ut.project(@score.when(20.16).then(1).else(0).as('score_bin')).to_sql).sum(&:score_bin)
588
897
  assert_equal 4, User.where(@score.when(20.16).then(1).else(0).eq(1)).count
589
- assert_equal 2, t(@arthur, @score.when(65.62,1).else(0)+1)
590
- assert_equal 0, t(@arthur, @score.when(65.62,1).else(0)-1)
591
- assert_equal "11", t(@arthur, @score.when(65.62).then("1").else("0")+"1")
592
- assert_equal 66.62, t(@arthur, @score.when(65.62).then(@score).else(@score)+1)
593
- assert_equal "65.621", t(@arthur, @score.when(65.62).then(@score.cast(:string)).else(@score.cast(:string))+1).tr('0','') # tr is here because of precision on cast for some DBMS
898
+ assert_equal 2, t(@arthur, @score.when(65.62, 1).else(0) + 1)
899
+ assert_equal 0, t(@arthur, @score.when(65.62, 1).else(0) - 1)
900
+ assert_equal '11', t(@arthur, @score.when(65.62).then('1').else('0') + '1')
901
+ assert_equal 66.62, t(@arthur, @score.when(65.62).then(@score).else(@score) + 1)
902
+ assert_equal '65.621', t(@arthur, @score.when(65.62).then(@score.cast(:string)).else(@score.cast(:string)) + 1).tr('0', '') # tr is here because of precision on cast for some DBMS
594
903
  end
595
904
 
596
905
  def test_format_numbers
597
906
  # score of Arthur = 65.62
598
- skip " Works with SQLite if the version used knows printf" if $sqlite
599
-
600
- assert_equal "Wrong Format", t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
601
- assert_equal "AZERTY65,62", t(@arthur, @score.format_number("AZERTY%.2f","fr_FR"))
602
- assert_equal "65,62AZERTY", t(@arthur, @score.format_number("%.2fAZERTY","fr_FR"))
603
- assert_equal "$ 65.62 €", t(@arthur, @score.format_number("$ %.2f €","en_US"))
604
- assert_equal "$ 66 €", t(@arthur, @score.format_number("$ %.0f €","en_US"))
605
- assert_equal "$ 0065,62 €", t(@arthur, @score.format_number("$ %07.2f €","fr_FR"))
606
- assert_equal "$ 65,62 €", t(@arthur, @score.format_number("$ %-07.2f €","fr_FR"))
607
- assert_equal "$ 65,62 €", t(@arthur, @score.format_number("$ %-7.2f €","fr_FR"))
608
- assert_equal "$ 65,62 €", t(@arthur, @score.format_number("$ % 7.2f €","fr_FR"))
609
- assert_equal "$ 65,6 €", t(@arthur, @score.format_number("$ % 7.1f €","fr_FR"))
610
- assert_equal "$ +65,62 €", t(@arthur, @score.format_number("$ % +7.2f €","fr_FR"))
611
- assert_equal "$ +065,62 €", t(@arthur, @score.format_number("$ %0+7.2f €","fr_FR"))
612
- assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
613
- assert_includes ["$ 6,56E1 €","$ 6,56E+01 €"], t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
614
- assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
615
- assert_equal "123 456 765,6", t(@arthur, (@score+123456700).format_number("%.1f","sv_SE")).gsub("\u00A0"," ") # some DBMS put no-break space here (it makes sense thus)
616
- assert_equal "123456765,6", t(@arthur, (@score+123456700).format_number("%.1f","fr_FR")).gsub("\u00A0","") # because SqlServer does it like no one else
617
- assert_equal "123,456,765.6", t(@arthur, (@score+123456700).format_number("%.1f","en_US"))
618
- assert_equal " 123,456,765.6", t(@arthur, (@score+123456700).format_number("%16.1f","en_US"))
619
- assert_equal "$ 0,00 €", t(@arthur, @score.when(65.62).then(Arel.sql("null")).else(1).format_number("$ %.2f €","fr_FR"))
620
- assert_equal "$ 0,00 €", t(@arthur, (@score-65.62).format_number("$ %.2f €","fr_FR"))
907
+ skip ' Works with SQLite if the version used knows printf' if $sqlite
908
+
909
+ assert_equal 'Wrong Format', t(@arthur, @score.format_number('$ %...234.6F €', 'fr_FR'))
910
+ assert_equal 'AZERTY65,62', t(@arthur, @score.format_number('AZERTY%.2f', 'fr_FR'))
911
+ assert_equal '65,62AZERTY', t(@arthur, @score.format_number('%.2fAZERTY', 'fr_FR'))
912
+ assert_equal '$ 65.62 €', t(@arthur, @score.format_number('$ %.2f €', 'en_US'))
913
+ assert_equal '$ 66 €', t(@arthur, @score.format_number('$ %.0f €', 'en_US'))
914
+ assert_equal '$ 0065,62 €', t(@arthur, @score.format_number('$ %07.2f €', 'fr_FR'))
915
+ assert_equal '$ 65,62 €', t(@arthur, @score.format_number('$ %-07.2f €', 'fr_FR'))
916
+ assert_equal '$ 65,62 €', t(@arthur, @score.format_number('$ %-7.2f €', 'fr_FR'))
917
+ assert_equal '$ 65,62 €', t(@arthur, @score.format_number('$ % 7.2f €', 'fr_FR'))
918
+ assert_equal '$ 65,6 €', t(@arthur, @score.format_number('$ % 7.1f €', 'fr_FR'))
919
+ assert_equal '$ +65,62 €', t(@arthur, @score.format_number('$ % +7.2f €', 'fr_FR'))
920
+ assert_equal '$ +065,62 €', t(@arthur, @score.format_number('$ %0+7.2f €', 'fr_FR'))
921
+ assert_includes ['$ 6,56e1 €', '$ 6,56e+01 €'], t(@arthur, @score.format_number('$ %.2e €', 'fr_FR'))
922
+ assert_includes ['$ 6,56E1 €', '$ 6,56E+01 €'], t(@arthur, @score.format_number('$ %.2E €', 'fr_FR'))
923
+ assert_includes ['$ 6,562E1 €', '$ 6,562E+01 €'], t(@arthur, @score.format_number('$ %.3E €', 'fr_FR'))
924
+ assert_equal '123 456 765,6', t(@arthur, (@score + 123_456_700).format_number('%.1f', 'sv_SE')).tr("\u00A0", ' ') # some DBMS put no-break space here (it makes sense thus)
925
+ assert_equal '123456765,6', t(@arthur, (@score + 123_456_700).format_number('%.1f', 'fr_FR')).delete("\u00A0") # because SqlServer does it like no one else
926
+ assert_equal '123,456,765.6', t(@arthur, (@score + 123_456_700).format_number('%.1f', 'en_US'))
927
+ assert_equal ' 123,456,765.6', t(@arthur, (@score + 123_456_700).format_number('%16.1f', 'en_US'))
928
+ assert_equal '$ 0,00 €', t(@arthur, @score.when(65.62).then(Arel.sql('null')).else(1).format_number('$ %.2f €', 'fr_FR'))
929
+ assert_equal '$ 0,00 €', t(@arthur, (@score - 65.62).format_number('$ %.2f €', 'fr_FR'))
621
930
  end
622
931
 
623
932
  def test_accent_insensitive
624
- skip "SQLite is natively Case Insensitive and Accent Sensitive" if $sqlite
625
- skip "Not finished" if @env_db == 'mysql'
933
+ skip 'SQLite is natively Case Insensitive and Accent Sensitive' if $sqlite
934
+ skip 'Not finished' if @env_db == 'mysql'
626
935
  # actual comments value: "arrêté"
627
936
  # AI & CI
628
937
  if !['postgresql'].include?(@env_db) # Extension unaccent required on PG
629
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("arrêté")).then("1").else("0"))
630
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("arrete")).then("1").else("0"))
631
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("àrrétè")).then("1").else("0"))
632
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("arretez")).then("1").else("0"))
633
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("Arrete")).then("1").else("0"))
634
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_imatches("Arrêté")).then("1").else("0"))
938
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_imatches('arrêté')).then('1').else('0'))
939
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_imatches('arrete')).then('1').else('0'))
940
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_imatches('àrrétè')).then('1').else('0'))
941
+ assert_equal '0', t(@arthur, Arel.when(@comments.ai_imatches('arretez')).then('1').else('0'))
942
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_imatches('Arrete')).then('1').else('0'))
943
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_imatches('Arrêté')).then('1').else('0'))
635
944
  # AI & CS
636
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("arrêté")).then("1").else("0"))
637
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("arrete")).then("1").else("0"))
638
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("àrrétè")).then("1").else("0"))
639
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("arretez")).then("1").else("0"))
640
- if !['oracle','postgresql','mysql'].include?(@env_db) # AI => CI
641
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("Arrete")).then("1").else("0"))
642
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.ai_matches("Arrêté")).then("1").else("0"))
945
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_matches('arrêté')).then('1').else('0'))
946
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_matches('arrete')).then('1').else('0'))
947
+ assert_equal '1', t(@arthur, Arel.when(@comments.ai_matches('àrrétè')).then('1').else('0'))
948
+ assert_equal '0', t(@arthur, Arel.when(@comments.ai_matches('arretez')).then('1').else('0'))
949
+ if !%w[oracle postgresql mysql].include?(@env_db) # AI => CI
950
+ assert_equal '0', t(@arthur, Arel.when(@comments.ai_matches('Arrete')).then('1').else('0'))
951
+ assert_equal '0', t(@arthur, Arel.when(@comments.ai_matches('Arrêté')).then('1').else('0'))
643
952
  end
644
953
  end
645
954
  # AS & CI
646
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("arrêté")).then("1").else("0"))
955
+ assert_equal '1', t(@arthur, Arel.when(@comments.imatches('arrêté')).then('1').else('0'))
647
956
  if !['mysql'].include?(@env_db) # CI => AI in utf8 (AI not possible in latin1)
648
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("arrete")).then("1").else("0"))
649
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("àrrétè")).then("1").else("0"))
957
+ assert_equal '0', t(@arthur, Arel.when(@comments.imatches('arrete')).then('1').else('0'))
958
+ assert_equal '0', t(@arthur, Arel.when(@comments.imatches('àrrétè')).then('1').else('0'))
650
959
  end
651
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("arretez")).then("1").else("0"))
960
+ assert_equal '0', t(@arthur, Arel.when(@comments.imatches('arretez')).then('1').else('0'))
652
961
  if !['mysql'].include?(@env_db) # CI => AI in utf8 (AI not possible in latin1)
653
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("Arrete")).then("1").else("0"))
962
+ assert_equal '0', t(@arthur, Arel.when(@comments.imatches('Arrete')).then('1').else('0'))
654
963
  end
655
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.imatches("Arrêté")).then("1").else("0"))
964
+ assert_equal '1', t(@arthur, Arel.when(@comments.imatches('Arrêté')).then('1').else('0'))
656
965
  # AS & CS
657
- assert_equal "1", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("arrêté")).then("1").else("0"))
658
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("arrete")).then("1").else("0"))
659
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("àrrétè")).then("1").else("0"))
660
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("arretez")).then("1").else("0"))
661
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrete")).then("1").else("0"))
662
- assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrêté")).then("1").else("0"))
966
+ assert_equal '1', t(@arthur, Arel.when(@comments.smatches('arrêté')).then('1').else('0'))
967
+ assert_equal '0', t(@arthur, Arel.when(@comments.smatches('arrete')).then('1').else('0'))
968
+ assert_equal '0', t(@arthur, Arel.when(@comments.smatches('àrrétè')).then('1').else('0'))
969
+ assert_equal '0', t(@arthur, Arel.when(@comments.smatches('arretez')).then('1').else('0'))
970
+ assert_equal '0', t(@arthur, Arel.when(@comments.smatches('Arrete')).then('1').else('0'))
971
+ assert_equal '0', t(@arthur, Arel.when(@comments.smatches('Arrêté')).then('1').else('0'))
663
972
  end
664
973
 
665
974
  def test_subquery_with_order
666
- assert_equal 9, User.where(:name => User.select(:name).order(:name)).count
667
- assert_equal 9, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
668
- if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
669
- assert_equal 2, User.where(:name => User.select(:name).order(:name).limit(2)).count
670
- # assert_equal 6, User.where(:name => User.select(:name).order(:name).offset(2)).count
975
+ skip if ['mssql'].include?(@env_db) && Arel::VERSION.to_i < 10
976
+ assert_equal 10, User.where(name: User.select(:name).order(:name)).count
977
+ assert_equal 10, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
978
+ if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
979
+ assert_equal 2, User.where(name: User.select(:name).order(:name).limit(2)).count
980
+ # assert_equal 6, User.where(name: User.select(:name).order(:name).offset(2)).count
671
981
  end
672
982
  end
673
983
 
674
984
  def test_in_with_nil
675
- assert_equal true, @myung.where(@age.in(1)).blank?
676
- assert_equal false, @myung.where(@age.in(23)).blank?
677
- assert_equal true, @myung.where(@age.in([1])).blank?
678
- assert_equal true, @myung.where(@age.in([1,2])).blank?
679
- assert_equal false, @myung.where(@age.in([1,23])).blank?
680
- assert_equal true, @myung.where(@age.in(nil)).blank?
681
- assert_equal true, @myung.where(@age.in([nil])).blank?
682
- assert_equal true, @myung.where(@age.in([nil,1])).blank?
683
- assert_equal false, @myung.where(@age.in([nil,23])).blank?
684
- assert_equal true, @myung.where(@age.in([nil,1,2])).blank?
685
- assert_equal false, @myung.where(@age.in([nil,1,23])).blank?
686
- assert_equal true, @test.where(@age.in(1)).blank?
687
- assert_equal true, @test.where(@age.in([1])).blank?
688
- assert_equal true, @test.where(@age.in([1,2])).blank?
689
- assert_equal false, @test.where(@age.in(nil)).blank?
690
- assert_equal false, @test.where(@age.in([nil])).blank?
691
- assert_equal false, @test.where(@age.in([nil,1])).blank?
692
- assert_equal false, @test.where(@age.in([nil,1,2])).blank?
985
+ assert_predicate @myung.where(@age.in(1)), :blank?
986
+ assert_predicate @myung.where(@age.in(23)), :present?
987
+ assert_predicate @myung.where(@age.in([1])), :blank?
988
+ assert_predicate @myung.where(@age.in([1, 2])), :blank?
989
+ assert_predicate @myung.where(@age.in([1, 23])), :present?
990
+ assert_predicate @myung.where(@age.in(nil)), :blank?
991
+ assert_predicate @myung.where(@age.in([nil])), :blank?
992
+ assert_predicate @myung.where(@age.in([nil, 1])), :blank?
993
+ assert_predicate @myung.where(@age.in([nil, 23])), :present?
994
+ assert_predicate @myung.where(@age.in([nil, 1, 2])), :blank?
995
+ assert_predicate @myung.where(@age.in([nil, 1, 23])), :present?
996
+ assert_predicate @test.where(@age.in(1)), :blank?
997
+ assert_predicate @test.where(@age.in([1])), :blank?
998
+ assert_predicate @test.where(@age.in([1, 2])), :blank?
999
+ assert_predicate @test.where(@age.in(nil)), :present?
1000
+ assert_predicate @test.where(@age.in([nil])), :present?
1001
+ assert_predicate @test.where(@age.in([nil, 1])), :present?
1002
+ assert_predicate @test.where(@age.in([nil, 1, 2])), :present?
693
1003
  end
694
1004
 
695
1005
  def test_scope_with_in_plus_new
696
1006
  begin
697
- @test.where(@age.in([1,2])).new
698
- @test.where(@age.not_in([1,2])).new
1007
+ @test.where(@age.in([1, 2])).new
1008
+ @test.where(@age.not_in([1, 2])).new
699
1009
  assert true
700
1010
  rescue
701
1011
  assert false
@@ -703,44 +1013,44 @@ module ArelExtensions
703
1013
  end
704
1014
 
705
1015
  def test_is_not_null
706
- assert_equal false, @myung.where(@age.is_not_null).blank?
707
- assert_equal true, @test.where(@age.is_not_null).blank?
1016
+ assert_predicate @myung.where(@age.is_not_null), :present?
1017
+ assert_predicate @test.where(@age.is_not_null), :blank?
708
1018
  end
709
1019
 
710
1020
  def test_not_in_with_nil
711
- assert_equal false, @myung.where(@age.not_in(1)).blank?
712
- assert_equal true, @myung.where(@age.not_in(23)).blank?
713
- assert_equal false, @myung.where(@age.not_in([1])).blank?
714
- assert_equal false, @myung.where(@age.not_in([1,2])).blank?
715
- assert_equal true, @myung.where(@age.not_in([1,23])).blank?
716
- assert_equal false, @myung.where(@age.not_in(nil)).blank?
717
- assert_equal false, @myung.where(@age.not_in([nil])).blank?
718
- assert_equal false, @myung.where(@age.not_in([nil,1])).blank?
719
- assert_equal true, @myung.where(@age.not_in([nil,23])).blank?
720
- assert_equal false, @myung.where(@age.not_in([nil,1,2])).blank?
721
- assert_equal true, @myung.where(@age.not_in([nil,1,23])).blank?
722
-
723
- assert_equal false, @myung.where(@age.not_in(1..2)).blank?
1021
+ assert_predicate @myung.where(@age.not_in(1)), :present?
1022
+ assert_predicate @myung.where(@age.not_in(23)), :blank?
1023
+ assert_predicate @myung.where(@age.not_in([1])), :present?
1024
+ assert_predicate @myung.where(@age.not_in([1, 2])), :present?
1025
+ assert_predicate @myung.where(@age.not_in([1, 23])), :blank?
1026
+ assert_predicate @myung.where(@age.not_in(nil)), :present?
1027
+ assert_predicate @myung.where(@age.not_in([nil])), :present?
1028
+ assert_predicate @myung.where(@age.not_in([nil, 1])), :present?
1029
+ assert_predicate @myung.where(@age.not_in([nil, 23])), :blank?
1030
+ assert_predicate @myung.where(@age.not_in([nil, 1, 2])), :present?
1031
+ assert_predicate @myung.where(@age.not_in([nil, 1, 23])), :blank?
1032
+
1033
+ assert_predicate @myung.where(@age.not_in(1..2)), :present?
724
1034
 
725
1035
  # if the column is null, the entry will never be selected with not in (like every DBMS does)
726
- # assert_equal false , @test.where(@age.not_in(1)).blank?
727
- # assert_equal false , @test.where(@age.not_in([1])).blank?
728
- # assert_equal false , @test.where(@age.not_in([1,2])).blank?
729
- # assert_equal true , @test.where(@age.not_in(nil)).blank?
730
- # assert_equal true , @test.where(@age.not_in([nil])).blank?
731
- # assert_equal true , @test.where(@age.not_in([nil,1])).blank?
732
- # assert_equal true , @test.where(@age.not_in([nil,1,2])).blank?
1036
+ # assert_predicate @test.where(@age.not_in(1)), :present?
1037
+ # assert_predicate @test.where(@age.not_in([1])), :present?
1038
+ # assert_predicate @test.where(@age.not_in([1,2])), :present?
1039
+ # assert_predicate @test.where(@age.not_in(nil)), :blank?
1040
+ # assert_predicate @test.where(@age.not_in([nil])), :blank?
1041
+ # assert_predicate @test.where(@age.not_in([nil,1])), :blank?
1042
+ # assert_predicate @test.where(@age.not_in([nil,1,2])), :blank?
733
1043
  end
734
1044
 
735
1045
  def test_in_on_grouping
736
- skip "We should modify the visitor of IN to make it work" if $sqlite || @env_db == 'mssql'
737
- assert_equal 2, User.where(Arel.tuple(@name,@age).in(Arel.tuple('Myung',23),Arel.tuple('Arthur',21))).count
738
- assert_equal 1, User.where(Arel.tuple(@name,@age).in(Arel.tuple('Myung',23))).count
739
- assert_equal 0, User.where(Arel.tuple(@name,@age).in([])).count
1046
+ skip 'We should modify the visitor of IN to make it work' if $sqlite || @env_db == 'mssql'
1047
+ assert_equal 2, User.where(Arel.tuple(@name, @age).in(Arel.tuple('Myung', 23), Arel.tuple('Arthur', 21))).count
1048
+ assert_equal 1, User.where(Arel.tuple(@name, @age).in(Arel.tuple('Myung', 23))).count
1049
+ assert_equal 0, User.where(Arel.tuple(@name, @age).in([])).count
740
1050
  end
741
1051
 
742
1052
  def test_alias_shortened
743
- if ['postgresql','oracle'].include?(@env_db)
1053
+ if %w[postgresql oracle].include?(@env_db)
744
1054
  new_alias = Arel.shorten('azerty' * 15)
745
1055
  at = User.arel_table.alias('azerty' * 15)
746
1056
  assert_equal "\"user_tests\" \"#{new_alias}\"".downcase, User.arel_table.alias('azerty' * 15).to_sql.downcase
@@ -763,64 +1073,64 @@ module ArelExtensions
763
1073
  assert (479.82048 - t(User.where(nil), @score.variance(unbiased: false))).abs < 0.01
764
1074
  assert ( 23.23355 - t(User.where(nil), @score.std)).abs < 0.01
765
1075
  assert ( 21.90480 - t(User.where(nil), @score.std(unbiased: false))).abs < 0.01
766
- skip "Not Yet Implemented" # if !['postgresql'].include?(@env_db)
767
- assert_equal 2, User.select(@score.std(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
768
- assert_equal 2, User.select(@score.variance(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
769
- assert_equal 2, User.select(@score.sum(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
770
- assert_equal 2, User.select(@comments.group_concat(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
1076
+ skip 'Not Yet Implemented' # if !['postgresql'].include?(@env_db)
1077
+ assert_equal 2, User.select(@score.std(group: Arel.when(@name > 'M').then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
1078
+ assert_equal 2, User.select(@score.variance(group: Arel.when(@name > 'M').then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
1079
+ assert_equal 2, User.select(@score.sum(group: Arel.when(@name > 'M').then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
1080
+ assert_equal 2, User.select(@comments.group_concat(group: Arel.when(@name > 'M').then(0).else(1)).as('res')).map{|e| e['res']}.uniq.length
771
1081
  end
772
1082
 
773
1083
  def test_levenshtein_distance
774
- skip "Not Yet Implemented" if $sqlite
775
- assert_equal 0, t(@arthur,@name.levenshtein_distance("Arthur"))
776
- assert_equal 2, t(@arthur,@name.levenshtein_distance("Artoor"))
777
- assert_equal 1, t(@arthur,@name.levenshtein_distance("Artehur"))
1084
+ skip 'Not Yet Implemented' if $sqlite
1085
+ assert_equal 0, t(@arthur, @name.levenshtein_distance('Arthur'))
1086
+ assert_equal 2, t(@arthur, @name.levenshtein_distance('Artoor'))
1087
+ assert_equal 1, t(@arthur, @name.levenshtein_distance('Artehur'))
778
1088
  end
779
1089
 
780
1090
  def test_json
781
1091
  skip "Can't be tested on travis"
782
1092
  # creation
783
- assert_equal 'Arthur', t(@arthur,Arel.json(@name))
784
- assert_equal ["Arthur","Arthur"], parse_json(t(@arthur,Arel.json(@name,@name)))
785
- assert_equal ({"Arthur" => "Arthur", "Arthur2" => "ArthurArthur"}), parse_json(t(@arthur,Arel.json({@name => @name,@name+"2" => @name+@name})))
786
- assert_equal ({"Arthur" => "Arthur","Arthur2" => 1}), parse_json(t(@arthur,Arel.json({@name => @name,@name+"2" => 1})))
787
- assert_equal ([{"age" => 21},{"name" => "Arthur","score" => 65.62}]), parse_json(t(@arthur,Arel.json([{age: @age},{name: @name,score: @score}])))
1093
+ assert_equal 'Arthur', t(@arthur, Arel.json(@name))
1094
+ assert_equal %w[Arthur Arthur], parse_json(t(@arthur, Arel.json(@name, @name)))
1095
+ assert_equal ({'Arthur' => 'Arthur', 'Arthur2' => 'ArthurArthur'}), parse_json(t(@arthur, Arel.json({@name => @name, @name + '2' => @name + @name})))
1096
+ assert_equal ({'Arthur' => 'Arthur', 'Arthur2' => 1}), parse_json(t(@arthur, Arel.json({@name => @name, @name + '2' => 1})))
1097
+ assert_equal [{'age' => 21}, {'name' => 'Arthur', 'score' => 65.62}], parse_json(t(@arthur, Arel.json([{age: @age}, {name: @name, score: @score}])))
788
1098
 
789
1099
  # aggregate
790
- assert_equal ({"5" => "Lucas", "15" => "Sophie", "23" => "Myung", "25" => "Laure"}),
791
- parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16),Arel.json({@age => @name}).group(false)))
792
- assert_equal ({"5" => "Lucas", "15" => "Sophie", "23" => "Myung", "25" => "Laure", "Laure"=>25, "Lucas"=>5, "Myung"=>23, "Sophie"=>15}),
793
- parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16),Arel.json({@age => @name,@name => @age}).group(false)))
794
- assert_equal ([{"5" => "Lucas"},{ "15" => "Sophie"},{ "23" => "Myung"},{ "25" => "Laure"}]),
795
- parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score),Arel.json({@age => @name}).group(true,[@age])))
1100
+ assert_equal ({'5' => 'Lucas', '15' => 'Sophie', '23' => 'Myung', '25' => 'Laure'}),
1101
+ parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16), Arel.json({@age => @name}).group(false)))
1102
+ assert_equal ({'5' => 'Lucas', '15' => 'Sophie', '23' => 'Myung', '25' => 'Laure', 'Laure' => 25, 'Lucas' => 5, 'Myung' => 23, 'Sophie' => 15}),
1103
+ parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16), Arel.json({@age => @name, @name => @age}).group(false)))
1104
+ assert_equal [{'5' => 'Lucas'}, {'15' => 'Sophie'}, {'23' => 'Myung'}, {'25' => 'Laure'}],
1105
+ parse_json(t(User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score), Arel.json({@age => @name}).group(true, [@age])))
796
1106
 
797
- # puts User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score,Arel.json({@age => @name}).group(true,[@age])).to_sql
798
- # puts User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score,Arel.json({@age => @name}).group(true,[@age])).to_a
1107
+ # puts User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score, Arel.json({@age => @name}).group(true,[@age])).to_sql
1108
+ # puts User.group(:score).where(@age.is_not_null).where(@score == 20.16).select(@score, Arel.json({@age => @name}).group(true,[@age])).to_a
799
1109
 
800
- skip "Not Yet Implemented" if $sqlite || ['oracle','mssql'].include?(@env_db)
1110
+ skip 'Not Yet Implemented' if $sqlite || %w[oracle mssql].include?(@env_db)
801
1111
  # get
802
- h1 = Arel.json({@name => @name+@name,@name+"2" => 1})
803
- assert_equal "ArthurArthur", parse_json(t(@arthur,h1.get(@name)))
804
- h2 = Arel.json([{age: @age},{name: @name,score: @score}])
805
- assert_equal ({"age" => 21}), parse_json(t(@arthur,h2.get(0)))
806
- assert_equal 21, parse_json(t(@arthur,h2.get(0).get('age')))
807
- assert_nil t(@arthur,h2.get('age'))
1112
+ h1 = Arel.json({@name => @name + @name, @name + '2' => 1})
1113
+ assert_equal 'ArthurArthur', parse_json(t(@arthur, h1.get(@name)))
1114
+ h2 = Arel.json([{age: @age}, {name: @name, score: @score}])
1115
+ assert_equal ({'age' => 21}), parse_json(t(@arthur, h2.get(0)))
1116
+ assert_equal 21, parse_json(t(@arthur, h2.get(0).get('age')))
1117
+ assert_nil t(@arthur, h2.get('age'))
808
1118
  # set
809
- assert_equal ({"Arthur" => ["toto", "tata"], "Arthur2" => 1}), parse_json(t(@arthur,h1.set(@name, ['toto','tata'])))
810
- assert_equal ({"Arthur" => "ArthurArthur", "Arthur2" => 1, "Arthur3" => 2}), parse_json(t(@arthur,h1.set(@name+"3",2)))
811
- assert_equal ({"Arthur" => "ArthurArthur", "Arthur2" => 1, "Arthur3" => nil}), parse_json(t(@arthur,h1.set(@name+"3",nil)))
812
- assert_equal ({"Arthur" => "ArthurArthur", "Arthur2" => 1, "Arthur3" => {"a" => 2}}), parse_json(t(@arthur,h1.set(@name+"3",{a: 2})))
1119
+ assert_equal ({'Arthur' => %w[toto tata], 'Arthur2' => 1}), parse_json(t(@arthur, h1.set(@name, %w[toto tata])))
1120
+ assert_equal ({'Arthur' => 'ArthurArthur', 'Arthur2' => 1, 'Arthur3' => 2}), parse_json(t(@arthur, h1.set(@name + '3', 2)))
1121
+ assert_equal ({'Arthur' => 'ArthurArthur', 'Arthur2' => 1, 'Arthur3' => nil}), parse_json(t(@arthur, h1.set(@name + '3', nil)))
1122
+ assert_equal ({'Arthur' => 'ArthurArthur', 'Arthur2' => 1, 'Arthur3' => {'a' => 2}}), parse_json(t(@arthur, h1.set(@name + '3', {a: 2})))
813
1123
  # merge
814
- assert_equal ({"Arthur" => ["toto", "tata"], "Arthur2" => 1, "Arthur3" => 2}), parse_json(t(@arthur,h1.merge({@name => ['toto','tata']},{@name+"3" => 2})))
815
- assert_equal ({"Arthur" => ["toto", "tata"], "Arthur2" => 1, "Arthur3" => 2}), parse_json(t(@arthur,h1.merge({@name => ['toto','tata'], @name+"3" => 2})))
816
- assert_equal ({"Arthur" => "ArthurArthur","Arthur2" => 1}), parse_json(t(@arthur,h1.merge({})))
1124
+ assert_equal ({'Arthur' => %w[toto tata], 'Arthur2' => 1, 'Arthur3' => 2}), parse_json(t(@arthur, h1.merge({@name => %w[toto tata]}, {@name + '3' => 2})))
1125
+ assert_equal ({'Arthur' => %w[toto tata], 'Arthur2' => 1, 'Arthur3' => 2}), parse_json(t(@arthur, h1.merge({@name => %w[toto tata], @name + '3' => 2})))
1126
+ assert_equal ({'Arthur' => 'ArthurArthur', 'Arthur2' => 1}), parse_json(t(@arthur, h1.merge({})))
817
1127
  end
818
1128
 
819
1129
  def test_as_on_everything
820
1130
  name = @arthur.select(@name.as('NaMe')).first.attributes
821
- assert_equal 'Arthur', name["NaMe"] || name["name"] # because of Oracle
822
- assert_equal 'Arthur', @arthur.select(@name.as('Na Me')).first.attributes["Na Me"]
823
- assert_equal 'ArthurArthur', @arthur.select((@name+@name).as('Na-Me')).first.attributes["Na-Me"]
1131
+ assert_equal 'Arthur', name['NaMe'] || name['name'] # because of Oracle
1132
+ assert_equal 'Arthur', @arthur.select(@name.as('Na Me')).first.attributes['Na Me']
1133
+ assert_equal 'ArthurArthur', @arthur.select((@name + @name).as('Na-Me')).first.attributes['Na-Me']
824
1134
  end
825
1135
 
826
1136
  def test_exists_in_subquery