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
@@ -5,6 +5,27 @@ module ArelExtensions
5
5
  module VisitorToSql
6
6
  describe 'the to_sql visitor' do
7
7
  before do
8
+ if Arel::Table.engine.is_a?(ActiveRecord::Base)
9
+ puts 'This is a hack.'
10
+ # As a matter of fact, if the whole if-block is removed, the to_sql
11
+ # test become flaky.
12
+ #
13
+ # The first time `Arel::Table.engine` is called
14
+ # from `ArelExtensions.column_of_via_arel_table(table_name, column_name)`
15
+ # in `lib/arel_extensions/helpers.rb`
16
+ # will almost always fail. It's important to note that when the test
17
+ # fails, it's always on 1 test case, and every subsequent test that
18
+ # calls to these methods passes.
19
+ #
20
+ # After investigation, it turned out that `Arel::Table.engine` will be
21
+ # of type `ActiveRecord::Base` instead of the expected `FakeRecord::Base`
22
+ # as set in this `before` block, in the `@conn` instance variable.
23
+ # Subsequent calls to `column_of_via_arel_table` will have
24
+ # `Arel::Table.engine` of the expected type.
25
+ #
26
+ # It is still unclear why the call in the condition of this if-block
27
+ # fixes this behavior.
28
+ end
8
29
  @conn = FakeRecord::Base.new
9
30
  Arel::Table.engine = @conn
10
31
  @visitor = Arel::Visitors::ToSql.new @conn.connection
@@ -22,19 +43,19 @@ module ArelExtensions
22
43
  end
23
44
  end
24
45
 
25
- describe "primitive methods" do
26
- it "should be able to recognize equal nodes" do
27
- c = @table[:id]
28
- _(c == 1).must_be :eql?, (c == 1)
29
- _((c == 1).right.hash).must_equal (c == 1).right.hash
30
- _((c == 1).hash).must_equal (c == 1).hash
46
+ describe 'primitive methods' do
47
+ it 'should be able to recognize equal nodes' do
48
+ c = @table[:id]
49
+ _(c == 1).must_be :eql?, (c == 1)
50
+ _((c == 1).right.hash).must_equal (c == 1).right.hash
51
+ _((c == 1).hash).must_equal (c == 1).hash
31
52
 
32
- _([c == 1, c == 1].uniq).must_equal [c == 1]
33
- end
53
+ _([c == 1, c == 1].uniq).must_equal [c == 1]
54
+ end
34
55
  end
35
56
 
36
57
  # Math Functions
37
- it "should not break Arel functions" do
58
+ it 'should not break Arel functions' do
38
59
  _(compile(@price + 42)).must_be_like %{("products"."price" + 42)}
39
60
  _(compile(@table[:id] + @table[:pas_en_base]))
40
61
  .must_be_like %{("users"."id" + "users"."pas_en_base")}
@@ -50,7 +71,7 @@ module ArelExtensions
50
71
  .must_be_like %{"users"."pas_en_base" * "users"."id"}
51
72
  end
52
73
 
53
- it "should return right calculations on numbers" do
74
+ it 'should return right calculations on numbers' do
54
75
  # puts (@price.abs + 42).inspect
55
76
  _(compile(@price.abs + 42)).must_be_like %{(ABS("products"."price") + 42)}
56
77
  _(compile(@price.ceil + 42)).must_be_like %{(CEIL("products"."price") + 42)}
@@ -87,7 +108,7 @@ module ArelExtensions
87
108
  end
88
109
 
89
110
  # String Functions
90
- it "should accept functions on strings" do
111
+ it 'should accept functions on strings' do
91
112
  c = @table[:name]
