From 02f9a7d1003866fddc2d8069324bc2a6c394e04b Mon Sep 17 00:00:00 2001 From: BijenderKumar1 Date: Sun, 30 Jun 2024 11:48:18 +0000 Subject: [PATCH] Override equals function for Dynamic Value, Add comprehensive tests --- .../scala-2/zio/schema/DynamicValueSpec.scala | 33 ++++++++++++++++- .../main/scala/zio/schema/DynamicValue.scala | 37 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala index d6fcee057..f3c990dd4 100644 --- a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala +++ b/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala @@ -8,6 +8,18 @@ import zio.test.{ Sized, TestConfig, _ } object DynamicValueSpec extends ZIOSpecDefault { + case class Person(name: String, age: Int) + + object Person { + implicit val schema: Schema[Person] = DeriveSchema.gen[Person] + } + + case class User(name: String, age: Int) + + object User { + implicit val schema: Schema[User] = DeriveSchema.gen[User] + } + def spec: Spec[Environment, Any] = suite("DynamicValueSpec")( suite("round-trip")( @@ -101,12 +113,31 @@ object DynamicValueSpec extends ZIOSpecDefault { } } @@ TestAspect.size(250) @@ TestAspect.ignore ), - suite("hashCode consistency")( + suite("hashCode and equality consistency")( test("hashCode does not change") { val primitive1 = DynamicValue.Primitive(123, StandardType.IntType) val hash1 = primitive1.hashCode() val hash2 = primitive1.hashCode() assert(hash1)(equalTo(hash2)) + }, + test("equivalent DynamicValues have same hashCode and equality") { + val person1 = Person("John Doe", 42) + val person2 = Person("John Doe", 42) + + val dynamicPerson1 = DynamicValue.fromSchemaAndValue(Person.schema, person1) + val dynamicPerson2 = DynamicValue.fromSchemaAndValue(Person.schema, person2) + + assert(dynamicPerson1.hashCode())(equalTo(dynamicPerson2.hashCode())) && + assert(dynamicPerson1)(equalTo(dynamicPerson2)) + }, + test("different DynamicValues are not equal") { + val person1 = Person("John Doe", 42) + val person2 = Person("Jane Doe", 42) + + val dynamicPerson1 = DynamicValue.fromSchemaAndValue(Person.schema, person1) + val dynamicPerson2 = DynamicValue.fromSchemaAndValue(Person.schema, person2) + + assert(dynamicPerson1)(not(equalTo(dynamicPerson2))) } ) ) diff --git a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala index 2d5cab53d..1e4c00928 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala @@ -135,6 +135,43 @@ sealed trait DynamicValue { case DynamicValue.Error(message) => message.hashCode() case DynamicValue.Singleton(instance) => instance.hashCode() } + override def equals(obj: Any): Boolean = obj match { + case that: DynamicValue => + (this, that) match { + case (DynamicValue.Primitive(value1, standardType1), DynamicValue.Primitive(value2, standardType2)) => + value1 == value2 && standardType1 == standardType2 + case (DynamicValue.Record(id1, values1), DynamicValue.Record(id2, values2)) => + id1 == id2 && values1 == values2 + case (DynamicValue.Enumeration(id1, value1), DynamicValue.Enumeration(id2, value2)) => + id1 == id2 && value1 == value2 + case (DynamicValue.Sequence(values1), DynamicValue.Sequence(values2)) => + values1 == values2 + case (DynamicValue.Dictionary(entries1), DynamicValue.Dictionary(entries2)) => + entries1 == entries2 + case (DynamicValue.SetValue(values1), DynamicValue.SetValue(values2)) => + values1 == values2 + case (DynamicValue.SomeValue(value1), DynamicValue.SomeValue(value2)) => + value1 == value2 + case (DynamicValue.NoneValue, DynamicValue.NoneValue) => + true + case (DynamicValue.Tuple(left1, right1), DynamicValue.Tuple(left2, right2)) => + left1 == left2 && right1 == right2 + case (DynamicValue.LeftValue(value1), DynamicValue.LeftValue(value2)) => + value1 == value2 + case (DynamicValue.RightValue(value1), DynamicValue.RightValue(value2)) => + value1 == value2 + case (DynamicValue.BothValue(left1, right1), DynamicValue.BothValue(left2, right2)) => + left1 == left2 && right1 == right2 + case (DynamicValue.DynamicAst(ast1), DynamicValue.DynamicAst(ast2)) => + ast1 == ast2 + case (DynamicValue.Error(message1), DynamicValue.Error(message2)) => + message1 == message2 + case (DynamicValue.Singleton(instance1), DynamicValue.Singleton(instance2)) => + instance1 == instance2 + case _ => false + } + case _ => false + } }