diff --git a/enumset/src/commonMain/kotlin/EnumSet32.kt b/enumset/src/commonMain/kotlin/EnumSet32.kt index 4c0f6ce..42be9ac 100644 --- a/enumset/src/commonMain/kotlin/EnumSet32.kt +++ b/enumset/src/commonMain/kotlin/EnumSet32.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, OpenSavvy and contributors. + * Copyright (c) 2025-2026, OpenSavvy and contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,19 @@ internal class EnumSet32> private constructor( override fun toString(): String = this.joinToString(", ", "[", "]") + override fun equals(other: Any?): Boolean { + if (other === null) return false + if (other === this) return true + if (other is EnumSet32<*>) return entries == other.entries && set == other.set + if (other !is Set<*>) return false + + return size == other.size && + this.containsAll(other) + } + + override fun hashCode(): Int = + sumOf { it.hashCode() } + companion object { internal fun > of(elements: Iterable, entries: EnumEntries): EnumSet32 { diff --git a/enumset/src/commonTest/kotlin/datatypes/EnumSetSuite.kt b/enumset/src/commonTest/kotlin/datatypes/EnumSetSuite.kt index 96dee98..fac07cb 100644 --- a/enumset/src/commonTest/kotlin/datatypes/EnumSetSuite.kt +++ b/enumset/src/commonTest/kotlin/datatypes/EnumSetSuite.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, OpenSavvy and contributors. + * Copyright (c) 2025-2026, OpenSavvy and contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,8 @@ import opensavvy.prepared.suite.prepared import opensavvy.prepared.suite.random.random import opensavvy.prepared.suite.random.randomInt import kotlin.enums.EnumEntries +import kotlin.random.Random +import kotlin.random.nextInt fun > SuiteDsl.testEnumSetValidity( name: String, @@ -151,6 +153,59 @@ fun > SuiteDsl.testEnumSetValidity( } testFullEnumSetValidity(name, entries, set) } + + suite("Identity") { + val itemCounts = listOf( + 0, + 1, + 2, + Random.nextInt(0..entries.size), + entries.size / 2, + entries.size, + ) + + for (itemCount in itemCounts) suite("$itemCount items") { + /** + * A set of size `itemCount` with random items. + * + * This is a standard set, used as a control for this test. + */ + val hashSet by prepared { + val allItems = entries.toMutableList() + random.use { allItems.shuffle() } + + val items = HashSet() + repeat(itemCount) { + items.add(allItems.removeLast()) + } + + items + } + + /** + * The test implementation we want to test, with the same content as `hashSet`. + */ + val testedSet by prepared { + create(hashSet()) + } + + test("Equals") { + check(hashSet() == testedSet()) { "A HashSet should detect that it has the same elements as the tested set" } + check(testedSet() == hashSet()) { "The tested set should detect that it has the same elements as the HashSet" } + } + + test("Equals: fast-paths") { + check(testedSet() == testedSet()) { "The tested set itself is equal to itself" } + check(testedSet() == create(hashSet())) { "The tested set is equal to another set of the same type with the same elements" } + check(!testedSet().equals(null)) + check(testedSet() != Any()) + } + + test("HashCode") { + check(hashSet().hashCode() == testedSet().hashCode()) + } + } + } } fun > SuiteDsl.testEmptyEnumSetValidity(