arel_extensions 1.2.5 → 1.2.15

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -4
  3. data/.travis.yml +54 -86
  4. data/README.md +7 -2
  5. data/Rakefile +38 -27
  6. data/arel_extensions.gemspec +1 -1
  7. data/functions.html +2 -2
  8. data/gemfiles/rails4.gemfile +1 -1
  9. data/gemfiles/rails6.gemfile +30 -0
  10. data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
  11. data/generate_gems.sh +14 -0
  12. data/lib/arel_extensions.rb +49 -21
  13. data/lib/arel_extensions/attributes.rb +0 -1
  14. data/lib/arel_extensions/boolean_functions.rb +38 -13
  15. data/lib/arel_extensions/common_sql_functions.rb +5 -4
  16. data/lib/arel_extensions/insert_manager.rb +26 -24
  17. data/lib/arel_extensions/math.rb +3 -3
  18. data/lib/arel_extensions/math_functions.rb +4 -4
  19. data/lib/arel_extensions/nodes/abs.rb +0 -0
  20. data/lib/arel_extensions/nodes/case.rb +8 -4
  21. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  22. data/lib/arel_extensions/nodes/coalesce.rb +0 -0
  23. data/lib/arel_extensions/nodes/collate.rb +1 -1
  24. data/lib/arel_extensions/nodes/concat.rb +0 -0
  25. data/lib/arel_extensions/nodes/date_diff.rb +1 -3
  26. data/lib/arel_extensions/nodes/duration.rb +0 -2
  27. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  28. data/lib/arel_extensions/nodes/floor.rb +0 -0
  29. data/lib/arel_extensions/nodes/formatted_number.rb +20 -20
  30. data/lib/arel_extensions/nodes/function.rb +0 -0
  31. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  32. data/lib/arel_extensions/nodes/json.rb +43 -30
  33. data/lib/arel_extensions/nodes/length.rb +0 -0
  34. data/lib/arel_extensions/nodes/locate.rb +0 -0
  35. data/lib/arel_extensions/nodes/power.rb +5 -4
  36. data/lib/arel_extensions/nodes/rand.rb +0 -0
  37. data/lib/arel_extensions/nodes/replace.rb +23 -5
  38. data/lib/arel_extensions/nodes/round.rb +5 -5
  39. data/lib/arel_extensions/nodes/soundex.rb +14 -13
  40. data/lib/arel_extensions/nodes/substring.rb +8 -15
  41. data/lib/arel_extensions/nodes/trim.rb +1 -1
  42. data/lib/arel_extensions/nodes/union.rb +0 -1
  43. data/lib/arel_extensions/nodes/union_all.rb +0 -1
  44. data/lib/arel_extensions/nodes/wday.rb +0 -0
  45. data/lib/arel_extensions/predications.rb +35 -33
  46. data/lib/arel_extensions/set_functions.rb +2 -2
  47. data/lib/arel_extensions/string_functions.rb +25 -6
  48. data/lib/arel_extensions/tasks.rb +5 -5
  49. data/lib/arel_extensions/version.rb +1 -1
  50. data/lib/arel_extensions/visitors.rb +1 -1
  51. data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
  52. data/lib/arel_extensions/visitors/mssql.rb +13 -12
  53. data/lib/arel_extensions/visitors/mysql.rb +67 -37
  54. data/lib/arel_extensions/visitors/oracle.rb +14 -14
  55. data/lib/arel_extensions/visitors/oracle12.rb +1 -1
  56. data/lib/arel_extensions/visitors/postgresql.rb +46 -28
  57. data/lib/arel_extensions/visitors/sqlite.rb +52 -44
  58. data/lib/arel_extensions/visitors/to_sql.rb +73 -59
  59. data/test/arelx_test_helper.rb +28 -0
  60. data/test/support/fake_record.rb +4 -0
  61. data/test/test_comparators.rb +8 -7
  62. data/test/visitors/test_bulk_insert_oracle.rb +8 -7
  63. data/test/visitors/test_bulk_insert_sqlite.rb +8 -7
  64. data/test/visitors/test_bulk_insert_to_sql.rb +3 -3
  65. data/test/visitors/test_oracle.rb +41 -41
  66. data/test/visitors/test_to_sql.rb +367 -199
  67. data/test/with_ar/all_agnostic_test.rb +63 -41
  68. data/test/with_ar/insert_agnostic_test.rb +1 -1
  69. data/test/with_ar/test_bulk_sqlite.rb +5 -4
  70. data/test/with_ar/test_math_sqlite.rb +2 -2
  71. data/test/with_ar/test_string_mysql.rb +2 -4
  72. data/test/with_ar/test_string_sqlite.rb +2 -6
  73. data/version_v1.rb +3 -0
  74. data/version_v2.rb +3 -0
  75. metadata +10 -5
  76. data/test/helper.rb +0 -18
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'arelx_test_helper'
2
2
 
3
3
  module ArelExtensions
4
4
  module BulkInsertOracle
@@ -9,8 +9,8 @@ module ArelExtensions
9
9
  @table = Arel::Table.new(:users)
10
10
  @cols = ['name', 'comments', 'created_at']
