From 0bc1c15be9f951aa937199ff0d791180c464969d Mon Sep 17 00:00:00 2001 From: Dominik Goltermann Date: Wed, 5 Oct 2022 16:48:09 +0200 Subject: [PATCH] Fix eql? checks for definition models in order to return true if they have the same content --- lib/definition/model.rb | 7 +++- spec/lib/definition/model_spec.rb | 58 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/definition/model.rb b/lib/definition/model.rb index 678dd4f..5f8a8ef 100644 --- a/lib/definition/model.rb +++ b/lib/definition/model.rb @@ -55,7 +55,12 @@ def new(**kwargs) def ==(other) return false unless other.is_a?(self.class) - @_attributes == other.instance_variable_get(:@_attributes) + @_attributes.hash == other.instance_variable_get(:@_attributes).hash + end + alias eql? == + + def hash + @_attributes.hash end def to_h diff --git a/spec/lib/definition/model_spec.rb b/spec/lib/definition/model_spec.rb index 8904042..5d628b7 100644 --- a/spec/lib/definition/model_spec.rb +++ b/spec/lib/definition/model_spec.rb @@ -196,6 +196,64 @@ expect(model_a == model_b).to be false end + + it "returns false if a model is compared with its hash representation" do + model_a = test_model_class.new(name: "John") + + expect(model_a == model_a.to_h).to be false + end + end + + describe ".eql?" do + it "returns true if both models have the same content" do + model_a = test_model_class.new(name: "John") + model_b = test_model_class.new(name: "John") + + expect(model_a.eql?(model_b)).to be true + end + + it "returns false if both models have different content" do + model_a = test_model_class.new(name: "John") + model_b = test_model_class.new(name: "Marie") + + expect(model_a.eql?(model_b)).to be false + end + + it "returns false if a model is compared with its hash representation" do + model_a = test_model_class.new(name: "John") + + expect(model_a.eql?(model_a.to_h)).to be false + end + end + + describe ".hash" do + it "returns the same value for two models with the same content" do + model_a = test_model_class.new(name: "John") + model_b = test_model_class.new(name: "John") + + expect(model_a.hash).to eq(model_b.hash) + end + + it "returns a different value for two models with different content" do + model_a = test_model_class.new(name: "John") + model_b = test_model_class.new(name: "Marie") + + expect(model_a.hash).not_to eq(model_b.hash) + end + + it "considers the same model as an identical hash key" do + model_a = test_model_class.new(name: "John") + model_b = test_model_class.new(name: "John") + model_c = test_model_class.new(name: "Marie") + + test_hash = {} + test_hash[model_a] = "John" + test_hash[model_b] = "John" + test_hash[model_c] = "Marie" + + expect(test_hash.keys.size).to be(2) + expect(test_hash.keys).to eql([model_b, model_c]) + end end describe ".new" do