diff options
author | Ernie Miller <ernie@erniemiller.org> | 2012-08-18 22:33:25 -0400 |
---|---|---|
committer | Ernie Miller <ernie@erniemiller.org> | 2012-08-18 22:33:25 -0400 |
commit | 6e638bba594b6164190d2a6fb96ffa07a20b11f3 (patch) | |
tree | 2d54111a8fc8ef4a892739f07990158df73c3c4e | |
parent | 1de1041c00abff9cfc57837a80e12157901ff194 (diff) | |
download | rails-6e638bba594b6164190d2a6fb96ffa07a20b11f3.tar.gz rails-6e638bba594b6164190d2a6fb96ffa07a20b11f3.tar.bz2 rails-6e638bba594b6164190d2a6fb96ffa07a20b11f3.zip |
Add equality to ALL THE THINGS (that matter)
People are often trying to use ARel nodes inside ActiveRecord, and when
they do so, lots of things can break, because ActiveRecord relies on
Array#uniq and sometimes hash key equality to handle values that end up
in wheres, havings, etc. By implementing equality for all the nodes, we
should hopefully be able to prevent any nodes (even nodes containing
other nodes) from failing an equality check they should otherwise pass,
and alleviate many of these errors.
Fixes #130
43 files changed, 737 insertions, 4 deletions
diff --git a/lib/arel/nodes/and.rb b/lib/arel/nodes/and.rb index b4443c3d27..0d0fb3ee82 100644 --- a/lib/arel/nodes/and.rb +++ b/lib/arel/nodes/and.rb @@ -18,6 +18,16 @@ module Arel def right children[1] end + + def hash + children.hash + end + + def eql? other + self.class == other.class && + self.children == other.children + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/binary.rb b/lib/arel/nodes/binary.rb index bcd46db398..d55c7a5478 100644 --- a/lib/arel/nodes/binary.rb +++ b/lib/arel/nodes/binary.rb @@ -13,6 +13,17 @@ module Arel @left = @left.clone if @left @right = @right.clone if @right end + + def hash + [@left, @right].hash + end + + def eql? other + self.class == other.class && + self.left == other.left && + self.right == other.right + end + alias :== :eql? end %w{ diff --git a/lib/arel/nodes/extract.rb b/lib/arel/nodes/extract.rb index 1c9ee78816..92fbde62e1 100644 --- a/lib/arel/nodes/extract.rb +++ b/lib/arel/nodes/extract.rb @@ -18,6 +18,17 @@ module Arel self.alias = SqlLiteral.new(aliaz) self end + + def hash + super ^ [@field, @alias].hash + end + + def eql? other + super && + self.field == other.field && + self.alias == other.alias + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/false.rb b/lib/arel/nodes/false.rb index 611e19633b..6df70e43ce 100644 --- a/lib/arel/nodes/false.rb +++ b/lib/arel/nodes/false.rb @@ -1,6 +1,13 @@ module Arel module Nodes class False < Arel::Nodes::Node + def hash + self.class.hash + end + + def eql? other + self.class == other.class + end end end end diff --git a/lib/arel/nodes/function.rb b/lib/arel/nodes/function.rb index 5f6056a6b6..90bbf4a77b 100644 --- a/lib/arel/nodes/function.rb +++ b/lib/arel/nodes/function.rb @@ -16,6 +16,17 @@ module Arel self.alias = SqlLiteral.new(aliaz) self end + + def hash + [@expressions, @alias, @distinct].hash + end + + def eql? other + self.class == other.class && + self.expressions == other.expressions && + self.alias == other.alias && + self.distinct == other.distinct + end end %w{ diff --git a/lib/arel/nodes/insert_statement.rb b/lib/arel/nodes/insert_statement.rb index 37c12f011a..518160cce4 100644 --- a/lib/arel/nodes/insert_statement.rb +++ b/lib/arel/nodes/insert_statement.rb @@ -14,6 +14,18 @@ module Arel @columns = @columns.clone @values = @values.clone if @values end + + def hash + [@relation, @columns, @values].hash + end + + def eql? other + self.class == other.class && + self.relation == other.relation && + self.columns == other.columns && + self.values == other.values + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/named_function.rb b/lib/arel/nodes/named_function.rb index 56669bf858..c792f0af98 100644 --- a/lib/arel/nodes/named_function.rb +++ b/lib/arel/nodes/named_function.rb @@ -7,6 +7,15 @@ module Arel super(expr, aliaz) @name = name end + + def hash + super ^ @name.hash + end + + def eql? other + super && self.name == other.name + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/select_core.rb b/lib/arel/nodes/select_core.rb index 9b8c4a2a1f..3b400c768d 100644 --- a/lib/arel/nodes/select_core.rb +++ b/lib/arel/nodes/select_core.rb @@ -37,6 +37,26 @@ module Arel @having = @having.clone if @having @windows = @windows.clone end + + def hash + [ + @source, @top, @set_quantifier, @projections, + @wheres, @groups, @having, @windows + ].hash + end + + def eql? other + self.class == other.class && + self.source == other.source && + self.top == other.top && + self.set_quantifier == other.set_quantifier && + self.projections == other.projections && + self.wheres == other.wheres && + self.groups == other.groups && + self.having == other.having && + self.windows == other.windows + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/select_statement.rb b/lib/arel/nodes/select_statement.rb index c99842f22f..32bdd7080c 100644 --- a/lib/arel/nodes/select_statement.rb +++ b/lib/arel/nodes/select_statement.rb @@ -5,7 +5,6 @@ module Arel attr_accessor :limit, :orders, :lock, :offset, :with def initialize cores = [SelectCore.new] - #puts caller @cores = cores @orders = [] @limit = nil @@ -19,6 +18,21 @@ module Arel @cores = @cores.map { |x| x.clone } @orders = @orders.map { |x| x.clone } end + + def hash + [@cores, @orders, @limit, @lock, @offset, @with].hash + end + + def eql? other + self.class == other.class && + self.cores == other.cores && + self.orders == other.orders && + self.limit == other.limit && + self.lock == other.lock && + self.offset == other.offset && + self.with == other.with + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/terminal.rb b/lib/arel/nodes/terminal.rb index c6b4f4e1e2..f4cdfdfe17 100644 --- a/lib/arel/nodes/terminal.rb +++ b/lib/arel/nodes/terminal.rb @@ -1,6 +1,13 @@ module Arel module Nodes class Distinct < Arel::Nodes::Node + def hash + self.class.hash + end + + def eql? other + self.class == other.class + end end end end diff --git a/lib/arel/nodes/true.rb b/lib/arel/nodes/true.rb index 63dd5562e1..082963e5e6 100644 --- a/lib/arel/nodes/true.rb +++ b/lib/arel/nodes/true.rb @@ -1,6 +1,13 @@ module Arel module Nodes class True < Arel::Nodes::Node + def hash + self.class.hash + end + + def eql? other + self.class == other.class + end end end end diff --git a/lib/arel/nodes/unary.rb b/lib/arel/nodes/unary.rb index 7828cceae5..42c31267dd 100644 --- a/lib/arel/nodes/unary.rb +++ b/lib/arel/nodes/unary.rb @@ -7,6 +7,16 @@ module Arel def initialize expr @expr = expr end + + def hash + @expr.hash + end + + def eql? other + self.class == other.class && + self.expr == other.expr + end + alias :== :eql? end %w{ diff --git a/lib/arel/nodes/update_statement.rb b/lib/arel/nodes/update_statement.rb index c08f1b2c5e..d6831dc242 100644 --- a/lib/arel/nodes/update_statement.rb +++ b/lib/arel/nodes/update_statement.rb @@ -18,6 +18,21 @@ module Arel @wheres = @wheres.clone @values = @values.clone end + + def hash + [@relation, @wheres, @values, @orders, @limit, @key].hash + end + + def eql? other + self.class == other.class && + self.relation == other.relation && + self.wheres == other.wheres && + self.values == other.values && + self.orders == other.orders && + self.limit == other.limit && + self.key == other.key + end + alias :== :eql? end end end diff --git a/lib/arel/nodes/window.rb b/lib/arel/nodes/window.rb index 383d6b8778..3c05f47f14 100644 --- a/lib/arel/nodes/window.rb +++ b/lib/arel/nodes/window.rb @@ -32,6 +32,17 @@ module Arel super @orders = @orders.map { |x| x.clone } end + + def hash + [@orders, @framing].hash + end + + def eql? other + self.class == other.class && + self.orders == other.orders && + self.framing == other.framing + end + alias :== :eql? end class NamedWindow < Window @@ -46,6 +57,15 @@ module Arel super @name = other.name.clone end + + def hash + super ^ @name.hash + end + + def eql? other + super && self.name == other.name + end + alias :== :eql? end class Rows < Unary @@ -60,7 +80,15 @@ module Arel end end - class CurrentRow < Arel::Nodes::Node; end + class CurrentRow < Node + def hash + self.class.hash + end + + def eql? other + self.class == other.class + end + end class Preceding < Unary def initialize(expr = nil) diff --git a/lib/arel/table.rb b/lib/arel/table.rb index 7a1983b3d2..6f1ab7e90f 100644 --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -123,6 +123,19 @@ Arel 4.0.0 with no replacement. PEW PEW PEW!!! InsertManager.new(@engine) end + def hash + [@name, @engine, @aliases, @table_alias].hash + end + + def eql? other + self.class == other.class && + self.name == other.name && + self.engine == other.engine && + self.aliases == other.aliases && + self.table_alias == other.table_alias + end + alias :== :eql? + private def attributes_for columns diff --git a/test/nodes/test_and.rb b/test/nodes/test_and.rb new file mode 100644 index 0000000000..88d6d61531 --- /dev/null +++ b/test/nodes/test_and.rb @@ -0,0 +1,20 @@ +require 'helper' + +module Arel + module Nodes + describe 'And' do + describe 'equality' do + it 'is equal with equal ivars' do + array = [And.new(['foo', 'bar']), And.new(['foo', 'bar'])] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [And.new(['foo', 'bar']), And.new(['foo', 'baz'])] + assert_equal 2, array.uniq.size + end + end + end + end +end + diff --git a/test/nodes/test_as.rb b/test/nodes/test_as.rb index 02cbe5f7b0..b1dcccf7c7 100644 --- a/test/nodes/test_as.rb +++ b/test/nodes/test_as.rb @@ -17,6 +17,18 @@ module Arel assert_kind_of Arel::Nodes::SqlLiteral, as.right end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [As.new('foo', 'bar'), As.new('foo', 'bar')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [As.new('foo', 'bar'), As.new('foo', 'baz')] + assert_equal 2, array.uniq.size + end + end end end end diff --git a/test/nodes/test_ascending.rb b/test/nodes/test_ascending.rb index 0e2c4810c6..63d758a8a8 100644 --- a/test/nodes/test_ascending.rb +++ b/test/nodes/test_ascending.rb @@ -29,6 +29,16 @@ module Arel ascending = Ascending.new 'zomg' assert !ascending.descending? end + + def test_equality_with_same_ivars + array = [Ascending.new('zomg'), Ascending.new('zomg')] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + array = [Ascending.new('zomg'), Ascending.new('zomg!')] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_bin.rb b/test/nodes/test_bin.rb index 7f123eab13..c370c5755f 100644 --- a/test/nodes/test_bin.rb +++ b/test/nodes/test_bin.rb @@ -18,6 +18,16 @@ module Arel node = Arel::Nodes::Bin.new(Arel.sql('zomg')) assert_equal 'BINARY zomg', viz.accept(node) end + + def test_equality_with_same_ivars + array = [Bin.new('zomg'), Bin.new('zomg')] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + array = [Bin.new('zomg'), Bin.new('zomg!')] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_count.rb b/test/nodes/test_count.rb index be53b86855..88d2a694c8 100644 --- a/test/nodes/test_count.rb +++ b/test/nodes/test_count.rb @@ -24,4 +24,16 @@ describe Arel::Nodes::Count do } end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [Arel::Nodes::Count.new('foo'), Arel::Nodes::Count.new('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Arel::Nodes::Count.new('foo'), Arel::Nodes::Count.new('foo!')] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_delete_statement.rb b/test/nodes/test_delete_statement.rb index 299bdd38ee..4bd5446ba2 100644 --- a/test/nodes/test_delete_statement.rb +++ b/test/nodes/test_delete_statement.rb @@ -11,4 +11,24 @@ describe Arel::Nodes::DeleteStatement do dolly.wheres.wont_be_same_as statement.wheres end end + + describe 'equality' do + it 'is equal with equal ivars' do + statement1 = Arel::Nodes::DeleteStatement.new + statement1.wheres = %w[a b c] + statement2 = Arel::Nodes::DeleteStatement.new + statement2.wheres = %w[a b c] + array = [statement1, statement2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + statement1 = Arel::Nodes::DeleteStatement.new + statement1.wheres = %w[a b c] + statement2 = Arel::Nodes::DeleteStatement.new + statement2.wheres = %w[1 2 3] + array = [statement1, statement2] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_descending.rb b/test/nodes/test_descending.rb index 424f8298cd..22b456fd8d 100644 --- a/test/nodes/test_descending.rb +++ b/test/nodes/test_descending.rb @@ -29,6 +29,16 @@ module Arel descending = Descending.new 'zomg' assert descending.descending? end + + def test_equality_with_same_ivars + array = [Descending.new('zomg'), Descending.new('zomg')] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + array = [Descending.new('zomg'), Descending.new('zomg!')] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_distinct.rb b/test/nodes/test_distinct.rb new file mode 100644 index 0000000000..ffa8a68e6c --- /dev/null +++ b/test/nodes/test_distinct.rb @@ -0,0 +1,20 @@ +require 'helper' + +module Arel + module Nodes + describe 'Distinct' do + describe 'equality' do + it 'is equal to other distinct nodes' do + array = [Distinct.new, Distinct.new] + assert_equal 1, array.uniq.size + end + + it 'is not equal with other nodes' do + array = [Distinct.new, Node.new] + assert_equal 2, array.uniq.size + end + end + end + end +end + diff --git a/test/nodes/test_equality.rb b/test/nodes/test_equality.rb index fb022f615f..79764cc7d3 100644 --- a/test/nodes/test_equality.rb +++ b/test/nodes/test_equality.rb @@ -69,6 +69,16 @@ module Arel node.right.must_equal right end end + + it 'is equal with equal ivars' do + array = [Equality.new('foo', 'bar'), Equality.new('foo', 'bar')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Equality.new('foo', 'bar'), Equality.new('foo', 'baz')] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_extract.rb b/test/nodes/test_extract.rb index bd1dfa4750..80bb465f24 100644 --- a/test/nodes/test_extract.rb +++ b/test/nodes/test_extract.rb @@ -16,4 +16,18 @@ describe Arel::Nodes::Extract do } end end + + describe 'equality' do + it 'is equal with equal ivars' do + table = Arel::Table.new :users + array = [table[:attr].extract('foo'), table[:attr].extract('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + table = Arel::Table.new :users + array = [table[:attr].extract('foo'), table[:attr].extract('bar')] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_false.rb b/test/nodes/test_false.rb new file mode 100644 index 0000000000..a2a8866680 --- /dev/null +++ b/test/nodes/test_false.rb @@ -0,0 +1,20 @@ +require 'helper' + +module Arel + module Nodes + describe 'False' do + describe 'equality' do + it 'is equal to other false nodes' do + array = [False.new, False.new] + assert_equal 1, array.uniq.size + end + + it 'is not equal with other nodes' do + array = [False.new, Node.new] + assert_equal 2, array.uniq.size + end + end + end + end +end + diff --git a/test/nodes/test_grouping.rb b/test/nodes/test_grouping.rb index 3f84ac301e..b7aa51d37f 100644 --- a/test/nodes/test_grouping.rb +++ b/test/nodes/test_grouping.rb @@ -7,6 +7,18 @@ module Arel grouping = Grouping.new('foo') grouping.eq('foo').to_sql.must_be_like %q{('foo') = 'foo'} end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [Grouping.new('foo'), Grouping.new('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Grouping.new('foo'), Grouping.new('bar')] + assert_equal 2, array.uniq.size + end + end end end end diff --git a/test/nodes/test_infix_operation.rb b/test/nodes/test_infix_operation.rb index 3d2eb0d9c6..b7b6b02d0f 100644 --- a/test/nodes/test_infix_operation.rb +++ b/test/nodes/test_infix_operation.rb @@ -25,6 +25,16 @@ module Arel assert_equal operation, ordering.expr assert ordering.descending? end + + def test_equality_with_same_ivars + array = [InfixOperation.new(:+, 1, 2), InfixOperation.new(:+, 1, 2)] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + array = [InfixOperation.new(:+, 1, 2), InfixOperation.new(:+, 1, 3)] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_insert_statement.rb b/test/nodes/test_insert_statement.rb index ef37e5c871..e0a5696ea4 100644 --- a/test/nodes/test_insert_statement.rb +++ b/test/nodes/test_insert_statement.rb @@ -15,4 +15,28 @@ describe Arel::Nodes::InsertStatement do dolly.values.wont_be_same_as statement.values end end + + describe 'equality' do + it 'is equal with equal ivars' do + statement1 = Arel::Nodes::InsertStatement.new + statement1.columns = %w[a b c] + statement1.values = %w[x y z] + statement2 = Arel::Nodes::InsertStatement.new + statement2.columns = %w[a b c] + statement2.values = %w[x y z] + array = [statement1, statement2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + statement1 = Arel::Nodes::InsertStatement.new + statement1.columns = %w[a b c] + statement1.values = %w[x y z] + statement2 = Arel::Nodes::InsertStatement.new + statement2.columns = %w[a b c] + statement2.values = %w[1 2 3] + array = [statement1, statement2] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_named_function.rb b/test/nodes/test_named_function.rb index 3e0b2c3972..9d16f9cbee 100644 --- a/test/nodes/test_named_function.rb +++ b/test/nodes/test_named_function.rb @@ -25,6 +25,22 @@ module Arel assert_kind_of SqlLiteral, function.alias assert_equal 'wth', function.alias end + + def test_equality_with_same_ivars + array = [ + NamedFunction.new('omg', 'zomg', 'wth'), + NamedFunction.new('omg', 'zomg', 'wth') + ] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + array = [ + NamedFunction.new('omg', 'zomg', 'wth'), + NamedFunction.new('zomg', 'zomg', 'wth') + ] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_not.rb b/test/nodes/test_not.rb index c5bb0088c8..a08d037445 100644 --- a/test/nodes/test_not.rb +++ b/test/nodes/test_not.rb @@ -12,6 +12,18 @@ module Arel node.expr.must_equal expr end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [Not.new('foo'), Not.new('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Not.new('foo'), Not.new('baz')] + assert_equal 2, array.uniq.size + end + end end end end diff --git a/test/nodes/test_or.rb b/test/nodes/test_or.rb index 88115669d1..3e7bcc9379 100644 --- a/test/nodes/test_or.rb +++ b/test/nodes/test_or.rb @@ -17,6 +17,18 @@ module Arel oror.expr.right.must_equal right end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [Or.new('foo', 'bar'), Or.new('foo', 'bar')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Or.new('foo', 'bar'), Or.new('foo', 'baz')] + assert_equal 2, array.uniq.size + end + end end end end diff --git a/test/nodes/test_over.rb b/test/nodes/test_over.rb index 0bdd665e56..0aac00b230 100644 --- a/test/nodes/test_over.rb +++ b/test/nodes/test_over.rb @@ -46,4 +46,22 @@ describe Arel::Nodes::Over do } end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [ + Arel::Nodes::Over.new('foo', 'bar'), + Arel::Nodes::Over.new('foo', 'bar') + ] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [ + Arel::Nodes::Over.new('foo', 'bar'), + Arel::Nodes::Over.new('foo', 'baz') + ] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_select_core.rb b/test/nodes/test_select_core.rb index 4382c79865..e4ed06b853 100644 --- a/test/nodes/test_select_core.rb +++ b/test/nodes/test_select_core.rb @@ -26,6 +26,44 @@ module Arel viz = Arel::Visitors::ToSql.new Table.engine.connection_pool assert_match 'DISTINCT', viz.accept(core) end + + def test_equality_with_same_ivars + core1 = SelectCore.new + core1.froms = %w[a b c] + core1.projections = %w[d e f] + core1.wheres = %w[g h i] + core1.groups = %w[j k l] + core1.windows = %w[m n o] + core1.having = %w[p q r] + core2 = SelectCore.new + core2.froms = %w[a b c] + core2.projections = %w[d e f] + core2.wheres = %w[g h i] + core2.groups = %w[j k l] + core2.windows = %w[m n o] + core2.having = %w[p q r] + array = [core1, core2] + assert_equal 1, array.uniq.size + end + + def test_inequality_with_different_ivars + core1 = SelectCore.new + core1.froms = %w[a b c] + core1.projections = %w[d e f] + core1.wheres = %w[g h i] + core1.groups = %w[j k l] + core1.windows = %w[m n o] + core1.having = %w[p q r] + core2 = SelectCore.new + core2.froms = %w[a b c] + core2.projections = %w[d e f] + core2.wheres = %w[g h i] + core2.groups = %w[j k l] + core2.windows = %w[m n o] + core2.having = %w[l o l] + array = [core1, core2] + assert_equal 2, array.uniq.size + end end end end diff --git a/test/nodes/test_select_statement.rb b/test/nodes/test_select_statement.rb index 8bbf7d174c..3e4fcc0c07 100644 --- a/test/nodes/test_select_statement.rb +++ b/test/nodes/test_select_statement.rb @@ -10,4 +10,40 @@ describe Arel::Nodes::SelectStatement do dolly.cores.wont_be_same_as statement.cores end end + + describe 'equality' do + it 'is equal with equal ivars' do + statement1 = Arel::Nodes::SelectStatement.new %w[a b c] + statement1.offset = 1 + statement1.limit = 2 + statement1.lock = false + statement1.orders = %w[x y z] + statement1.with = 'zomg' + statement2 = Arel::Nodes::SelectStatement.new %w[a b c] + statement2.offset = 1 + statement2.limit = 2 + statement2.lock = false + statement2.orders = %w[x y z] + statement2.with = 'zomg' + array = [statement1, statement2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + statement1 = Arel::Nodes::SelectStatement.new %w[a b c] + statement1.offset = 1 + statement1.limit = 2 + statement1.lock = false + statement1.orders = %w[x y z] + statement1.with = 'zomg' + statement2 = Arel::Nodes::SelectStatement.new %w[a b c] + statement2.offset = 1 + statement2.limit = 2 + statement2.lock = false + statement2.orders = %w[x y z] + statement2.with = 'wth' + array = [statement1, statement2] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_sql_literal.rb b/test/nodes/test_sql_literal.rb index 54d1d4417f..9deb8e5d8d 100644 --- a/test/nodes/test_sql_literal.rb +++ b/test/nodes/test_sql_literal.rb @@ -31,6 +31,16 @@ module Arel node = SqlLiteral.new('foo').eq(1) @visitor.accept(node).must_be_like %{ foo = 1 } end + + it 'is equal with equal contents' do + array = [SqlLiteral.new('foo'), SqlLiteral.new('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different contents' do + array = [SqlLiteral.new('foo'), SqlLiteral.new('bar')] + assert_equal 2, array.uniq.size + end end describe 'grouped "or" equality' do diff --git a/test/nodes/test_sum.rb b/test/nodes/test_sum.rb index 50f5c0f4b5..d65cd31d4b 100644 --- a/test/nodes/test_sum.rb +++ b/test/nodes/test_sum.rb @@ -9,4 +9,16 @@ describe Arel::Nodes::Sum do } end end + + describe 'equality' do + it 'is equal with equal ivars' do + array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo!')] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_table_alias.rb b/test/nodes/test_table_alias.rb index fef24bb19e..4aafd12b79 100644 --- a/test/nodes/test_table_alias.rb +++ b/test/nodes/test_table_alias.rb @@ -5,12 +5,32 @@ module Arel module Nodes describe 'table alias' do it 'has an #engine which delegates to the relation' do - engine = Object.new - relation = OpenStruct.new(:engine => engine) + engine = 'vroom' + relation = Table.new(:users, engine) node = TableAlias.new relation, :foo node.engine.must_equal engine end + + describe 'equality' do + it 'is equal with equal ivars' do + relation1 = Table.new(:users, 'vroom') + node1 = TableAlias.new relation1, :foo + relation2 = Table.new(:users, 'vroom') + node2 = TableAlias.new relation2, :foo + array = [node1, node2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + relation1 = Table.new(:users, 'vroom') + node1 = TableAlias.new relation1, :foo + relation2 = Table.new(:users, 'vroom') + node2 = TableAlias.new relation2, :bar + array = [node1, node2] + assert_equal 2, array.uniq.size + end + end end end end diff --git a/test/nodes/test_true.rb b/test/nodes/test_true.rb new file mode 100644 index 0000000000..ed4743a63b --- /dev/null +++ b/test/nodes/test_true.rb @@ -0,0 +1,21 @@ +require 'helper' + +module Arel + module Nodes + describe 'True' do + describe 'equality' do + it 'is equal to other true nodes' do + array = [True.new, True.new] + assert_equal 1, array.uniq.size + end + + it 'is not equal with other nodes' do + array = [True.new, Node.new] + assert_equal 2, array.uniq.size + end + end + end + end +end + + diff --git a/test/nodes/test_update_statement.rb b/test/nodes/test_update_statement.rb index 8920e977b5..920dc6e3ef 100644 --- a/test/nodes/test_update_statement.rb +++ b/test/nodes/test_update_statement.rb @@ -15,4 +15,44 @@ describe Arel::Nodes::UpdateStatement do dolly.values.wont_be_same_as statement.values end end + + describe 'equality' do + it 'is equal with equal ivars' do + statement1 = Arel::Nodes::UpdateStatement.new + statement1.relation = 'zomg' + statement1.wheres = 2 + statement1.values = false + statement1.orders = %w[x y z] + statement1.limit = 42 + statement1.key = 'zomg' + statement2 = Arel::Nodes::UpdateStatement.new + statement2.relation = 'zomg' + statement2.wheres = 2 + statement2.values = false + statement2.orders = %w[x y z] + statement2.limit = 42 + statement2.key = 'zomg' + array = [statement1, statement2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + statement1 = Arel::Nodes::UpdateStatement.new + statement1.relation = 'zomg' + statement1.wheres = 2 + statement1.values = false + statement1.orders = %w[x y z] + statement1.limit = 42 + statement1.key = 'zomg' + statement2 = Arel::Nodes::UpdateStatement.new + statement2.relation = 'zomg' + statement2.wheres = 2 + statement2.values = false + statement2.orders = %w[x y z] + statement2.limit = 42 + statement2.key = 'wth' + array = [statement1, statement2] + assert_equal 2, array.uniq.size + end + end end diff --git a/test/nodes/test_window.rb b/test/nodes/test_window.rb new file mode 100644 index 0000000000..f09d16e441 --- /dev/null +++ b/test/nodes/test_window.rb @@ -0,0 +1,73 @@ +require 'helper' + +module Arel + module Nodes + describe 'Window' do + describe 'equality' do + it 'is equal with equal ivars' do + window1 = Window.new + window1.orders = [1, 2] + window1.frame 3 + window2 = Window.new + window2.orders = [1, 2] + window2.frame 3 + array = [window1, window2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + window1 = Window.new + window1.orders = [1, 2] + window1.frame 3 + window2 = Window.new + window2.orders = [1, 2] + window2.frame 4 + array = [window1, window2] + assert_equal 2, array.uniq.size + end + end + end + + describe 'NamedWindow' do + describe 'equality' do + it 'is equal with equal ivars' do + window1 = NamedWindow.new 'foo' + window1.orders = [1, 2] + window1.frame 3 + window2 = NamedWindow.new 'foo' + window2.orders = [1, 2] + window2.frame 3 + array = [window1, window2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + window1 = NamedWindow.new 'foo' + window1.orders = [1, 2] + window1.frame 3 + window2 = NamedWindow.new 'bar' + window2.orders = [1, 2] + window2.frame 3 + array = [window1, window2] + assert_equal 2, array.uniq.size + end + end + end + + describe 'CurrentRow' do + describe 'equality' do + it 'is equal to other current row nodes' do + array = [CurrentRow.new, CurrentRow.new] + assert_equal 1, array.uniq.size + end + + it 'is not equal with other nodes' do + array = [CurrentRow.new, Node.new] + assert_equal 2, array.uniq.size + end + end + end + end +end + + diff --git a/test/test_attributes.rb b/test/test_attributes.rb index 010d708859..d0b00d4333 100644 --- a/test/test_attributes.rb +++ b/test/test_attributes.rb @@ -10,6 +10,18 @@ module Arel assert_equal [attribute], node.expressions end + describe 'equality' do + it 'is equal with equal ivars' do + array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'bar')] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'baz')] + assert_equal 2, array.uniq.size + end + end + describe 'for' do it 'deals with unknown column types' do column = Struct.new(:type).new :crazy diff --git a/test/test_table.rb b/test/test_table.rb index 1035540513..5db8cdd6c0 100644 --- a/test/test_table.rb +++ b/test/test_table.rb @@ -180,5 +180,29 @@ module Arel end end end + + describe 'equality' do + it 'is equal with equal ivars' do + relation1 = Table.new(:users, 'vroom') + relation1.aliases = %w[a b c] + relation1.table_alias = 'zomg' + relation2 = Table.new(:users, 'vroom') + relation2.aliases = %w[a b c] + relation2.table_alias = 'zomg' + array = [relation1, relation2] + assert_equal 1, array.uniq.size + end + + it 'is not equal with different ivars' do + relation1 = Table.new(:users, 'vroom') + relation1.aliases = %w[a b c] + relation1.table_alias = 'zomg' + relation2 = Table.new(:users, 'vroom') + relation2.aliases = %w[x y z] + relation2.table_alias = 'zomg' + array = [relation1, relation2] + assert_equal 2, array.uniq.size + end + end end end |