arel 3.0.3 → 4.0.0.beta1
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.
- checksums.yaml +7 -0
- data/.travis.yml +2 -2
- data/Gemfile +3 -4
- data/History.txt +0 -51
- data/Manifest.txt +8 -2
- data/README.markdown +1 -1
- data/Rakefile +1 -1
- data/arel.gemspec +21 -29
- data/lib/arel.rb +1 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/nodes/and.rb +10 -0
- data/lib/arel/nodes/binary.rb +11 -0
- data/lib/arel/nodes/extract.rb +11 -0
- data/lib/arel/nodes/false.rb +7 -0
- data/lib/arel/nodes/function.rb +11 -0
- data/lib/arel/nodes/grouping.rb +7 -0
- data/lib/arel/nodes/insert_statement.rb +12 -0
- data/lib/arel/nodes/named_function.rb +9 -0
- data/lib/arel/nodes/select_core.rb +20 -0
- data/lib/arel/nodes/select_statement.rb +15 -1
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/terminal.rb +7 -0
- data/lib/arel/nodes/true.rb +7 -0
- data/lib/arel/nodes/unary.rb +10 -1
- data/lib/arel/nodes/update_statement.rb +15 -0
- data/lib/arel/nodes/window.rb +30 -3
- data/lib/arel/select_manager.rb +4 -0
- data/lib/arel/table.rb +13 -0
- data/lib/arel/tree_manager.rb +0 -2
- data/lib/arel/visitors/bind_visitor.rb +10 -0
- data/lib/arel/visitors/dot.rb +1 -1
- data/lib/arel/visitors/oracle.rb +1 -2
- data/lib/arel/visitors/to_sql.rb +138 -27
- data/test/nodes/test_and.rb +20 -0
- data/test/nodes/test_as.rb +12 -0
- data/test/nodes/test_ascending.rb +10 -0
- data/test/nodes/test_bin.rb +10 -0
- data/test/nodes/test_count.rb +12 -0
- data/test/nodes/test_delete_statement.rb +20 -0
- data/test/nodes/test_descending.rb +10 -0
- data/test/nodes/test_distinct.rb +20 -0
- data/test/nodes/test_equality.rb +10 -0
- data/test/nodes/test_extract.rb +14 -0
- data/test/nodes/test_false.rb +20 -0
- data/test/nodes/test_grouping.rb +25 -0
- data/test/nodes/test_infix_operation.rb +10 -0
- data/test/nodes/test_insert_statement.rb +24 -0
- data/test/nodes/test_named_function.rb +16 -0
- data/test/nodes/test_not.rb +12 -0
- data/test/nodes/test_or.rb +12 -0
- data/test/nodes/test_over.rb +18 -0
- data/test/nodes/test_select_core.rb +38 -0
- data/test/nodes/test_select_statement.rb +36 -0
- data/test/nodes/test_sql_literal.rb +10 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_table_alias.rb +36 -0
- data/test/nodes/test_true.rb +21 -0
- data/test/nodes/test_update_statement.rb +40 -0
- data/test/nodes/test_window.rb +73 -0
- data/test/test_attributes.rb +12 -0
- data/test/test_insert_manager.rb +0 -2
- data/test/test_select_manager.rb +10 -5
- data/test/test_table.rb +24 -0
- data/test/test_update_manager.rb +8 -0
- data/test/visitors/test_bind_visitor.rb +20 -1
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +44 -0
- metadata +76 -86
- data/lib/arel/nodes/ordering.rb +0 -6
- data/lib/arel/relation.rb +0 -6
@@ -31,6 +31,16 @@ module Arel
|
|
31
31
|
node = SqlLiteral.new('foo').eq(1)
|
32
32
|
@visitor.accept(node).must_be_like %{ foo = 1 }
|
33
33
|
end
|
34
|
+
|
35
|
+
it 'is equal with equal contents' do
|
36
|
+
array = [SqlLiteral.new('foo'), SqlLiteral.new('foo')]
|
37
|
+
assert_equal 1, array.uniq.size
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'is not equal with different contents' do
|
41
|
+
array = [SqlLiteral.new('foo'), SqlLiteral.new('bar')]
|
42
|
+
assert_equal 2, array.uniq.size
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
46
|
describe 'grouped "or" equality' do
|
data/test/nodes/test_sum.rb
CHANGED
@@ -9,4 +9,16 @@ describe Arel::Nodes::Sum do
|
|
9
9
|
}
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
describe 'equality' do
|
14
|
+
it 'is equal with equal ivars' do
|
15
|
+
array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo')]
|
16
|
+
assert_equal 1, array.uniq.size
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is not equal with different ivars' do
|
20
|
+
array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo!')]
|
21
|
+
assert_equal 2, array.uniq.size
|
22
|
+
end
|
23
|
+
end
|
12
24
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
describe 'table alias' do
|
7
|
+
it 'has an #engine which delegates to the relation' do
|
8
|
+
engine = 'vroom'
|
9
|
+
relation = Table.new(:users, engine)
|
10
|
+
|
11
|
+
node = TableAlias.new relation, :foo
|
12
|
+
node.engine.must_equal engine
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'equality' do
|
16
|
+
it 'is equal with equal ivars' do
|
17
|
+
relation1 = Table.new(:users, 'vroom')
|
18
|
+
node1 = TableAlias.new relation1, :foo
|
19
|
+
relation2 = Table.new(:users, 'vroom')
|
20
|
+
node2 = TableAlias.new relation2, :foo
|
21
|
+
array = [node1, node2]
|
22
|
+
assert_equal 1, array.uniq.size
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'is not equal with different ivars' do
|
26
|
+
relation1 = Table.new(:users, 'vroom')
|
27
|
+
node1 = TableAlias.new relation1, :foo
|
28
|
+
relation2 = Table.new(:users, 'vroom')
|
29
|
+
node2 = TableAlias.new relation2, :bar
|
30
|
+
array = [node1, node2]
|
31
|
+
assert_equal 2, array.uniq.size
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
describe 'True' do
|
6
|
+
describe 'equality' do
|
7
|
+
it 'is equal to other true nodes' do
|
8
|
+
array = [True.new, True.new]
|
9
|
+
assert_equal 1, array.uniq.size
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is not equal with other nodes' do
|
13
|
+
array = [True.new, Node.new]
|
14
|
+
assert_equal 2, array.uniq.size
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
@@ -15,4 +15,44 @@ describe Arel::Nodes::UpdateStatement do
|
|
15
15
|
dolly.values.wont_be_same_as statement.values
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
describe 'equality' do
|
20
|
+
it 'is equal with equal ivars' do
|
21
|
+
statement1 = Arel::Nodes::UpdateStatement.new
|
22
|
+
statement1.relation = 'zomg'
|
23
|
+
statement1.wheres = 2
|
24
|
+
statement1.values = false
|
25
|
+
statement1.orders = %w[x y z]
|
26
|
+
statement1.limit = 42
|
27
|
+
statement1.key = 'zomg'
|
28
|
+
statement2 = Arel::Nodes::UpdateStatement.new
|
29
|
+
statement2.relation = 'zomg'
|
30
|
+
statement2.wheres = 2
|
31
|
+
statement2.values = false
|
32
|
+
statement2.orders = %w[x y z]
|
33
|
+
statement2.limit = 42
|
34
|
+
statement2.key = 'zomg'
|
35
|
+
array = [statement1, statement2]
|
36
|
+
assert_equal 1, array.uniq.size
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'is not equal with different ivars' do
|
40
|
+
statement1 = Arel::Nodes::UpdateStatement.new
|
41
|
+
statement1.relation = 'zomg'
|
42
|
+
statement1.wheres = 2
|
43
|
+
statement1.values = false
|
44
|
+
statement1.orders = %w[x y z]
|
45
|
+
statement1.limit = 42
|
46
|
+
statement1.key = 'zomg'
|
47
|
+
statement2 = Arel::Nodes::UpdateStatement.new
|
48
|
+
statement2.relation = 'zomg'
|
49
|
+
statement2.wheres = 2
|
50
|
+
statement2.values = false
|
51
|
+
statement2.orders = %w[x y z]
|
52
|
+
statement2.limit = 42
|
53
|
+
statement2.key = 'wth'
|
54
|
+
array = [statement1, statement2]
|
55
|
+
assert_equal 2, array.uniq.size
|
56
|
+
end
|
57
|
+
end
|
18
58
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
describe 'Window' do
|
6
|
+
describe 'equality' do
|
7
|
+
it 'is equal with equal ivars' do
|
8
|
+
window1 = Window.new
|
9
|
+
window1.orders = [1, 2]
|
10
|
+
window1.frame 3
|
11
|
+
window2 = Window.new
|
12
|
+
window2.orders = [1, 2]
|
13
|
+
window2.frame 3
|
14
|
+
array = [window1, window2]
|
15
|
+
assert_equal 1, array.uniq.size
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'is not equal with different ivars' do
|
19
|
+
window1 = Window.new
|
20
|
+
window1.orders = [1, 2]
|
21
|
+
window1.frame 3
|
22
|
+
window2 = Window.new
|
23
|
+
window2.orders = [1, 2]
|
24
|
+
window2.frame 4
|
25
|
+
array = [window1, window2]
|
26
|
+
assert_equal 2, array.uniq.size
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'NamedWindow' do
|
32
|
+
describe 'equality' do
|
33
|
+
it 'is equal with equal ivars' do
|
34
|
+
window1 = NamedWindow.new 'foo'
|
35
|
+
window1.orders = [1, 2]
|
36
|
+
window1.frame 3
|
37
|
+
window2 = NamedWindow.new 'foo'
|
38
|
+
window2.orders = [1, 2]
|
39
|
+
window2.frame 3
|
40
|
+
array = [window1, window2]
|
41
|
+
assert_equal 1, array.uniq.size
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'is not equal with different ivars' do
|
45
|
+
window1 = NamedWindow.new 'foo'
|
46
|
+
window1.orders = [1, 2]
|
47
|
+
window1.frame 3
|
48
|
+
window2 = NamedWindow.new 'bar'
|
49
|
+
window2.orders = [1, 2]
|
50
|
+
window2.frame 3
|
51
|
+
array = [window1, window2]
|
52
|
+
assert_equal 2, array.uniq.size
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'CurrentRow' do
|
58
|
+
describe 'equality' do
|
59
|
+
it 'is equal to other current row nodes' do
|
60
|
+
array = [CurrentRow.new, CurrentRow.new]
|
61
|
+
assert_equal 1, array.uniq.size
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is not equal with other nodes' do
|
65
|
+
array = [CurrentRow.new, Node.new]
|
66
|
+
assert_equal 2, array.uniq.size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
data/test/test_attributes.rb
CHANGED
@@ -10,6 +10,18 @@ module Arel
|
|
10
10
|
assert_equal [attribute], node.expressions
|
11
11
|
end
|
12
12
|
|
13
|
+
describe 'equality' do
|
14
|
+
it 'is equal with equal ivars' do
|
15
|
+
array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'bar')]
|
16
|
+
assert_equal 1, array.uniq.size
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is not equal with different ivars' do
|
20
|
+
array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'baz')]
|
21
|
+
assert_equal 2, array.uniq.size
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
13
25
|
describe 'for' do
|
14
26
|
it 'deals with unknown column types' do
|
15
27
|
column = Struct.new(:type).new :crazy
|
data/test/test_insert_manager.rb
CHANGED
@@ -10,7 +10,6 @@ module Arel
|
|
10
10
|
|
11
11
|
describe 'insert' do
|
12
12
|
it 'can create a Values node' do
|
13
|
-
table = Table.new(:users)
|
14
13
|
manager = Arel::InsertManager.new Table.engine
|
15
14
|
values = manager.create_values %w{ a b }, %w{ c d }
|
16
15
|
|
@@ -20,7 +19,6 @@ module Arel
|
|
20
19
|
end
|
21
20
|
|
22
21
|
it 'allows sql literals' do
|
23
|
-
table = Table.new(:users)
|
24
22
|
manager = Arel::InsertManager.new Table.engine
|
25
23
|
manager.values = manager.create_values [Arel.sql('*')], %w{ a }
|
26
24
|
manager.to_sql.must_be_like %{
|
data/test/test_select_manager.rb
CHANGED
@@ -119,7 +119,7 @@ module Arel
|
|
119
119
|
manager = Arel::SelectManager.new Table.engine
|
120
120
|
manager.project Arel.sql('name')
|
121
121
|
manager.from as
|
122
|
-
manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg
|
122
|
+
manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg) foo"
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -147,7 +147,7 @@ module Arel
|
|
147
147
|
manager1.from(as)
|
148
148
|
|
149
149
|
manager1.to_sql.must_be_like %{
|
150
|
-
SELECT lol FROM (SELECT * FROM "users"
|
150
|
+
SELECT lol FROM (SELECT * FROM "users") omg
|
151
151
|
}
|
152
152
|
end
|
153
153
|
end
|
@@ -672,7 +672,6 @@ module Arel
|
|
672
672
|
end
|
673
673
|
|
674
674
|
it 'returns string join sql' do
|
675
|
-
table = Table.new :users
|
676
675
|
manager = Arel::SelectManager.new Table.engine
|
677
676
|
manager.from Nodes::StringJoin.new('hello')
|
678
677
|
manager.join_sql.must_be_like %{ 'hello' }
|
@@ -1033,6 +1032,14 @@ module Arel
|
|
1033
1032
|
end
|
1034
1033
|
end
|
1035
1034
|
|
1035
|
+
describe 'projections' do
|
1036
|
+
it 'reads projections' do
|
1037
|
+
manager = Arel::SelectManager.new Table.engine
|
1038
|
+
manager.project Arel.sql('foo'), Arel.sql('bar')
|
1039
|
+
manager.projections.must_equal [Arel.sql('foo'), Arel.sql('bar')]
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
|
1036
1043
|
describe 'projections=' do
|
1037
1044
|
it 'overwrites projections' do
|
1038
1045
|
manager = Arel::SelectManager.new Table.engine
|
@@ -1132,7 +1139,6 @@ module Arel
|
|
1132
1139
|
|
1133
1140
|
describe 'source' do
|
1134
1141
|
it 'returns the join source of the select core' do
|
1135
|
-
table = Table.new :users
|
1136
1142
|
manager = Arel::SelectManager.new Table.engine
|
1137
1143
|
manager.source.must_equal manager.ast.cores.last.source
|
1138
1144
|
end
|
@@ -1140,7 +1146,6 @@ module Arel
|
|
1140
1146
|
|
1141
1147
|
describe 'distinct' do
|
1142
1148
|
it 'sets the quantifier' do
|
1143
|
-
table = Table.new :users
|
1144
1149
|
manager = Arel::SelectManager.new Table.engine
|
1145
1150
|
|
1146
1151
|
manager.distinct
|
data/test/test_table.rb
CHANGED
@@ -180,5 +180,29 @@ module Arel
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
end
|
183
|
+
|
184
|
+
describe 'equality' do
|
185
|
+
it 'is equal with equal ivars' do
|
186
|
+
relation1 = Table.new(:users, 'vroom')
|
187
|
+
relation1.aliases = %w[a b c]
|
188
|
+
relation1.table_alias = 'zomg'
|
189
|
+
relation2 = Table.new(:users, 'vroom')
|
190
|
+
relation2.aliases = %w[a b c]
|
191
|
+
relation2.table_alias = 'zomg'
|
192
|
+
array = [relation1, relation2]
|
193
|
+
assert_equal 1, array.uniq.size
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'is not equal with different ivars' do
|
197
|
+
relation1 = Table.new(:users, 'vroom')
|
198
|
+
relation1.aliases = %w[a b c]
|
199
|
+
relation1.table_alias = 'zomg'
|
200
|
+
relation2 = Table.new(:users, 'vroom')
|
201
|
+
relation2.aliases = %w[x y z]
|
202
|
+
relation2.table_alias = 'zomg'
|
203
|
+
array = [relation1, relation2]
|
204
|
+
assert_equal 2, array.uniq.size
|
205
|
+
end
|
206
|
+
end
|
183
207
|
end
|
184
208
|
end
|
data/test/test_update_manager.rb
CHANGED
@@ -8,6 +8,14 @@ module Arel
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
it "should not quote sql literals" do
|
12
|
+
table = Table.new(:users)
|
13
|
+
um = Arel::UpdateManager.new Table.engine
|
14
|
+
um.table table
|
15
|
+
um.set [[table[:name], (Arel::Nodes::BindParam.new '?')]]
|
16
|
+
um.to_sql.must_be_like %{ UPDATE "users" SET "name" = ? }
|
17
|
+
end
|
18
|
+
|
11
19
|
it 'handles limit properly' do
|
12
20
|
table = Table.new(:users)
|
13
21
|
um = Arel::UpdateManager.new Table.engine
|
@@ -1,9 +1,28 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'arel/visitors/bind_visitor'
|
3
|
+
require 'support/fake_record'
|
3
4
|
|
4
5
|
module Arel
|
5
6
|
module Visitors
|
6
|
-
class TestBindVisitor < MiniTest::Unit::TestCase
|
7
|
+
class TestBindVisitor < MiniTest::Unit::TestCase
|
8
|
+
|
9
|
+
##
|
10
|
+
# Tests visit_Arel_Nodes_Assignment correctly
|
11
|
+
# substitutes binds with values from block
|
12
|
+
def test_assignment_binds_are_substituted
|
13
|
+
table = Table.new(:users)
|
14
|
+
um = Arel::UpdateManager.new Table.engine
|
15
|
+
bp = Nodes::BindParam.new '?'
|
16
|
+
um.set [[table[:name], bp]]
|
17
|
+
visitor = Class.new(Arel::Visitors::ToSql) {
|
18
|
+
include Arel::Visitors::BindVisitor
|
19
|
+
}.new Table.engine.connection
|
20
|
+
|
21
|
+
assignment = um.ast.values[0]
|
22
|
+
actual = visitor.accept(assignment) { "replace" }
|
23
|
+
actual.must_be_like "\"name\" = replace"
|
24
|
+
end
|
25
|
+
|
7
26
|
def test_visitor_yields_on_binds
|
8
27
|
visitor = Class.new(Arel::Visitors::Visitor) {
|
9
28
|
def initialize omg
|
@@ -48,6 +48,45 @@ module Arel
|
|
48
48
|
sql.must_be_like %{ omg(*) = 2 }
|
49
49
|
end
|
50
50
|
|
51
|
+
it 'should visit built-in functions' do
|
52
|
+
function = Nodes::Count.new([Arel.star])
|
53
|
+
assert_equal 'COUNT(*)', @visitor.accept(function)
|
54
|
+
|
55
|
+
function = Nodes::Sum.new([Arel.star])
|
56
|
+
assert_equal 'SUM(*)', @visitor.accept(function)
|
57
|
+
|
58
|
+
function = Nodes::Max.new([Arel.star])
|
59
|
+
assert_equal 'MAX(*)', @visitor.accept(function)
|
60
|
+
|
61
|
+
function = Nodes::Min.new([Arel.star])
|
62
|
+
assert_equal 'MIN(*)', @visitor.accept(function)
|
63
|
+
|
64
|
+
function = Nodes::Avg.new([Arel.star])
|
65
|
+
assert_equal 'AVG(*)', @visitor.accept(function)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should visit built-in functions operating on distinct values' do
|
69
|
+
function = Nodes::Count.new([Arel.star])
|
70
|
+
function.distinct = true
|
71
|
+
assert_equal 'COUNT(DISTINCT *)', @visitor.accept(function)
|
72
|
+
|
73
|
+
function = Nodes::Sum.new([Arel.star])
|
74
|
+
function.distinct = true
|
75
|
+
assert_equal 'SUM(DISTINCT *)', @visitor.accept(function)
|
76
|
+
|
77
|
+
function = Nodes::Max.new([Arel.star])
|
78
|
+
function.distinct = true
|
79
|
+
assert_equal 'MAX(DISTINCT *)', @visitor.accept(function)
|
80
|
+
|
81
|
+
function = Nodes::Min.new([Arel.star])
|
82
|
+
function.distinct = true
|
83
|
+
assert_equal 'MIN(DISTINCT *)', @visitor.accept(function)
|
84
|
+
|
85
|
+
function = Nodes::Avg.new([Arel.star])
|
86
|
+
function.distinct = true
|
87
|
+
assert_equal 'AVG(DISTINCT *)', @visitor.accept(function)
|
88
|
+
end
|
89
|
+
|
51
90
|
it 'works with lists' do
|
52
91
|
function = Nodes::NamedFunction.new('omg', [Arel.star, Arel.star])
|
53
92
|
assert_equal 'omg(*, *)', @visitor.accept(function)
|
@@ -126,6 +165,11 @@ module Arel
|
|
126
165
|
@visitor.accept(nil).must_be_like "NULL"
|
127
166
|
end
|
128
167
|
|
168
|
+
it "should visit_Arel_SelectManager, which is a subquery" do
|
169
|
+
mgr = Table.new(:foo).project(:bar)
|
170
|
+
@visitor.accept(mgr).must_be_like '(SELECT bar FROM "foo")'
|
171
|
+
end
|
172
|
+
|
129
173
|
it "should visit_Arel_Nodes_And" do
|
130
174
|
node = Nodes::And.new [@attr.eq(10), @attr.eq(11)]
|
131
175
|
@visitor.accept(node).must_be_like %{
|