92
113
  _(compile(c + 'test')).must_be_like %{CONCAT(\"users\".\"name\", 'test')}
93
114
  _(compile(c.length)).must_be_like %{LENGTH("users"."name")}
@@ -114,7 +135,7 @@ module ArelExtensions
114
135
 
115
136
  # some optimization on concat
116
137
  _(compile(c + 'test' + ' chain')).must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
117
- _(compile(Arel::Nodes.build_quoted('test') + ' chain')).must_be_like %{'test chain'}
138
+ _(compile(Arel.quoted('test') + ' chain')).must_be_like %{'test chain'}
118
139
  _(compile(c + '' + c)).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
119
140
 
120
141
  _(compile(c.md5)).must_be_like %{MD5(\"users\".\"name\")}
@@ -122,7 +143,7 @@ module ArelExtensions
122
143
 
123
144
  # Comparators
124
145
 
125
- it "should accept comparators on integers" do
146
+ it 'should accept comparators on integers' do
126
147
  _(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
127
148
  _(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
128
149
  _(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
@@ -138,7 +159,7 @@ module ArelExtensions
138
159
  # _(compile(@table[:id].count >= 42)).must_match %{COUNT("users"."id") >= 42}
139
160
  end
140
161
 
141
- it "should accept comparators on dates" do
162
+ it 'should accept comparators on dates' do
142
163
  c = @table[:created_at]
143
164
  u = @table[:updated_at]
144
165
  _(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
@@ -146,7 +167,7 @@ module ArelExtensions
146
167
  _(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
147
168
  end
148
169
 
149
- it "should accept comparators on strings" do
170
+ it 'should accept comparators on strings' do
150
171
  c = @table[:name]
151
172
  _(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
152
173
  _(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
@@ -162,33 +183,33 @@ module ArelExtensions
162
183
 
163
184
  # Maths
164
185
  # DateDiff
165
- it "should diff date col and date" do
186
+ it 'should diff date col and date' do
166
187
  _(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
167
188
  end
168
189
 
169
- it "should diff date col and datetime col" do
190
+ it 'should diff date col and datetime col' do
170
191
  _(compile(@table[:created_at] - @table[:updated_at])).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
171
192
  end
172
193
 
173
- it "should diff date col and datetime col with AS" do
194
+ it 'should diff date col and datetime col with AS' do
174
195
  _(compile((@table[:updated_at] - @table[:created_at]).as('new_name')))
175
196
  .must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
176
197
  end
177
198
 
178
- it "should diff between time values" do
179
- d2 = Time.new(2015,6,1)
180
- d1 = DateTime.new(2015,6,2)
199
+ it 'should diff between time values' do
200
+ d2 = Time.new(2015, 6, 1)
201
+ d1 = DateTime.new(2015, 6, 2)
181
202
  _(compile(ArelExtensions::Nodes::DateDiff.new([d1, d2])))
182
203
  .must_match("DATEDIFF('2015-06-02', '2015-06-01')")
183
204
  end
184
205
 
185
- it "should diff between time values and time col" do
186
- d1 = DateTime.new(2015,6,2)
206
+ it 'should diff between time values and time col' do
207
+ d1 = DateTime.new(2015, 6, 2)
187
208
  _(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
188
209
  .must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
189
210
  end
190
211
 
191
- it "should diff between date col and duration" do
212
+ it 'should diff between date col and duration' do
192
213
  d1 = 10
193
214
  d2 = -10
194
215
  _(compile(@table[:created_at] - d1))
@@ -197,7 +218,7 @@ module ArelExtensions
197
218
  .must_match %{DATE_SUB("users"."created_at", -10)}
198
219
  end
199
220
 
200
- it "should accept operators on dates with numbers" do
221
+ it 'should accept operators on dates with numbers' do
201
222
  c = @table[:created_at]
202
223
  # u = @table[:updated_at]
203
224
  _(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
@@ -205,7 +226,7 @@ module ArelExtensions
205
226
  end
206
227
 
207
228
  # Maths on sums
208
- it "should accept math operators on anything" do
229
+ it 'should accept math operators on anything' do
209
230
  c = @table[:name]
210
231
  _((c == 'test').to_sql)
211
232
  .must_be_like %{"users"."name" = 'test'}
@@ -219,7 +240,7 @@ module ArelExtensions
219
240
  _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
220
241
  end
221
242
 
222
- it "should manage complex formulas" do
243
+ it 'should manage complex formulas' do
223
244
  c = @table[:name]
224
245
  _(compile(
225
246
  (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
@@ -227,7 +248,7 @@ module ArelExtensions
227
248
  .must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
228
249
  end
229
250
 
230
- it "should accept aggregator like GROUP CONCAT" do
251
+ it 'should accept aggregator like GROUP CONCAT' do
231
252
  _(@table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql)
232
253
  .must_be_like %{SELECT GROUP_CONCAT("users"."first_name") FROM "users" GROUP BY "users"."last_name"}
233
254
  _(@table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql)
@@ -235,7 +256,7 @@ module ArelExtensions
235
256
  end
236
257
 
237
258
  # Unions
238
- it "should accept union operators on queries and union nodes" do
259
+ it 'should accept union operators on queries and union nodes' do
239
260
  c = @table.project(@table[:name])
240
261
  _(compile(c + c))
241
262
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
@@ -252,66 +273,73 @@ module ArelExtensions
252
273
  c = @table.project(@table[:name])
253
274
  _(compile(c.union_all(c)))
254
275
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
255
- _((c.union_all(c)).to_sql)
276
+ _(c.union_all(c).to_sql)
256
277
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
257
- _((c.union_all(c.union_all(c))).to_sql)
278
+ _(c.union_all(c.union_all(c)).to_sql)
258
279
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
259
- _(((c.union_all(c)).union_all(c)).to_sql)
280
+ _((c.union_all(c)).union_all(c).to_sql)
260
281
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
261
- _((c.union_all(c).union_all(c)).to_sql)
282
+ _(c.union_all(c).union_all(c).to_sql)
262
283
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
263
284
  _((c.union_all(c)).as('union_table').to_sql)
264
285
  .must_be_like %{((SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")) union_table}
265
286
  end
266
287
 
267
288
  # Case
268
- it "should accept case clause" do
269
- _(@table[:name].when("smith").then("cool").when("doe").then("fine").else("uncool").to_sql)
289
+ it 'should accept case clause' do
290
+ _(@table[:name].when('smith').then('cool').when('doe').then('fine').else('uncool').to_sql)
270
291
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' WHEN 'doe' THEN 'fine' ELSE 'uncool' END}
271
- _(@table[:name].when("smith").then(1).when("doe").then(2).else(0).to_sql)
292
+ _(@table[:name].when('smith').then(1).when('doe').then(2).else(0).to_sql)
272
293
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
273
- _(ArelExtensions::Nodes::Case.new.when(@table[:name] == "smith").then(1).when(@table[:name] == "doe").then(2).else(0).to_sql)
294
+ _(Arel.when(@table[:name] == 'smith').then(1).when(@table[:name] == 'doe').then(2).else(0).to_sql)
274
295
  .must_be_like %{CASE WHEN "users"."name" = 'smith' THEN 1 WHEN "users"."name" = 'doe' THEN 2 ELSE 0 END}
275
- _(ArelExtensions::Nodes::Case.new(@table[:name]).when("smith").then(1).when("doe").then(2).else(0).to_sql)
296
+ _(ArelExtensions::Nodes::Case.new(@table[:name]).when('smith').then(1).when('doe').then(2).else(0).to_sql)
276
297
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
277
- _(@table[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql)
298
+ _(@table[:name].when('smith').then(1).when('doe').then(2).else(0).sum.to_sql)
278
299
  .must_be_like %{SUM(CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)}
279
- _(@table[:name].when("smith").then("cool").else("uncool").matches('value',false).to_sql)
300
+ _(@table[:name].when('smith').then('cool').else('uncool').matches('value', false).to_sql)
280
301
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END LIKE 'value'}
281
- _(@table[:name].when("smith").then("cool").else("uncool").imatches('value',false).to_sql)
302
+ _(@table[:name].when('smith').then('cool').else('uncool').imatches('value', false).to_sql)
282
303
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
283
304
  end
284
305
 
285
- it "should be possible to use as on anything" do
286
- _(compile(@table[:name].as('alias'))).must_be_like %{"users"."name" AS alias}
287
- _(compile(@table[:name].concat(' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
288
- _(compile((@table[:name] + ' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
289
- _(compile((@table[:age] + 42).as('alias'))).must_be_like %{("users"."age" + 42) AS alias}
290
- _(compile(@table[:name].coalesce('').as('alias'))).must_be_like %{COALESCE("users"."name", '') AS alias}
291
- _(compile(Arel::Nodes.build_quoted('test').as('alias'))).must_be_like %{'test' AS alias}
292
- _(compile(@table.project(@table[:name]).as('alias'))).must_be_like %{(SELECT "users"."name" FROM "users") alias}
293
- _(compile(@table[:name].when("smith").then("cool").else("uncool").as('alias')))
294
- .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias}
306
+ it 'should be possible to use as/xas on anything' do
307
+ {
308
+ @table[:name] => %{"users"."name" AS alias},
309
+ @table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
310
+ (@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
311
+ (@table[:age] + 42) => %{("users"."age" + 42) AS alias},
312
+ @table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
313
+ Arel.quoted('test') => %{'test' AS alias},
314
+ @table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
315
+ @table[:name].when('smith').then('cool').else('uncool') => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
316
+ }.each do |exp, res|
317
+ _(compile(exp.as('alias'))).must_be_like res
318
+ _(compile(exp.xas('alias'))).must_be_like res
319
+
320
+ res_no_alias = res.gsub(/\s*(?:AS alias|"alias")\s*\z/, '')
321
+ _(compile(exp.xas(nil))).must_be_like res_no_alias
322
+ end
295
323
  end
296
324
 
297
- it "should accept comparators on functions" do
325
+ it 'should accept comparators on functions' do
298
326
  c = @table[:name]
299
327
  _(compile(c.soundex == 'test')).must_be_like %{SOUNDEX("users"."name") = 'test'}
300
328
  _(compile(c.soundex != 'test')).must_be_like %{SOUNDEX("users"."name") != 'test'}
301
329
  _(compile(c.length >= 0)).must_be_like %{LENGTH("users"."name") >= 0}
302
330
  end
303
331
 
304
- it "should accept in on select statement" do
332
+ it 'should accept in on select statement' do
305
333
  c = @table[:name]
306
334
  _(compile(c.in(@table.project(@table[:name]))))
307
335
  .must_be_like %{"users"."name" IN (SELECT "users"."name" FROM "users")}
308
336
  end
309
337
 
310
- it "should accept coalesce function properly even on none actual tables and attributes" do
338
+ it 'should accept coalesce function properly even on none actual tables and attributes' do
311
339
  fake_at = Arel::Table.new('fake_table')
312
340
  _(compile(fake_at['fake_attribute'].coalesce('other_value')))
313
341
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value')}
314
- _(compile(fake_at['fake_attribute'].coalesce('other_value1','other_value2')))
342
+ _(compile(fake_at['fake_attribute'].coalesce('other_value1', 'other_value2')))
315
343
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value1', 'other_value2')}
316
344
  _(compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2')))
317
345
  .must_be_like %{COALESCE(COALESCE("fake_table"."fake_attribute", 'other_value1'), 'other_value2')}
@@ -321,7 +349,7 @@ module ArelExtensions
321
349
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') ILIKE 'truc'}
322
350
  end
323
351
 
324
- it "should be possible to cast nodes types" do
352
+ it 'should be possible to cast nodes types' do
325
353
  _(compile(@table[:id].cast('char')))
326
354
  .must_be_like %{CAST("users"."id" AS char)}
327
355
  _(compile(@table[:id].coalesce(' ').cast('char')))
@@ -336,34 +364,34 @@ module ArelExtensions
336
364
  .must_be_like %{(CAST("users"."id" AS int) + 2)}
337
365
  end
338
366
 
339
- describe "the function in" do
340
- it "should be possible to have nil element in the function IN" do
367
+ describe 'the function in' do
368
+ it 'should be possible to have nil element in the function IN' do
341
369
  _(compile(@table[:id].in(nil)))
342
370
  .must_be_like %{ISNULL("users"."id")}
343
371
  _(compile(@table[:id].in([nil])))
344
372
  .must_be_like %{ISNULL("users"."id")}
345
- _(compile(@table[:id].in([nil,1])))
373
+ _(compile(@table[:id].in([nil, 1])))
346
374
  .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
347
- _(compile(@table[:id].in([nil,1,2])))
375
+ _(compile(@table[:id].in([nil, 1, 2])))
348
376
  .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
349
377
  _(compile(@table[:id].in(1)))
350
378
  .must_be_like %{"users"."id" IN (1)}
351
379
  _(compile(@table[:id].in([1])))
352
380
  .must_be_like %{"users"."id" = 1}
353
- _(compile(@table[:id].in([1,2])))
381
+ _(compile(@table[:id].in([1, 2])))
354
382
  .must_be_like %{"users"."id" IN (1, 2)}
355
383
  _(compile(@table[:id].in([])))
356
384
  .must_be_like %{1 = 0}
357
385
  end
358
386
 
359
- it "should be possible to correctly use a Range on an IN" do
387
+ it 'should be possible to correctly use a Range on an IN' do
360
388
  _(compile(@table[:id].in(1..4)))
361
389
  .must_be_like %{"users"."id" BETWEEN (1) AND (4)}
362
390
  _(compile(@table[:created_at].in(Date.new(2016, 3, 31)..Date.new(2017, 3, 31))))
363
391
  .must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
364
392
  end
365
393
 
366
- it "should be possible to use a list of values and ranges on an IN" do
394
+ it 'should be possible to use a list of values and ranges on an IN' do
367
395
  _(compile(@table[:id].in [1..10, 20, 30, 40..50]))
368
396
  .must_be_like %{("users"."id" IN (20, 30)) OR ("users"."id" BETWEEN (1) AND (10)) OR ("users"."id" BETWEEN (40) AND (50))}
369
397
  _(compile(@table[:created_at].in(Date.new(2016, 1, 1), Date.new(2016, 2, 1)..Date.new(2016, 2, 28), Date.new(2016, 3, 31)..Date.new(2017, 3, 31), Date.new(2018, 1, 1))))
@@ -372,8 +400,8 @@ module ArelExtensions
372
400
  OR ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
373
401
  end
374
402
 
375
- it "should respecting Grouping" do
376
- g = ->(*v) { Arel::Nodes::Grouping.new(v) }
403
+ it 'should respecting Grouping' do
404
+ g = ->(*v) { Arel.grouping(v) }
377
405
  _(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
378
406
  .must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
379
407
  _(compile(g[@table[:id], @table[:age]].in [g[1, 42], g[2, 51]]))
@@ -384,27 +412,27 @@ module ArelExtensions
384
412
  end
385
413
  end
386
414
 
387
- describe "the function not_in" do
388
- it "should be possible to have nil element in the function IN" do
415
+ describe 'the function not_in' do
416
+ it 'should be possible to have nil element in the function IN' do
389
417
  _(compile(@table[:id].not_in nil))
390
418
  .must_be_like %{NOT ISNULL("users"."id")}
391
419
  _(compile(@table[:id].not_in [nil]))
392
420
  .must_be_like %{NOT ISNULL("users"."id")}
393
- _(compile(@table[:id].not_in [nil,1]))
421
+ _(compile(@table[:id].not_in [nil, 1]))
394
422
  .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" != 1)}
395
- _(compile(@table[:id].not_in [nil,1,2]))
423
+ _(compile(@table[:id].not_in [nil, 1, 2]))
396
424
  .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" NOT IN (1, 2))}
397
425
  _(compile(@table[:id].not_in 1))
398
426
  .must_be_like %{"users"."id" NOT IN (1)}
399
427
  _(compile(@table[:id].not_in [1]))
400
428
  .must_be_like %{"users"."id" != 1}
401
- _(compile(@table[:id].not_in [1,2]))
429
+ _(compile(@table[:id].not_in [1, 2]))
402
430
  .must_be_like %{"users"."id" NOT IN (1, 2)}
403
431
  _(compile(@table[:id].not_in []))
404
432
  .must_be_like %{1 = 1}
405
433
  end
406
434
 
407
- it "should be possible to correctly use a Range on an IN" do
435
+ it 'should be possible to correctly use a Range on an IN' do
408
436
  # FIXME: Should use NOT BETWEEN
409
437
  _(compile(@table[:id].not_in 1..4))
410
438
  .must_be_like %{NOT ("users"."id" BETWEEN (1) AND (4))}
@@ -413,7 +441,7 @@ module ArelExtensions
413
441
  .must_be_like %{NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
414
442
  end
415
443
 
416
- it "should be possible to use a list of values and ranges on an IN" do
444
+ it 'should be possible to use a list of values and ranges on an IN' do
417
445
  _(compile(@table[:id].not_in [1..10, 20, 30, 40..50]))
418
446
  .must_be_like %{ ("users"."id" NOT IN (20, 30))
419
447
  AND (NOT ("users"."id" BETWEEN (1) AND (10)))
@@ -425,26 +453,26 @@ module ArelExtensions
425
453
  end
426
454
  end
427
455
 
428
- it "should be possible to add and substract as much as we want" do
456
+ it 'should be possible to add and substract as much as we want' do
429
457
  c = @table[:name]
430
- _(compile(c.locate('test')+1))
458
+ _(compile(c.locate('test') + 1))
431
459
  .must_be_like %{(LOCATE('test', "users"."name") + 1)}
432
- _(compile(c.locate('test')-1))
460
+ _(compile(c.locate('test') - 1))
433
461
  .must_be_like %{(LOCATE('test', "users"."name") - 1)}
434
- _(compile(c.locate('test')+c.locate('test')))
462
+ _(compile(c.locate('test') + c.locate('test')))
435
463
  .must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
436
- _(compile(c.locate('test')+1+c.locate('test')-1 + 1))
464
+ _(compile(c.locate('test') + 1 + c.locate('test') - 1 + 1))
437
465
  .must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
438
466
  end
439
467
 
440
- it "should be possible to add and substract on some nodes" do
468
+ it 'should be possible to add and substract on some nodes' do
441
469
  c = @table[:name]
442
- _(compile(c.when(0,0).else(42) + 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
443
- _(compile(c.when(0,0).else(42) - 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
444
- _(compile(c.when(0,"0").else("42") + "42")).must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
470
+ _(compile(c.when(0, 0).else(42) + 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
471
+ _(compile(c.when(0, 0).else(42) - 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
472
+ _(compile(c.when(0, '0').else('42') + '42')).must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
445
473
  end
446
474
 
447
- it "should be possible to desc and asc on functions" do
475
+ it 'should be possible to desc and asc on functions' do
448
476
  c = @table[:name]
449
477
  _(compile(c.asc))
450
478
  .must_be_like %{"users"."name" ASC}
@@ -452,19 +480,19 @@ module ArelExtensions
452
480
  .must_be_like %{SUBSTRING("users"."name", 2) ASC}
453
481
  _(compile(c.substring(2).desc))
454
482
  .must_be_like %{SUBSTRING("users"."name", 2) DESC}
455
- _(compile((c.locate('test')+1).asc))
483
+ _(compile((c.locate('test') + 1).asc))
456
484
  .must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
457
485
  end
458
486
 
459
- it "should be possible to call Table function on TableAlias" do
487
+ it 'should be possible to call Table function on TableAlias' do
460
488
  t = @table
461
- a = t.alias("aliased_users")
489
+ a = t.alias('aliased_users')
462
490
  _(compile(a.join(t).join_sources))
463
491
  .must_be_like %{INNER JOIN \"users\"}
464
492
  end
465
493
 
466
- describe "logical functions" do
467
- it "should know about truth" do
494
+ describe 'logical functions' do
495
+ it 'should know about truth' do
468
496
  _(compile(Arel.false))
469
497
  .must_be_like %{1 = 0}
470
498
 
@@ -472,7 +500,7 @@ module ArelExtensions
472
500
  .must_be_like %{1 = 1}
473
501
  end
474
502
 
475
- it "boolean nodes should be variadic" do
503
+ it 'boolean nodes should be variadic' do
476
504
  c = @table[:id]
477
505
 
478
506
  _(compile(Arel::Nodes::And.new))
@@ -497,8 +525,8 @@ module ArelExtensions
497
525
  .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
498
526
  end
499
527
 
500
- it "should know trivial identities" do
501
- skip "For future optimization"
528
+ it 'should know trivial identities' do
529
+ skip 'For future optimization'
502
530
  c = @table[:id]
503
531
  _(compile(Arel::Nodes::And.new(Arel.true, c == 1)))
504
532
  .must_be_like %{"users"."id" = 1}
@@ -515,7 +543,7 @@ module ArelExtensions
515
543
  .must_be_like %{"users"."id" = 1}
516
544
  end
517
545
 
518
- it "should be possible to have multiple arguments on an OR or an AND node" do
546
+ it 'should be possible to have multiple arguments on an OR or an AND node' do
519
547
  c = @table[:id]
520
548
  _(compile((c == 1).and))
521
549
  .must_be_like %{"users"."id" = 1}
@@ -534,7 +562,7 @@ module ArelExtensions
534
562
  .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
535
563
  end
536
564
 
537
- it "should avoid useless nesting" do
565
+ it 'should avoid useless nesting' do
538
566
  c = @table[:id]
539
567
  _(compile(((c == 1).and(c == 2)).and ((c == 3).and(c == 4))))
540
568
  .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3) AND ("users"."id" = 4)}
@@ -548,7 +576,7 @@ module ArelExtensions
548
576
  end
549
577
  end
550
578
 
551
- puts "AREL VERSION : " + Arel::VERSION.to_s
579
+ puts "AREL VERSION: #{Arel::VERSION}"
552
580
  end
553
581
  end
554
582
  end