11
11
  @data = [
12
- ['nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
- ['nom2', "sdfdsfdsfsdf", '2016-01-01']
12
+ ['nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
+ ['nom2', "sdfdsfdsfsdf", '2016-01-01']
14
14
  ]
15
15
  end
16
16
 
@@ -24,11 +24,12 @@ module ArelExtensions
24
24
 
25
25
  it "should import large set of data in Oracle" do
26
26
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
27
- insert_manager.bulk_insert(@cols, @data)
28
- sql = compile(insert_manager.ast)
29
- sql.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at") ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
27
+ insert_manager.bulk_insert(@cols, @data)
28
+ _(compile(insert_manager.ast))
29
+ .must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at")
30
+ ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
30
31
  end
31
32
 
32
- end
33
+ end
33
34
  end
34
35
  end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'arelx_test_helper'
2
2
 
3
3
  module ArelExtensions
4
4
  module BulkInsertSQLlite
@@ -11,8 +11,8 @@ module ArelExtensions
11
11
  Arel::Table.engine = @conn
12
12
  @cols = ['id', 'name', 'comments', 'created_at']
13
13
  @data = [
14
- [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
15
- [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
14
+ [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
15
+ [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
16
16
  ]
17
17
  end
18
18
 
@@ -27,10 +27,11 @@ module ArelExtensions
27
27
  it "should import large set of data" do
28
28
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
29
29
  insert_manager.bulk_insert(@cols, @data)
30
- sql = compile(insert_manager.ast)
31
- sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") SELECT 23 AS 'id', 'nom1' AS 'name', 'sdfdsfdsfsdf' AS 'comments', '2016-01-01' AS 'created_at' UNION ALL SELECT 25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
30
+ _(compile(insert_manager.ast))
31
+ .must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at")
32
+ SELECT 23 AS 'id', 'nom1' AS 'name', 'sdfdsfdsfsdf' AS 'comments', '2016-01-01' AS 'created_at' UNION ALL SELECT 25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
32
33
  end
33
34
 
34
- end
35
+ end
35
36
  end
36
- end
37
+ end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'arelx_test_helper'
2
2
 
3
3
  module ArelExtensions
4
4
  module BulkInsertToSql
@@ -27,8 +27,8 @@ module ArelExtensions
27
27
  it "should import large set of data using ToSql" do
28
28
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
29
29
  insert_manager.bulk_insert(@cols, @data)
30
- sql = compile(insert_manager.ast)
31
- sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
30
+ _(compile(insert_manager.ast))
31
+ .must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
32
32
  end
33
33
  end
34
34
  end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'arelx_test_helper'
2
2
 
3
3
  module ArelExtensions
4
4
  module VisitorOracle
@@ -23,86 +23,86 @@ module ArelExtensions
23
23
  # Comparators
24
24
 
25
25
  it "should accept comparators on integers" do
26
- compile(@table[:id] == 42).must_match %{"users"."id" = 42}
27
- compile(@table[:id] == @table[:id]).must_be_like %{"users"."id" = "users"."id"}
28
- compile(@table[:id] != 42).must_match %{"users"."id" != 42}
29
- compile(@table[:id] > 42).must_match %{"users"."id" > 42}
30
- compile(@table[:id] >= 42).must_match %{"users"."id" >= 42}
31
- compile(@table[:id] >= @table[:id]).must_be_like %{"users"."id" >= "users"."id"}
32
- compile(@table[:id] < 42).must_match %{"users"."id" < 42}
33
- compile(@table[:id] <= 42).must_match %{"users"."id" <= 42}
34
- compile((@table[:id] <= 42).as('new_name')).must_match %{("users"."id" <= 42) AS new_name}
26
+ _(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
27
+ _(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
28
+ _(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
29
+ _(compile(@table[:id] > 42)).must_match %{"users"."id" > 42}
30
+ _(compile(@table[:id] >= 42)).must_match %{"users"."id" >= 42}
31
+ _(compile(@table[:id] >= @table[:id])).must_be_like %{"users"."id" >= "users"."id"}
32
+ _(compile(@table[:id] < 42)).must_match %{"users"."id" < 42}
33
+ _(compile(@table[:id] <= 42)).must_match %{"users"."id" <= 42}
34
+ _(compile((@table[:id] <= 42).as('new_name'))).must_match %{("users"."id" <= 42) AS new_name}
35
35
  end
36
36
 
37
37
  it "should accept comparators on dates" do
38
38
  c = @table[:created_at]
39
39
  u = @table[:updated_at]
40
- compile(c > @date).must_be_like %{"users"."created_at" > '2016-03-31'}
41
- compile(u >= @date).must_be_like %{"users"."updated_at" >= '2016-03-31'}
42
- compile(c < u).must_be_like %{"users"."created_at" < "users"."updated_at"}
40
+ _(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
41
+ _(compile(u >= @date)).must_be_like %{"users"."updated_at" >= '2016-03-31'}
42
+ _(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
43
43
  end
44
44
 
45
45
  it "should accept comparators on strings" do
46
46
  c = @table[:name]
47
- compile(c == 'test').must_be_like %{"users"."name" = 'test'}
48
- compile(c != 'test').must_be_like %{"users"."name" != 'test'}
49
- compile(c > 'test').must_be_like %{"users"."name" > 'test'}
50
- compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
51
- compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
52
- compile(c =~ /\Atest\Z/).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
53
- compile(c =~ /\Atest\z/).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
54
- compile(c =~ '^test$').must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
55
- compile(c !~ /\Ate\Dst\Z/).must_be_like %{NOT REGEXP_LIKE("users"."name", '^te[^0-9]st$')}
56
- compile(c.imatches('%test%')).must_be_like %{LOWER("users"."name") LIKE LOWER('%test%')}
57
- compile(c.imatches_any(['%test%', 't2'])).must_be_like %{((LOWER("users"."name") LIKE LOWER('%test%')) OR (LOWER("users"."name") LIKE LOWER('t2')))}
58
- compile(c.idoes_not_match('%test%')).must_be_like %{LOWER("users"."name") NOT LIKE LOWER('%test%')}
47
+ _(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
48
+ _(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
49
+ _(compile(c > 'test')).must_be_like %{"users"."name" > 'test'}
50
+ _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
51
+ _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
52
+ _(compile(c =~ /\Atest\Z/)).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
53
+ _(compile(c =~ /\Atest\z/)).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
54
+ _(compile(c =~ '^test$')).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
55
+ _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{NOT REGEXP_LIKE("users"."name", '^te[^0-9]st$')}
56
+ _(compile(c.imatches('%test%'))).must_be_like %{LOWER("users"."name") LIKE LOWER('%test%')}
57
+ _(compile(c.imatches_any(['%test%', 't2']))).must_be_like %{((LOWER("users"."name") LIKE LOWER('%test%')) OR (LOWER("users"."name") LIKE LOWER('t2')))}
58
+ _(compile(c.idoes_not_match('%test%'))).must_be_like %{LOWER("users"."name") NOT LIKE LOWER('%test%')}
59
59
  end
60
60
 
61
61
  # Maths
62
62
  # DateDiff
63
63
  it "should diff date col and date" do
64
- compile(@table[:created_at] - Date.new(2016, 3, 31)).must_match %{"users"."created_at" - TO_DATE('2016-03-31')}
64
+ _(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{"users"."created_at" - TO_DATE('2016-03-31')}
65
65
  end
66
66
 
67
67
  it "should diff date col and datetime col" do
68
- compile(@table[:created_at] - @table[:updated_at]).must_match %{"users"."created_at" - "users"."updated_at"}
68
+ _(compile(@table[:created_at] - @table[:updated_at])).must_match %{"users"."created_at" - "users"."updated_at"}
69
69
  end
70
70
 
71
71
  it "should diff date col and datetime col with AS" do
72
72
  sql = compile((@table[:updated_at] - @table[:created_at]).as('new_name'))
73
73
  # sql.must_be_like %{(TO_DATE("users"."updated_at") - "users"."created_at") * 86400 AS new_name}
74
- sql.must_be_like %{("users"."updated_at" - "users"."created_at") * (CASE WHEN (TRUNC("users"."updated_at", 'DDD') = "users"."updated_at") THEN 1 ELSE 86400 END) AS new_name}
74
+ _(sql).must_be_like %{("users"."updated_at" - "users"."created_at") * (CASE WHEN (TRUNC("users"."updated_at", 'DDD') = "users"."updated_at") THEN 1 ELSE 86400 END) AS new_name}
75
75
  end
76
76
 
77
77
  it "should diff between time values" do
78
78
  d2 = Time.new(2015,6,1)
79
79
  d1 = DateTime.new(2015,6,2)
80
- sql = compile(ArelExtensions::Nodes::DateDiff.new([d1,d2]))
81
- sql.must_match("TO_DATE('2015-06-02') - TO_DATE('2015-06-01')")
80
+ _(compile(ArelExtensions::Nodes::DateDiff.new([d1,d2])))
81
+ .must_match("TO_DATE('2015-06-02') - TO_DATE('2015-06-01')")
82
82
  end
83
83
 
84
84
  it "should diff between time values and time col" do
85
85
  d1 = DateTime.new(2015,6,2)
86
- sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]]))
87
- sql.must_match %{TO_DATE('2015-06-02') - "users"."updated_at"}
86
+ _(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
87
+ .must_match %{TO_DATE('2015-06-02') - "users"."updated_at"}
88
88
  end
89
89
 
90
90
  it "should accept operators on dates with numbers" do
91
91
  c = @table[:created_at]
92
- compile(c - 42).must_be_like %{DATE_SUB("users"."created_at", 42)}
93
- compile(c - @table[:id]).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
92
+ _(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
93
+ _(compile(c - @table[:id])).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
94
94
  end
95
95
 
96
96
  # Maths on sums
97
97
  it "should accept math operators on anything" do
98
98
  c = @table[:name]
99
- (c == 'test').to_sql.must_be_like %{"users"."name" = 'test'}
100
- (c != 'test').to_sql.must_be_like %{"users"."name" != 'test'}
101
- (c > 'test').to_sql.must_be_like %{"users"."name" > 'test'}
102
- compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
103
- compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
104
- compile(c =~ /\Atest\Z/).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
105
- compile(c !~ /\Ate\Dst\Z/).must_be_like %{NOT REGEXP_LIKE("users"."name", '^te[^0-9]st$')}
99
+ _((c == 'test').to_sql).must_be_like %{"users"."name" = 'test'}
100
+ _((c != 'test').to_sql).must_be_like %{"users"."name" != 'test'}
101
+ _((c > 'test').to_sql).must_be_like %{"users"."name" > 'test'}
102
+ _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
103
+ _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
104
+ _(compile(c =~ /\Atest\Z/)).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
105
+ _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{NOT REGEXP_LIKE("users"."name", '^te[^0-9]st$')}
106
106
  end
107
107
 
108
108
  end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'arelx_test_helper'
2
2
  require 'set'
3
3
 
4
4
  module ArelExtensions
@@ -22,371 +22,539 @@ module ArelExtensions
22
22
  end
23
23
  end
24
24
 
25
+ describe "primitive methods" do
26
+
27
+ it "should be able to recognize equal nodes" do
28
+ c = @table[:id]
29
+ _(c == 1).must_be :eql?, (c == 1)
30
+ _((c == 1).right.hash).must_equal (c == 1).right.hash
31
+ _((c == 1).hash).must_equal (c == 1).hash
32
+
33
+ _([c == 1, c == 1].uniq).must_equal [c == 1]
34
+ end
35
+
36
+ end
37
+
25
38
  # Math Functions
26
39
  it "should not break Arel functions" do
27
- compile(@price + 42).must_be_like %{("products"."price" + 42)}
28
- compile(@table[:id] + @table[:pas_en_base])
40
+ _(compile(@price + 42)).must_be_like %{("products"."price" + 42)}
41
+ _(compile(@table[:id] + @table[:pas_en_base]))
29
42
  .must_be_like %{("users"."id" + "users"."pas_en_base")}
30
- compile(@table[:pas_en_base] + @table[:id])
43
+ _(compile(@table[:pas_en_base] + @table[:id]))
31
44
  .must_be_like %{("users"."pas_en_base" + "users"."id")}
32
- compile(@table[:id] - @table[:pas_en_base])
45
+ _(compile(@table[:id] - @table[:pas_en_base]))
33
46
  .must_be_like %{("users"."id" - "users"."pas_en_base")}
34
- compile(@table[:pas_en_base] - @table[:id])
47
+ _(compile(@table[:pas_en_base] - @table[:id]))
35
48
  .must_be_like %{("users"."pas_en_base" - "users"."id")}
36
- compile(@table[:id] * @table[:pas_en_base])
49
+ _(compile(@table[:id] * @table[:pas_en_base]))
37
50
  .must_be_like %{"users"."id" * "users"."pas_en_base"}
38
- compile(@table[:pas_en_base] * @table[:id])
51
+ _(compile(@table[:pas_en_base] * @table[:id]))
39
52
  .must_be_like %{"users"."pas_en_base" * "users"."id"}
40
53
  end
41
54
 
42
55
  it "should return right calculations on numbers" do
43
56
  #puts (@price.abs + 42).inspect
44
- compile(@price.abs + 42).must_be_like %{(ABS("products"."price") + 42)}
45
- compile(@price.ceil + 42).must_be_like %{(CEIL("products"."price") + 42)}
46
- compile(@price.floor + 42).must_be_like %{(FLOOR("products"."price") + 42)}
47
- compile(@price.log10 + 42).must_be_like %{(LOG10("products"."price") + 42)}
48
- compile(@price.power(42) + 42).must_be_like %{(POW("products"."price", 42) + 42)}
49
- compile(@price.pow(42) + 42).must_be_like %{(POW("products"."price", 42) + 42)}
50
- compile(@price.ceil + @price.floor).must_be_like %{(CEIL("products"."price") + FLOOR("products"."price"))}
51
- compile((@price.ceil + @price.floor).abs).must_be_like %{ABS((CEIL("products"."price") + FLOOR("products"."price")))}
52
- compile(@price.round + 42).must_be_like %{(ROUND("products"."price") + 42)}
53
- compile(@price.round(2) + 42).must_be_like %{(ROUND("products"."price", 2) + 42)}
54
- compile(Arel.rand + 42).must_be_like %{(RAND() + 42)}
55
- compile(@price.sum + 42).must_be_like %{(SUM("products"."price") + 42)}
56
- compile((@price + 42).sum).must_be_like %{SUM(("products"."price" + 42))}
57
- compile((@price + 42).average).must_be_like %{AVG(("products"."price" + 42))}
58
- compile((Arel.rand * 9).round + 42).must_be_like %{(ROUND(RAND() * 9) + 42)}
59
- compile((Arel.rand * @price).round(2) + @price).must_be_like %{(ROUND(RAND() * "products"."price", 2) + "products"."price")}
60
-
61
- compile(@price.std + 42).must_be_like %{(STD("products"."price") + 42)}
62
- compile(@price.variance + 42).must_be_like %{(VARIANCE("products"."price") + 42)}
63
-
64
- compile(@price.coalesce(0) - 42).must_be_like %{(COALESCE("products"."price", 0) - 42)}
65
- compile(@price.sum - 42).must_be_like %{(SUM("products"."price") - 42)}
66
- compile(@price.std - 42).must_be_like %{(STD("products"."price") - 42)}
67
- compile(@price.variance - 42).must_be_like %{(VARIANCE("products"."price") - 42)}
68
-
69
- compile(@price * 42.0).must_be_like %{"products"."price" * 42.0}
70
- compile(@price / 42.0).must_be_like %{"products"."price" / 42.0}
57
+ _(compile(@price.abs + 42)).must_be_like %{(ABS("products"."price") + 42)}
58
+ _(compile(@price.ceil + 42)).must_be_like %{(CEIL("products"."price") + 42)}
59
+ _(compile(@price.floor + 42)).must_be_like %{(FLOOR("products"."price") + 42)}
60
+ _(compile(@price.log10 + 42)).must_be_like %{(LOG10("products"."price") + 42)}
61
+ _(compile(@price.power(42) + 42)).must_be_like %{(POW("products"."price", 42) + 42)}
62
+ _(compile(@price.pow(42) + 42)).must_be_like %{(POW("products"."price", 42) + 42)}
63
+ _(compile(@price.ceil + @price.floor)).must_be_like %{(CEIL("products"."price") + FLOOR("products"."price"))}
64
+ _(compile((@price.ceil + @price.floor).abs)).must_be_like %{ABS((CEIL("products"."price") + FLOOR("products"."price")))}
65
+ _(compile(@price.round + 42)).must_be_like %{(ROUND("products"."price") + 42)}
66
+ _(compile(@price.round(2) + 42)).must_be_like %{(ROUND("products"."price", 2) + 42)}
67
+ _(compile(Arel.rand + 42)).must_be_like %{(RAND() + 42)}
68
+ _(compile(@price.sum + 42)).must_be_like %{(SUM("products"."price") + 42)}
69
+ _(compile((@price + 42).sum)).must_be_like %{SUM(("products"."price" + 42))}
70
+ _(compile((@price + 42).average)).must_be_like %{AVG(("products"."price" + 42))}
71
+ _(compile((Arel.rand * 9).round + 42)).must_be_like %{(ROUND(RAND() * 9) + 42)}
72
+ _(compile((Arel.rand * @price).round(2) + @price)).must_be_like %{(ROUND(RAND() * "products"."price", 2) + "products"."price")}
73
+
74
+ _(compile(@price.std + 42)).must_be_like %{(STD("products"."price") + 42)}
75
+ _(compile(@price.variance + 42)).must_be_like %{(VARIANCE("products"."price") + 42)}
76
+
77
+ _(compile(@price.coalesce(0) - 42)).must_be_like %{(COALESCE("products"."price", 0) - 42)}
78
+ _(compile(@price.sum - 42)).must_be_like %{(SUM("products"."price") - 42)}
79
+ _(compile(@price.std - 42)).must_be_like %{(STD("products"."price") - 42)}
80
+ _(compile(@price.variance - 42)).must_be_like %{(VARIANCE("products"."price") - 42)}
81
+
82
+ _(compile(@price * 42.0)).must_be_like %{"products"."price" * 42.0}
83
+ _(compile(@price / 42.0)).must_be_like %{"products"."price" / 42.0}
71
84
 
72
85
  fake_table = Arel::Table.new('fake_tables')
73
86
 
74
- compile(fake_table[:fake_att] - 42).must_be_like %{("fake_tables"."fake_att" - 42)}
75
- compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
87
+ _(compile(fake_table[:fake_att] - 42)).must_be_like %{("fake_tables"."fake_att" - 42)}
88
+ _(compile(fake_table[:fake_att].coalesce(0) - 42)).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
76
89
  end
77
90
 
78
91
  # String Functions
79
92
  it "should accept functions on strings" do
80
93
  c = @table[:name]
81
- compile(c + 'test').must_be_like %{CONCAT(\"users\".\"name\", 'test')}
82
- compile(c.length).must_be_like %{LENGTH("users"."name")}
94
+ _(compile(c + 'test')).must_be_like %{CONCAT(\"users\".\"name\", 'test')}
95
+ _(compile(c.length)).must_be_like %{LENGTH("users"."name")}
83
96
  #puts (c.length.round + 42).inspect
84
- compile(c.length.round + 42).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
85
- compile(c.locate('test')).must_be_like %{LOCATE('test', "users"."name")}
86
- compile(c & 42).must_be_like %{FIND_IN_SET(42, "users"."name")}
87
-
88
- compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
89
- compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
90
- compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
91
- compile(c =~ /\Atest\z/).must_be_like %{"users"."name" REGEXP '^test$'}
92
- compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
93
- compile(c.imatches('%test%')).must_be_like %{"users"."name" ILIKE '%test%'}
94
- compile(c.imatches_any(['%test%', 't2'])).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
95
- compile(c.idoes_not_match('%test%')).must_be_like %{"users"."name" NOT ILIKE '%test%'}
96
-
97
- compile(c.substring(1)).must_be_like %{SUBSTRING("users"."name", 1)}
98
- compile(c + '0').must_be_like %{CONCAT("users"."name", '0')}
99
- compile(c.substring(1) + '0').must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
100
- compile(c.substring(1) + c.substring(2)).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
101
- compile(c.concat(c).concat(c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
102
- compile(c + c + c).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
97
+ _(compile(c.length.round + 42)).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
98
+ _(compile(c.locate('test'))).must_be_like %{LOCATE('test', "users"."name")}
99
+ _(compile(c & 42)).must_be_like %{FIND_IN_SET(42, "users"."name")}
100
+
101
+ _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
102
+ _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
103
+ _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
104
+ _(compile(c =~ /\Atest\z/)).must_be_like %{"users"."name" REGEXP '^test$'}
105
+ _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
106
+ _(compile(c.imatches('%test%'))).must_be_like %{"users"."name" ILIKE '%test%'}
107
+ _(compile(c.imatches_any(['%test%', 't2']))).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
108
+ _(compile(c.idoes_not_match('%test%'))).must_be_like %{"users"."name" NOT ILIKE '%test%'}
109
+
110
+ _(compile(c.substring(1))).must_be_like %{SUBSTRING("users"."name", 1)}
111
+ _(compile(c + '0')).must_be_like %{CONCAT("users"."name", '0')}
112
+ _(compile(c.substring(1) + '0')).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
113
+ _(compile(c.substring(1) + c.substring(2))).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
114
+ _(compile(c.concat(c).concat(c))).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
115
+ _(compile(c + c + c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
103
116
 
104
117
  # some optimization on concat
105
- compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
106
- compile(Arel::Nodes.build_quoted('test') + ' chain').must_be_like %{'test chain'}
107
- compile(c + '' + c).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
118
+ _(compile(c + 'test' + ' chain')).must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
119
+ _(compile(Arel::Nodes.build_quoted('test') + ' chain')).must_be_like %{'test chain'}
120
+ _(compile(c + '' + c)).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
108
121
 
109
- compile(c.md5).must_be_like %{MD5(\"users\".\"name\")}
122
+ _(compile(c.md5)).must_be_like %{MD5(\"users\".\"name\")}
110
123
  end
111
124
 
112
125
  # Comparators
113
126
 
114
127
  it "should accept comparators on integers" do
115
- compile(@table[:id] == 42).must_match %{"users"."id" = 42}
116
- compile(@table[:id] == @table[:id]).must_be_like %{"users"."id" = "users"."id"}
117
- compile(@table[:id] != 42).must_match %{"users"."id" != 42}
118
- compile(@table[:id] > 42).must_match %{"users"."id" > 42}
119
- compile(@table[:id] >= 42).must_match %{"users"."id" >= 42}
120
- compile(@table[:id] >= @table[:id]).must_be_like %{"users"."id" >= "users"."id"}
121
- compile(@table[:id] < 42).must_match %{"users"."id" < 42}
122
- compile(@table[:id] <= 42).must_match %{"users"."id" <= 42}
123
- compile((@table[:id] <= 42).as('new_name')).must_match %{("users"."id" <= 42) AS new_name}
124
- puts @table[:id].count.class
125
- compile(@table[:id].count.eq 42).must_match %{COUNT("users"."id") = 42}
126
- #compile(@table[:id].count == 42).must_match %{COUNT("users"."id") = 42} # TODO
127
- #compile(@table[:id].count != 42).must_match %{COUNT("users"."id") != 42}
128
- #compile(@table[:id].count >= 42).must_match %{COUNT("users"."id") >= 42}
128
+ _(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
129
+ _(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
130
+ _(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
131
+ _(compile(@table[:id] > 42)).must_match %{"users"."id" > 42}
132
+ _(compile(@table[:id] >= 42)).must_match %{"users"."id" >= 42}
133
+ _(compile(@table[:id] >= @table[:id])).must_be_like %{"users"."id" >= "users"."id"}
134
+ _(compile(@table[:id] < 42)).must_match %{"users"."id" < 42}
135
+ _(compile(@table[:id] <= 42)).must_match %{"users"."id" <= 42}
136
+ _(compile((@table[:id] <= 42).as('new_name'))).must_match %{("users"."id" <= 42) AS new_name}
137
+ _(compile(@table[:id].count.eq 42)).must_match %{COUNT("users"."id") = 42}
138
+ #_(compile(@table[:id].count == 42)).must_match %{COUNT("users"."id") = 42} # TODO
139
+ #_(compile(@table[:id].count != 42)).must_match %{COUNT("users"."id") != 42}
140
+ #_(compile(@table[:id].count >= 42)).must_match %{COUNT("users"."id") >= 42}
129
141
  end
130
142
 
131
143
  it "should accept comparators on dates" do
132
144
  c = @table[:created_at]
133
145
  u = @table[:updated_at]
134
- compile(c > @date).must_be_like %{"users"."created_at" > '2016-03-31'}
135
- compile(u >= @date).must_be_like %{"users"."updated_at" >= '2016-03-31'}
136
- compile(c < u).must_be_like %{"users"."created_at" < "users"."updated_at"}
146
+ _(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
147
+ _(compile(u >= @date)).must_be_like %{"users"."updated_at" >= '2016-03-31'}
148
+ _(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
137
149
  end
138
150
 
139
151
  it "should accept comparators on strings" do
140
152
  c = @table[:name]
141
- compile(c == 'test').must_be_like %{"users"."name" = 'test'}
142
- compile(c != 'test').must_be_like %{"users"."name" != 'test'}
143
- compile(c > 'test').must_be_like %{"users"."name" > 'test'}
144
- compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
145
- compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
146
- compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
147
- compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
148
- compile(c.imatches('%test%')).must_be_like %{"users"."name" ILIKE '%test%'}
149
- compile(c.imatches_any(['%test%', 't2'])).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
150
- compile(c.idoes_not_match('%test%')).must_be_like %{"users"."name" NOT ILIKE '%test%'}
153
+ _(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
154
+ _(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
155
+ _(compile(c > 'test')).must_be_like %{"users"."name" > 'test'}
156
+ _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
157
+ _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
158
+ _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
159
+ _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
160
+ _(compile(c.imatches('%test%'))).must_be_like %{"users"."name" ILIKE '%test%'}
161
+ _(compile(c.imatches_any(['%test%', 't2']))).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
162
+ _(compile(c.idoes_not_match('%test%'))).must_be_like %{"users"."name" NOT ILIKE '%test%'}
151
163
  end
152
164
 
153
165
  # Maths
154
166
  # DateDiff
155
167
  it "should diff date col and date" do
156
- compile(@table[:created_at] - Date.new(2016, 3, 31)).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
168
+ _(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
157
169
  end
158
170
 
159
171
  it "should diff date col and datetime col" do
160
- compile(@table[:created_at] - @table[:updated_at]).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
172
+ _(compile(@table[:created_at] - @table[:updated_at])).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
161
173
  end
162
174
 
163
175
  it "should diff date col and datetime col with AS" do
164
- sql = compile((@table[:updated_at] - @table[:created_at]).as('new_name'))
165
- sql.must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
176
+ _(compile((@table[:updated_at] - @table[:created_at]).as('new_name')))
177
+ .must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
166
178
  end
167
179
 
168
180
  it "should diff between time values" do
169
181
  d2 = Time.new(2015,6,1)
170
182
  d1 = DateTime.new(2015,6,2)
171
- sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, d2]))
172
- sql.must_match("DATEDIFF('2015-06-02', '2015-06-01')")
183
+ _(compile(ArelExtensions::Nodes::DateDiff.new([d1, d2])))
184
+ .must_match("DATEDIFF('2015-06-02', '2015-06-01')")
173
185
  end
174
186
 
175
187
  it "should diff between time values and time col" do
176
188
  d1 = DateTime.new(2015,6,2)
177
- sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]]))
178
- sql.must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
189
+ _(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
190
+ .must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
179
191
  end
180
192
 
181
193
  it "should diff between date col and duration" do
182
194
  d1 = 10
183
195
  d2 = -10
184
- compile(@table[:created_at] - d1).
185
- must_match %{DATE_SUB("users"."created_at", 10)}
186
- compile(@table[:created_at] - d2).
187
- must_match %{DATE_SUB("users"."created_at", -10)}
196
+ _(compile(@table[:created_at] - d1))
197
+ .must_match %{DATE_SUB("users"."created_at", 10)}
198
+ _(compile(@table[:created_at] - d2))
199
+ .must_match %{DATE_SUB("users"."created_at", -10)}
188
200
  end
189
201
 
190
202
  it "should accept operators on dates with numbers" do
191
203
  c = @table[:created_at]
192
204
  #u = @table[:updated_at]
193
- compile(c - 42).must_be_like %{DATE_SUB("users"."created_at", 42)}
194
- compile(c - @table[:id]).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
205
+ _(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
206
+ _(compile(c - @table[:id])).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
195
207
  end
196
208
 
197
209
  # Maths on sums
198
210
  it "should accept math operators on anything" do
199
211
  c = @table[:name]
200
- (c == 'test').to_sql.must_be_like %{"users"."name" = 'test'}
201
- (c != 'test').to_sql.must_be_like %{"users"."name" != 'test'}
202
- (c > 'test').to_sql.must_be_like %{"users"."name" > 'test'}
203
- compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
204
- compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
205
- compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
206
- compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
212
+ _((c == 'test').to_sql)
213
+ .must_be_like %{"users"."name" = 'test'}
214
+ _((c != 'test').to_sql)
215
+ .must_be_like %{"users"."name" != 'test'}
216
+ _((c > 'test').to_sql)
217
+ .must_be_like %{"users"."name" > 'test'}
218
+ _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
219
+ _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
220
+ _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
221
+ _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
207
222
  end
208
223
 
209
224
  it "should manage complex formulas" do
210
225
  c = @table[:name]
211
- compile(
212
- (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
213
- ).must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
226
+ _(compile(
227
+ (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
228
+ ))
229
+ .must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
214
230
  end
215
231
 
216
232
  it "should accept aggregator like GROUP CONCAT" do
217
- @table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql
233
+ _(@table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql)
218
234
  .must_be_like %{SELECT GROUP_CONCAT("users"."first_name") FROM "users" GROUP BY "users"."last_name"}
219
- @table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql
235
+ _(@table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql)
220
236
  .must_be_like %{SELECT GROUP_CONCAT("users"."first_name", '++') FROM "users" GROUP BY "users"."last_name"}
221
237
  end
222
238
 
223
239
  # Unions
224
240
  it "should accept union operators on queries and union nodes" do
225
241
  c = @table.project(@table[:name])
226
- compile(c + c)
242
+ _(compile(c + c))
227
243
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
228
- (c + c).to_sql
244
+ _((c + c).to_sql)
229
245
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
230
- (c + (c + c)).to_sql
246
+ _((c + (c + c)).to_sql)
231
247
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
232
- ((c + c) + c).to_sql
248
+ _(((c + c) + c).to_sql)
233
249
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
234
- (c + c + c).to_sql
250
+ _((c + c + c).to_sql)
235
251
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
236
- (c + c).as('union_table').to_sql
252
+ _((c + c).as('union_table').to_sql)
237
253
  .must_be_like %{((SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")) union_table}
238
254
  c = @table.project(@table[:name])
239
- compile(c.union_all(c))
255
+ _(compile(c.union_all(c)))
240
256
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
241
- (c.union_all(c)).to_sql
257
+ _((c.union_all(c)).to_sql)
242
258
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
243
- (c.union_all(c.union_all(c))).to_sql
259
+ _((c.union_all(c.union_all(c))).to_sql)
244
260
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
245
- ((c.union_all(c)).union_all(c)).to_sql
261
+ _(((c.union_all(c)).union_all(c)).to_sql)
246
262
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
247
- (c.union_all(c).union_all(c)).to_sql
263
+ _((c.union_all(c).union_all(c)).to_sql)
248
264
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
249
- (c.union_all(c)).as('union_table').to_sql
265
+ _((c.union_all(c)).as('union_table').to_sql)
250
266
  .must_be_like %{((SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")) union_table}
251
267
  end
252
268
 
253
269
  # Case
254
270
  it "should accept case clause" do
255
- @table[:name].when("smith").then("cool").when("doe").then("fine").else("uncool").to_sql
271
+ _(@table[:name].when("smith").then("cool").when("doe").then("fine").else("uncool").to_sql)
256
272
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' WHEN 'doe' THEN 'fine' ELSE 'uncool' END}
257
- @table[:name].when("smith").then(1).when("doe").then(2).else(0).to_sql
273
+ _(@table[:name].when("smith").then(1).when("doe").then(2).else(0).to_sql)
258
274
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
259
- ArelExtensions::Nodes::Case.new.when(@table[:name] == "smith").then(1).when(@table[:name] == "doe").then(2).else(0).to_sql
275
+ _(ArelExtensions::Nodes::Case.new.when(@table[:name] == "smith").then(1).when(@table[:name] == "doe").then(2).else(0).to_sql)
260
276
  .must_be_like %{CASE WHEN "users"."name" = 'smith' THEN 1 WHEN "users"."name" = 'doe' THEN 2 ELSE 0 END}
261
- ArelExtensions::Nodes::Case.new(@table[:name]).when("smith").then(1).when("doe").then(2).else(0).to_sql
277
+ _(ArelExtensions::Nodes::Case.new(@table[:name]).when("smith").then(1).when("doe").then(2).else(0).to_sql)
262
278
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
263
- @table[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql
279
+ _(@table[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql)
264
280
  .must_be_like %{SUM(CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)}
265
- @table[:name].when("smith").then("cool").else("uncool").matches('value',false).to_sql
281
+ _(@table[:name].when("smith").then("cool").else("uncool").matches('value',false).to_sql)
266
282
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END LIKE 'value'}
267
- @table[:name].when("smith").then("cool").else("uncool").imatches('value',false).to_sql
283
+ _(@table[:name].when("smith").then("cool").else("uncool").imatches('value',false).to_sql)
268
284
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
269
285
  end
270
286
 
271
287
  it "should be possible to use as on anything" do
272
- compile(@table[:name].as('alias')).must_be_like %{"users"."name" AS alias}
273
- compile(@table[:name].concat(' test').as('alias')).must_be_like %{CONCAT("users"."name", ' test') AS alias}
274
- compile((@table[:name] + ' test').as('alias')).must_be_like %{CONCAT("users"."name", ' test') AS alias}
275
- compile((@table[:age] + 42).as('alias')).must_be_like %{("users"."age" + 42) AS alias}
276
- compile(@table[:name].coalesce('').as('alias')).must_be_like %{COALESCE("users"."name", '') AS alias}
277
- compile(Arel::Nodes.build_quoted('test').as('alias')).must_be_like %{'test' AS alias}
278
- compile(@table.project(@table[:name]).as('alias')).must_be_like %{(SELECT "users"."name" FROM "users") alias}
279
- compile(@table[:name].when("smith").then("cool").else("uncool").as('alias')).
280
- must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias}
288
+ _(compile(@table[:name].as('alias'))).must_be_like %{"users"."name" AS alias}
289
+ _(compile(@table[:name].concat(' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
290
+ _(compile((@table[:name] + ' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
291
+ _(compile((@table[:age] + 42).as('alias'))).must_be_like %{("users"."age" + 42) AS alias}
292
+ _(compile(@table[:name].coalesce('').as('alias'))).must_be_like %{COALESCE("users"."name", '') AS alias}
293
+ _(compile(Arel::Nodes.build_quoted('test').as('alias'))).must_be_like %{'test' AS alias}
294
+ _(compile(@table.project(@table[:name]).as('alias'))).must_be_like %{(SELECT "users"."name" FROM "users") alias}
295
+ _(compile(@table[:name].when("smith").then("cool").else("uncool").as('alias')))
296
+ .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias}
281
297
  end
282
298
 
283
299
  it "should accept comparators on functions" do
284
300
  c = @table[:name]
285
- compile(c.soundex == 'test').must_be_like %{SOUNDEX("users"."name") = 'test'}
286
- compile(c.soundex != 'test').must_be_like %{SOUNDEX("users"."name") != 'test'}
287
- compile(c.length >= 0 ).must_be_like %{LENGTH("users"."name") >= 0}
301
+ _(compile(c.soundex == 'test')).must_be_like %{SOUNDEX("users"."name") = 'test'}
302
+ _(compile(c.soundex != 'test')).must_be_like %{SOUNDEX("users"."name") != 'test'}
303
+ _(compile(c.length >= 0 )).must_be_like %{LENGTH("users"."name") >= 0}
288
304
  end
289
305
 
290
306
  it "should accept in on select statement" do
291
307
  c = @table[:name]
292
- compile(c.in(@table.project(@table[:name])))
308
+ _(compile(c.in(@table.project(@table[:name]))))
293
309
  .must_be_like %{"users"."name" IN (SELECT "users"."name" FROM "users")}
294
310
  end
295
311
 
296
312
  it "should accept coalesce function properly even on none actual tables and attributes" do
297
313
  fake_at = Arel::Table.new('fake_table')
298
- compile(fake_at['fake_attribute'].coalesce('other_value'))
314
+ _(compile(fake_at['fake_attribute'].coalesce('other_value')))
299
315
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value')}
300
- compile(fake_at['fake_attribute'].coalesce('other_value1','other_value2'))
316
+ _(compile(fake_at['fake_attribute'].coalesce('other_value1','other_value2')))
301
317
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value1', 'other_value2')}
302
- compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2'))
318
+ _(compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2')))
303
319
  .must_be_like %{COALESCE(COALESCE("fake_table"."fake_attribute", 'other_value1'), 'other_value2')}
304
- compile(fake_at['fake_attribute'].coalesce('other_value').matches('truc'))
320
+ _(compile(fake_at['fake_attribute'].coalesce('other_value').matches('truc')))
305
321
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') LIKE 'truc'}
306
- compile(fake_at['fake_attribute'].coalesce('other_value').imatches('truc'))
322
+ _(compile(fake_at['fake_attribute'].coalesce('other_value').imatches('truc')))
307
323
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') ILIKE 'truc'}
308
324
  end
309
325
 
310
326
  it "should be possible to cast nodes types" do
311
- compile(@table[:id].cast('char'))
327
+ _(compile(@table[:id].cast('char')))
312
328
  .must_be_like %{CAST("users"."id" AS char)}
313
- compile(@table[:id].coalesce(' ').cast('char'))
329
+ _(compile(@table[:id].coalesce(' ').cast('char')))
314
330
  .must_be_like %{CAST(COALESCE("users"."id", ' ') AS char)}
315
- compile(@table[:id].coalesce(' ').cast(:string))
331
+ _(compile(@table[:id].coalesce(' ').cast(:string)))
316
332
  .must_be_like %{CAST(COALESCE("users"."id", ' ') AS char)}
317
- compile(@table[:id].cast(:string).coalesce(' '))
333
+ _(compile(@table[:id].cast(:string).coalesce(' ')))
318
334
  .must_be_like %{COALESCE(CAST(\"users\".\"id\" AS char), ' ')}
319
- compile(@table[:id].cast('char') + ' ')
335
+ _(compile(@table[:id].cast('char') + ' '))
320
336
  .must_be_like %{CONCAT(CAST("users"."id" AS char), ' ')}
321
- compile(@table[:id].cast('int') + 2)
337
+ _(compile(@table[:id].cast('int') + 2))
322
338
  .must_be_like %{(CAST("users"."id" AS int) + 2)}
323
339
  end
324
340
 
325
- it "should be possible to have nil element in the function NIL" do
326
- compile(@table[:id].in(nil))
327
- .must_be_like %{ISNULL("users"."id")}
328
- compile(@table[:id].in([nil]))
329
- .must_be_like %{ISNULL("users"."id")}
330
- compile(@table[:id].in([nil,1]))
331
- .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
332
- compile(@table[:id].in([nil,1,2]))
333
- .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
334
- compile(@table[:id].in(1))
335
- .must_be_like %{"users"."id" IN (1)}
336
- compile(@table[:id].in([1]))
337
- .must_be_like %{"users"."id" IN (1)}
338
- compile(@table[:id].in([1,2]))
339
- .must_be_like %{"users"."id" IN (1, 2)}
341
+ describe "the function in" do
342
+
343
+ it "should be possible to have nil element in the function IN" do
344
+ _(compile(@table[:id].in(nil)))
345
+ .must_be_like %{ISNULL("users"."id")}
346
+ _(compile(@table[:id].in([nil])))
347
+ .must_be_like %{ISNULL("users"."id")}
348
+ _(compile(@table[:id].in([nil,1])))
349
+ .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
350
+ _(compile(@table[:id].in([nil,1,2])))
351
+ .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
352
+ _(compile(@table[:id].in(1)))
353
+ .must_be_like %{"users"."id" IN (1)}
354
+ _(compile(@table[:id].in([1])))
355
+ .must_be_like %{"users"."id" = 1}
356
+ _(compile(@table[:id].in([1,2])))
357
+ .must_be_like %{"users"."id" IN (1, 2)}
358
+ _(compile(@table[:id].in([])))
359
+ .must_be_like %{1 = 0}
360
+ end
361
+
362
+ it "should be possible to correctly use a Range on an IN" do
363
+ _(compile(@table[:id].in(1..4)))
364
+ .must_be_like %{"users"."id" BETWEEN (1) AND (4)}
365
+ _(compile(@table[:created_at].in(Date.new(2016, 3, 31) .. Date.new(2017, 3, 31))))
366
+ .must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
367
+ end
368
+
369
+ it "should be possible to use a list of values and ranges on an IN" do
370
+ _(compile(@table[:id].in [1..10, 20, 30, 40..50]))
371
+ .must_be_like %{("users"."id" IN (20, 30)) OR ("users"."id" BETWEEN (1) AND (10)) OR ("users"."id" BETWEEN (40) AND (50))}
372
+ _(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))))
373
+ .must_be_like %{ ("users"."created_at" IN ('2016-01-01', '2018-01-01'))
374
+ OR ("users"."created_at" BETWEEN ('2016-02-01') AND ('2016-02-28'))
375
+ OR ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
376
+ end
377
+
378
+ it "should respecting Grouping" do
379
+ g = ->(*v) { Arel::Nodes::Grouping.new(v) }
380
+ _(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
381
+ .must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
382
+ _(compile(g[@table[:id], @table[:age]].in [g[1, 42], g[2, 51]]))
383
+ .must_be_like %{("users"."id", "users"."age") IN ((1, 42), (2, 51))}
384
+
385
+ _(compile(g[@table[:id], @table[:age]].in(g[1, 42], g[2, 51])))
386
+ .must_be_like %{("users"."id", "users"."age") IN ((1, 42), (2, 51))}
387
+ end
388
+
389
+
340
390
  end
341
391
 
342
- it "should be possible to correctly use a Range on an IN" do
343
- compile(@table[:id].in(1..4))
344
- .must_be_like %{"users"."id" BETWEEN (1) AND (4)}
345
- compile(@table[:created_at].in(@date .. Date.new(2017, 3, 31))) # @date = Date.new(2016, 3, 31)
346
- .must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
392
+ describe "the function not_in" do
393
+
394
+ it "should be possible to have nil element in the function IN" do
395
+ _(compile(@table[:id].not_in nil))
396
+ .must_be_like %{NOT ISNULL("users"."id")}
397
+ _(compile(@table[:id].not_in [nil]))
398
+ .must_be_like %{NOT ISNULL("users"."id")}
399
+ _(compile(@table[:id].not_in [nil,1]))
400
+ .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" != 1)}
401
+ _(compile(@table[:id].not_in [nil,1,2]))
402
+ .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" NOT IN (1, 2))}
403
+ _(compile(@table[:id].not_in 1))
404
+ .must_be_like %{"users"."id" NOT IN (1)}
405
+ _(compile(@table[:id].not_in [1]))
406
+ .must_be_like %{"users"."id" != 1}
407
+ _(compile(@table[:id].not_in [1,2]))
408
+ .must_be_like %{"users"."id" NOT IN (1, 2)}
409
+ _(compile(@table[:id].not_in []))
410
+ .must_be_like %{1 = 1}
411
+ end
412
+
413
+ it "should be possible to correctly use a Range on an IN" do
414
+ # FIXME: Should use NOT BETWEEN
415
+ _(compile(@table[:id].not_in 1..4))
416
+ .must_be_like %{NOT ("users"."id" BETWEEN (1) AND (4))}
417
+ # FIXME: Should use NOT BETWEEN
418
+ _(compile(@table[:created_at].not_in Date.new(2016, 3, 31) .. Date.new(2017, 3, 31)))
419
+ .must_be_like %{NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
420
+ end
421
+
422
+ it "should be possible to use a list of values and ranges on an IN" do
423
+ _(compile(@table[:id].not_in [1..10, 20, 30, 40..50]))
424
+ .must_be_like %{ ("users"."id" NOT IN (20, 30))
425
+ AND (NOT ("users"."id" BETWEEN (1) AND (10)))
426
+ AND (NOT ("users"."id" BETWEEN (40) AND (50)))}
427
+ _(compile(@table[:created_at].not_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)))
428
+ .must_be_like %{ ("users"."created_at" NOT IN ('2016-01-01', '2018-01-01'))
429
+ AND (NOT ("users"."created_at" BETWEEN ('2016-02-01') AND ('2016-02-28')))
430
+ AND (NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')))}
431
+ end
432
+
347
433
  end
348
434
 
349
435
  it "should be possible to add and substract as much as we want" do
350
436
  c = @table[:name]
351
- compile(c.locate('test')+1)
437
+ _(compile(c.locate('test')+1))
352
438
  .must_be_like %{(LOCATE('test', "users"."name") + 1)}
353
- compile(c.locate('test')-1)
439
+ _(compile(c.locate('test')-1))
354
440
  .must_be_like %{(LOCATE('test', "users"."name") - 1)}
355
- compile(c.locate('test')+c.locate('test'))
441
+ _(compile(c.locate('test')+c.locate('test')))
356
442
  .must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
357
- compile(c.locate('test')+1+c.locate('test')-1 + 1)
443
+ _(compile(c.locate('test')+1+c.locate('test')-1 + 1))
358
444
  .must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
359
445
  end
360
446
 
361
447
  it "should be possible to add and substract on some nodes" do
362
448
  c = @table[:name]
363
- compile(c.when(0,0).else(42) + 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
364
- compile(c.when(0,0).else(42) - 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
365
- compile(c.when(0,"0").else("42") + "42").must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
449
+ _(compile(c.when(0,0).else(42) + 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
450
+ _(compile(c.when(0,0).else(42) - 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
451
+ _(compile(c.when(0,"0").else("42") + "42")).must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
366
452
  end
367
453
 
368
454
  it "should be possible to desc and asc on functions" do
369
455
  c = @table[:name]
370
- compile(c.asc)
456
+ _(compile(c.asc))
371
457
  .must_be_like %{"users"."name" ASC}
372
- compile(c.substring(2).asc)
458
+ _(compile(c.substring(2).asc))
373
459
  .must_be_like %{SUBSTRING("users"."name", 2) ASC}
374
- compile(c.substring(2).desc)
460
+ _(compile(c.substring(2).desc))
375
461
  .must_be_like %{SUBSTRING("users"."name", 2) DESC}
376
- compile((c.locate('test')+1).asc)
462
+ _(compile((c.locate('test')+1).asc))
377
463
  .must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
378
464
  end
379
465
 
380
- it "should be possible to have multiple arguments on an OR or an AND node" do
381
- c = @table[:id]
382
- compile((c == 1).and(c == 2, c == 3)).
383
- must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
384
- compile((c == 1).and([c == 2, c == 3])).
385
- must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
386
- compile((c == 1).or(c == 2, c == 3)).
387
- must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
388
- compile((c == 1).or([c == 2, c == 3])).
389
- must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
466
+ it "should be possible to call Table function on TableAlias" do
467
+ t = @table
468
+ a = t.alias("aliased_users")
469
+ _(compile(a.join(t).join_sources))
470
+ .must_be_like %{INNER JOIN \"users\"}
471
+ end
472
+
473
+ describe "logical functions" do
474
+
475
+ it "should know about truth" do
476
+ _(compile(Arel.false))
477
+ .must_be_like %{1 = 0}
478
+
479
+ _(compile(Arel::true))
480
+ .must_be_like %{1 = 1}
481
+ end
482
+
483
+ it "boolean nodes should be variadic" do
484
+ c = @table[:id]
485
+
486
+ _(compile(Arel::Nodes::And.new))
487
+ .must_be_like %{1 = 1}
488
+ _(compile(Arel::Nodes::And.new(c == 1)))
489
+ .must_be_like %{"users"."id" = 1}
490
+ _(compile(Arel::Nodes::And.new(c == 1, c == 2)))
491
+ .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2)}
492
+ _(compile(Arel::Nodes::And.new [c == 1, c == 2, c == 3]))
493
+ .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
494
+
495
+
496
+ _(compile(Arel::Nodes::Or.new))
497
+ .must_be_like %{1 = 0}
498
+ _(compile(Arel::Nodes::Or.new(c == 1)))
499
+ .must_be_like %{"users"."id" = 1}
500
+ _(compile(Arel::Nodes::Or.new(c == 1, c == 2)))
501
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2)}
502
+ _(compile(Arel::Nodes::Or.new(c == 1, c == 2, c == 3)))
503
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
504
+ _(compile(Arel::Nodes::Or.new [c == 1, c == 2, c == 3]))
505
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
506
+ end
507
+
508
+ it "should know trivial identities" do
509
+ skip "For future optimization"
510
+ c = @table[:id]
511
+ _(compile(Arel::Nodes::And.new(Arel.true, c == 1)))
512
+ .must_be_like %{"users"."id" = 1}
513
+ _(compile(Arel::Nodes::And.new(Arel.false, c == 1)))
514
+ .must_be_like %{1 = 0}
515
+ _(compile(Arel::Nodes::And.new(c == 1, c == 1)))
516
+ .must_be_like %{"users"."id" = 1}
517
+
518
+ _(compile(Arel::Nodes::Or.new(Arel.true, c == 1)))
519
+ .must_be_like %{1 = 1}
520
+ _(compile(Arel::Nodes::Or.new(Arel.false, c == 1)))
521
+ .must_be_like %{"users"."id" = 1}
522
+ _(compile(Arel::Nodes::Or.new(c == 1, c == 1)))
523
+ .must_be_like %{"users"."id" = 1}
524
+ end
525
+
526
+ it "should be possible to have multiple arguments on an OR or an AND node" do
527
+ c = @table[:id]
528
+ _(compile((c == 1).and))
529
+ .must_be_like %{"users"."id" = 1}
530
+
531
+ _(compile((c == 1).and(c == 2, c == 3)))
532
+ .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
533
+ _(compile((c == 1).and([c == 2, c == 3])))
534
+ .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
535
+
536
+ _(compile((c == 1).or))
537
+ .must_be_like %{"users"."id" = 1}
538
+
539
+ _(compile((c == 1).or(c == 2, c == 3)))
540
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
541
+ _(compile((c == 1).or([c == 2, c == 3])))
542
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
543
+ end
544
+
545
+ it "should avoid useless nesting" do
546
+ c = @table[:id]
547
+ _(compile(((c == 1).and(c == 2)) .and ((c == 3).and(c == 4))))
548
+ .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3) AND ("users"."id" = 4)}
549
+ _(compile(((c == 1).or(c == 2)) .or ((c == 3).or(c == 4))))
550
+ .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3) OR ("users"."id" = 4)}
551
+
552
+ _(compile(((c == 1).or(c == 2)) .and ((c == 3).or(c == 4))))
553
+ .must_be_like %{(("users"."id" = 1) OR ("users"."id" = 2)) AND (("users"."id" = 3) OR ("users"."id" = 4))}
554
+ _(compile(((c == 1).and(c == 2)) .or ((c == 3).and(c == 4))))
555
+ .must_be_like %{(("users"."id" = 1) AND ("users"."id" = 2)) OR (("users"."id" = 3) AND ("users"."id" = 4))}
556
+ end
557
+
390
558
  end
391
559
 
392
560
  puts "AREL VERSION : " + Arel::VERSION.to_s