diff --git a/kotlin-utils/build.gradle.kts b/kotlin-utils/build.gradle.kts index f701c2a0..e2f4a677 100644 --- a/kotlin-utils/build.gradle.kts +++ b/kotlin-utils/build.gradle.kts @@ -2,11 +2,11 @@ plugins { `java-library` `maven-publish` id("org.jetbrains.kotlin.jvm") version "1.5.31" - id("org.jlleitschuh.gradle.ktlint") version "10.3.0" // ktlint + id("org.jlleitschuh.gradle.ktlint") version "11.0.0" // ktlint } group = "xyz.lbres" -version = "0.3.1" +version = "0.4.0" repositories { mavenCentral() diff --git a/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSet.kt b/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSet.kt index 8770b55d..ffb18e05 100644 --- a/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSet.kt +++ b/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSet.kt @@ -6,5 +6,43 @@ package xyz.lbres.kotlinutils.set.multiset * Read/write access is available through the [MutableMultiSet] interface. */ interface MultiSet : Set { + /** + * All distinct values contained in the MultiSet + */ + val distinctValues: Set + + /** + * Get the number of occurrences of a given element. + * + * @param element [E] + * @return [Int]: The number of occurrences of [element]. 0 if the element does not exist. + */ fun getCountOf(element: E): Int + + /** + * Create a new MultiSet with values that are in this set but not the other set. + * If there are multiple occurrences of a value, the number of occurrences in the other set will be subtracted from the number in this MultiSet. + * + * @param other [MultiSet]<[E]>: values to subtract from this MultiSet + * @return [MultiSet]<[E]>: MultiSet containing the items in this MultiSet but not the other + */ + operator fun minus(other: MultiSet): MultiSet + + /** + * Create a new MultiSet with all values from both sets. + * If there are multiple occurrences of a value, the number of occurrences in the other set will be added to the number in this MultiSet. + * + * @param other [MultiSet]<[E]>: values to add to this MultiSet + * @return [MultiSet]<[E]>: MultiSet containing all values from both MultiSets + */ + operator fun plus(other: MultiSet): MultiSet + + /** + * Create a new MultiSet with values that are shared between the sets. + * If there are multiple occurrences of a value, the smaller number of occurrences will be used. + * + * @param other [MultiSet]<[E]>: values to intersect with this MultiSet + * @return [MultiSet]<[E]>: MultiSet containing only values that are in both MultiSets + */ + fun intersect(other: MultiSet): MultiSet } diff --git a/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImpl.kt b/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImpl.kt index 568210f2..893623cf 100644 --- a/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImpl.kt +++ b/kotlin-utils/src/main/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImpl.kt @@ -1,24 +1,32 @@ package xyz.lbres.kotlinutils.set.multiset +import kotlin.math.max +import kotlin.math.min + /** * Set implementation that allows multiple occurrences of the same value. */ -internal class MultiSetImpl constructor(elements: Collection) : MultiSet { +internal class MultiSetImpl : MultiSet { /** * Number of elements in set. */ - override val size: Int = elements.size + override val size: Int + + /** + * All distinct values contained in the MultiSet, without any counts + */ + override val distinctValues: Set /** * Store the number of occurrences of each element in set. * Counts are guaranteed to be greater than 0. */ - private val countsMap: HashMap + private val countsMap: Map /** * The initial elements that were passed to the constructor. */ - private val initialElements: Collection = elements + private val initialElements: Collection /** * String representation of the set. @@ -26,26 +34,43 @@ internal class MultiSetImpl constructor(elements: Collection) : MultiSet) { + size = elements.size + initialElements = elements + string = createString() // init counts val mutableMap: MutableMap = mutableMapOf() + val mutableValues: MutableSet = mutableSetOf() for (element in elements) { val currentCount = mutableMap[element] ?: 0 mutableMap[element] = currentCount + 1 + mutableValues.add(element) } - countsMap = HashMap(mutableMap) + // cast to simpler data structures + countsMap = mutableMap.toMap() + distinctValues = mutableValues.toSet() + } + + /** + * Initialize stored variables from an existing counts map. + */ + private constructor(counts: Map) { + countsMap = counts + size = counts.values.fold(0, Int::plus) + distinctValues = counts.keys + + initialElements = counts.flatMap { + val element = it.key + val count = it.value + List(count) { element } + } + + string = createString() } /** @@ -72,6 +97,59 @@ internal class MultiSetImpl constructor(elements: Collection) : MultiSet: MultiSet to subtract from current + * @return [MultiSet]<[E]>: MultiSet containing the items in this MultiSet but not the other + */ + override operator fun minus(other: MultiSet): MultiSet { + val newCounts = countsMap.keys.associateWith { + val count = getCountOf(it) + val otherCount = other.getCountOf(it) + max(count - otherCount, 0) + }.filter { it.value > 0 }.toMap() + + return MultiSetImpl(newCounts) + } + + /** + * Create a new MultiSet with all values from both sets. + * If there are multiple occurrences of a value, the number of occurrences in the other set will be added to the number in this MultiSet. + * + * @param other [MultiSet]<[E]>: MultiSet to add to current + * @return [MultiSet]<[E]>: MultiSet containing all values from both MultiSets + */ + override operator fun plus(other: MultiSet): MultiSet { + val allValues = distinctValues + other.distinctValues + + val newCounts = allValues.associateWith { + getCountOf(it) + other.getCountOf(it) + } + + return MultiSetImpl(newCounts) + } + + /** + * Create a new MultiSet with values that are shared between the sets. + * If there are multiple occurrences of a value, the smaller number of occurrences will be used. + * + * @param other [MultiSet]<[E]>: MultiSet to intersect with current + * @return [MultiSet]<[E]>: MultiSet containing only values that are in both MultiSets + */ + override fun intersect(other: MultiSet): MultiSet { + val allValues = distinctValues + other.distinctValues + + val newCounts = allValues.associateWith { + val count = getCountOf(it) + val otherCount = other.getCountOf(it) + min(count, otherCount) + }.filter { it.value > 0 }.toMap() + + return MultiSetImpl(newCounts) + } + /** * If the current set contains 0 elements. * @@ -80,7 +158,7 @@ internal class MultiSetImpl constructor(elements: Collection) : MultiSet constructor(elements: Collection) : MultiSet) { + if (other == null || other !is MultiSet<*>) { return false } - return countsMap == other.countsMap + return try { + other as MultiSet + return minus(other).distinctValues.isEmpty() && other.minus(this).distinctValues.isEmpty() + } catch (e: Exception) { + false + } + } + + /** + * Create the static string representation of the set. + * Stored in a helper so it can be reused in both constructors. + */ + private fun createString(): String { + if (initialElements.isEmpty()) { + return "[]" + } + + val elementsString = initialElements.joinToString(", ") + return "[$elementsString]" } /** @@ -115,5 +211,5 @@ internal class MultiSetImpl constructor(elements: Collection) : MultiSet constructor(elements: Collection) : MutableMultiSet { +internal class MutableMultiSetImpl : MutableMultiSet { /** * Number of elements in set. References a mutable variable. */ @@ -16,7 +17,13 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut /** * Mutable variable to store number of elements in the set. */ - private var storedSize: Int = elements.size + private var storedSize: Int + + /** + * All distinct values contained in the MultiSet, without any counts + */ + override val distinctValues: Set + get() = countsMap.keys /** * Store the number of occurrences of each element in set. @@ -41,9 +48,10 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut private var string: String /** - * Initialize stored variables. + * Initialize stored variables from a collection of values. */ - init { + constructor(elements: Collection) { + storedSize = elements.size countsMap = mutableMapOf() for (element in elements) { @@ -56,6 +64,19 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut updateList() } + /** + * Initialize stored variables from an existing counts map. + */ + private constructor(counts: Map) { + countsMap = counts.toMutableMap() + storedSize = counts.values.fold(0, Int::plus) + + // string and list are initialized in updateList + list = mutableListOf() + string = "" + updateList() + } + /** * Add one occurrence of the specified element to the set. * @@ -201,6 +222,59 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut return newSet.countsMap.all { countsMap.contains(it.key) && it.value <= getCountOf(it.key) } } + /** + * Create a new MultiSet with values that are in this set but not the other set. + * If there are multiple occurrences of a value, the number of occurrences in the other set will be subtracted from the number in this MultiSet. + * + * @param other [MultiSet]<[E]>: values to subtract from this MultiSet + * @return [MutableMultiSet]<[E]>: MultiSet containing the items in this MultiSet but not the other + */ + override operator fun minus(other: MultiSet): MutableMultiSet { + val newCounts = countsMap.keys.associateWith { + val count = getCountOf(it) + val otherCount = other.getCountOf(it) + max(count - otherCount, 0) + }.filter { it.value > 0 }.toMap() + + return MutableMultiSetImpl(newCounts) + } + + /** + * Create a new MultiSet with all values from both sets. + * If there are multiple occurrences of a value, the number of occurrences in the other set will be added to the number in this MultiSet. + * + * @param other [MultiSet]<[E]>: values to add to this MultiSet + * @return [MutableMultiSet]<[E]>: MultiSet containing all values from both MultiSets + */ + override operator fun plus(other: MultiSet): MutableMultiSet { + val allValues = distinctValues + other.distinctValues + + val newCounts = allValues.associateWith { + getCountOf(it) + other.getCountOf(it) + } + + return MutableMultiSetImpl(newCounts) + } + + /** + * Create a new MultiSet with values that are shared between the sets. + * If there are multiple occurrences of a value, the smaller number of occurrences will be used. + * + * @param other [MultiSet]<[E]>: values to intersect with the MultiSet + * @return [MutableMultiSet]<[E]>: MultiSet containing only values that are in both MultiSets + */ + override fun intersect(other: MultiSet): MutableMultiSet { + val allValues = distinctValues + other.distinctValues + + val newCounts = allValues.associateWith { + val count = getCountOf(it) + val otherCount = other.getCountOf(it) + min(count, otherCount) + }.filter { it.value > 0 }.toMap() + + return MutableMultiSetImpl(newCounts) + } + /** * Update the values of [list] and [string] to match the current values in the set. */ @@ -233,7 +307,7 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut override fun isEmpty(): Boolean = storedSize.isZero() /** - * Get the number of occurrences of a given element in the current set. + * Get the number of occurrences of a given element. * * @param element [E] * @return [Int]: the number of occurrences of [element]. 0 if the element does not exist. @@ -247,11 +321,16 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut * @return [Boolean]: true if [other] is a non-null MultiSet which contains the same values as the current set, false otherwise */ override fun equals(other: Any?): Boolean { - if (other == null || other !is MutableMultiSetImpl<*>) { + if (other == null || other !is MultiSet<*>) { return false } - return countsMap == other.countsMap + return try { + other as MultiSet + return minus(other).distinctValues.isEmpty() && other.minus(this).distinctValues.isEmpty() + } catch (e: Exception) { + false + } } /** @@ -274,5 +353,5 @@ internal class MutableMultiSetImpl constructor(elements: Collection) : Mut return string } - override fun hashCode(): Int = listOf("MutableMultiSet", countsMap).hashCode() + override fun hashCode(): Int = listOf(javaClass.name, countsMap).hashCode() } diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImplTest.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImplTest.kt index 3da041c3..29a0e39d 100644 --- a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImplTest.kt +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetImplTest.kt @@ -3,262 +3,23 @@ package xyz.lbres.kotlinutils.set.multiset import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue internal class MultiSetImplTest { - @Test - internal fun testConstructor() { - var set: MultiSet = MultiSetImpl(listOf()) - var expectedSize = 0 - assertEquals(expectedSize, set.size) - - set = MultiSetImpl(setOf(-12)) - expectedSize = 1 - assertEquals(expectedSize, set.size) - - set = MultiSetImpl(mutableListOf(10, 10, 10, 10)) - expectedSize = 4 - assertEquals(expectedSize, set.size) - - set = MultiSetImpl(listOf(-12, 18, 4, 10000, 25, 25, -1, 0, 5, 25)) - expectedSize = 10 - assertEquals(expectedSize, set.size) - - val errSet = MultiSetImpl(mutableSetOf(ArithmeticException(), NullPointerException())) - expectedSize = 2 - assertEquals(expectedSize, errSet.size) - - val listSet = MultiSetImpl(listOf(listOf(1, 3, 4), listOf(55, 66, 77))) - expectedSize = 2 - assertEquals(expectedSize, listSet.size) - } - - @Test - internal fun testEquals() { - // equals - var set1: MultiSet = multiSetOf() - assertEquals(set1, set1) - - set1 = multiSetOf(3) - assertEquals(set1, set1) - - set1 = multiSetOf(3, 3, 3) - assertEquals(set1, set1) - - set1 = multiSetOf(2, 3, 4) - assertEquals(set1, set1) - - set1 = multiSetOf(1, 2, 3) - var set2 = multiSetOf(3, 1, 2) - assertEquals(set1, set2) - assertEquals(set2, set1) - - // not equals - set1 = multiSetOf() - set2 = multiSetOf(0) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = multiSetOf(1, 1) - set2 = multiSetOf(1) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = multiSetOf(1, 2) - set2 = multiSetOf(2, 2) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = multiSetOf(-1, 3, 1, -3) - set2 = multiSetOf(2, -2) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - // other type - val stringSet1 = multiSetOf("", "abc") - assertEquals(stringSet1, stringSet1) - - val stringSet2 = multiSetOf("abc") - assertNotEquals(stringSet1, stringSet2) - assertNotEquals(stringSet2, stringSet1) - - val listSet1 = multiSetOf(listOf(12, 34, 56), listOf(77, 78, 0, 15), listOf(5)) - assertEquals(listSet1, listSet1) - - val listSet2 = multiSetOf(listOf(12, 34, 56)) - assertNotEquals(listSet1, listSet2) - assertNotEquals(listSet2, listSet1) - } - - @Test - internal fun testContains() { - var set: MultiSet = multiSetOf() - assertFalse(set.contains(0)) - assertFalse(set.contains(1000)) - assertFalse(set.contains(-1000)) - - set = multiSetOf(1, 2) - assertFalse(set.contains(0)) - assertTrue(set.contains(1)) - assertTrue(set.contains(2)) - - set = multiSetOf(1, 1, 1) - assertTrue(set.contains(1)) - assertFalse(set.contains(2)) - - val error = ArithmeticException() - val errSet = multiSetOf(ArithmeticException(), error, NumberFormatException()) - assertTrue(errSet.contains(error)) - - val listSet = multiSetOf(listOf(), listOf(5, 6), listOf(9, 8, 3)) - assertTrue(listSet.contains(listOf())) - assertTrue(listSet.contains(listOf(9, 8, 3))) - assertFalse(listSet.contains(listOf(6, 6))) - } - - @Test - internal fun testContainsAll() { - // equal - var set1: MultiSet = multiSetOf() - assertTrue(set1.containsAll(set1)) - - set1 = multiSetOf(-445) - assertTrue(set1.containsAll(set1)) - - set1 = multiSetOf(1, 1) - assertTrue(set1.containsAll(set1)) + @Test fun testConstructor() = runImmutableConstructorTests() + @Test fun testEquals() = runImmutableEqualsTests() - set1 = multiSetOf(2, 3, 2, 4, 3, 4, 4) - assertTrue(set1.containsAll(set1)) + @Test fun testContains() = runImmutableContainsTests() + @Test fun testContainsAll() = runImmutableContainsAllTests() - set1 = multiSetOf(1, 2, 3) - var set2 = multiSetOf(3, 1, 2) - assertTrue(set1.containsAll(set2)) - assertTrue(set2.containsAll(set1)) + @Test fun testMinus() = runImmutableMinusTests() + @Test fun testPlus() = runImmutablePlusTests() + @Test fun testIntersect() = runImmutableIntersectTests() - // subset - set1 = multiSetOf(1) - set2 = multiSetOf() - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(1, 2, 3, 4) - set2 = multiSetOf(1, 3) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(1, 1, 1) - set2 = multiSetOf(1, 1) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(1, 3, -1, 5) - set2 = multiSetOf(1, 3, 5) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - // overlap - set1 = multiSetOf(1, 2, 3) - set2 = multiSetOf(1, 3, 4) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(100, 100, 300, 400) - set2 = multiSetOf(100, 300, 400, 400) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(-10, 5, -10, -10) - set2 = multiSetOf(-10, -5, -10, -10) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - // no overlap - set1 = multiSetOf(1) - set2 = multiSetOf(2) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(1, 1, 1, 1) - set2 = multiSetOf(2, 2, 2, 2) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = multiSetOf(4, -4, 5, 7) - set2 = multiSetOf(22, 23, 22) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - } - - @Test - internal fun testIsEmpty() { - // empty - var intSet: MultiSet = multiSetOf() - assertTrue(intSet.isEmpty()) - - var stringSet: MultiSet = multiSetOf() - assertTrue(stringSet.isEmpty()) - - // not empty - intSet = multiSetOf(0) - assertFalse(intSet.isEmpty()) - - intSet = multiSetOf(1000, -1000, 4, 2, 4) - assertFalse(intSet.isEmpty()) - - intSet = multiSetOf(3, 3, 3) - assertFalse(intSet.isEmpty()) - - stringSet = multiSetOf("123", "abc") - assertFalse(stringSet.isEmpty()) - - stringSet = multiSetOf("abcdefg", "abcdefg") - assertFalse(stringSet.isEmpty()) - } - - @Test - internal fun testGetCountOf() { - var set: MultiSet = multiSetOf() - var expected = 0 - - var value = 0 - assertEquals(expected, set.getCountOf(value)) - - value = 100 - assertEquals(expected, set.getCountOf(value)) - - set = multiSetOf(2) - - value = 2 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - - value = 1 - expected = 0 - assertEquals(expected, set.getCountOf(value)) - - set = multiSetOf(1, 1, 2, 1, -4, 5, 2) - - value = 1 - expected = 3 - assertEquals(expected, set.getCountOf(value)) - - value = 2 - expected = 2 - assertEquals(expected, set.getCountOf(value)) - - value = -4 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - - value = 5 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - } + @Test fun testIsEmpty() = runImmutableIsEmptyTests() + @Test fun testGetCountOf() = runImmutableGetCountOfTests() @Test - internal fun testIterator() { + fun testIterator() { var set: MultiSet = multiSetOf() var iter = set.iterator() assertFalse(iter.hasNext()) @@ -283,7 +44,7 @@ internal class MultiSetImplTest { } @Test - internal fun testToString() { + fun testToString() { var set: MultiSet = emptyMultiSet() var expected = "[]" assertEquals(expected, set.toString()) diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetUtilsTest.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetUtilsTest.kt index 74908eed..848a72d4 100644 --- a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetUtilsTest.kt +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MultiSetUtilsTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals internal class MultiSetUtilsTest { @Test - internal fun testMultiSetOf() { + fun testMultiSetOf() { var set: MultiSet = multiSetOf() var expected: MultiSet = MultiSetImpl(listOf()) assertEquals(expected, set) @@ -29,10 +29,14 @@ internal class MultiSetUtilsTest { val listSet = multiSetOf(listOf(123), listOf(1, 4, 5, 6), listOf(99, 100, 97)) val listExpected = MultiSetImpl(listOf(listOf(123), listOf(1, 4, 5, 6), listOf(99, 100, 97))) assertEquals(listExpected, listSet) + + val compListSet = multiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListSetExpected = MultiSetImpl(listOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def"))) + assertEquals(compListSetExpected, compListSet) } @Test - internal fun testMutableMultiSetOf() { + fun testMutableMultiSetOf() { var set: MutableMultiSet = mutableMultiSetOf() var expected: MutableMultiSet = MutableMultiSetImpl(listOf()) assertEquals(expected, set) @@ -56,17 +60,21 @@ internal class MultiSetUtilsTest { val listSet = mutableMultiSetOf(listOf(123), listOf(1, 4, 5, 6), listOf(99, 100, 97)) val listExpected = MutableMultiSetImpl(listOf(listOf(123), listOf(1, 4, 5, 6), listOf(99, 100, 97))) assertEquals(listExpected, listSet) + + val compListSet = mutableMultiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListSetExpected = MutableMultiSetImpl(listOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def"))) + assertEquals(compListSetExpected, compListSet) } @Test - internal fun testEmptyMultiSet() { + fun testEmptyMultiSet() { val set = emptyMultiSet() val expected = multiSetOf() assertEquals(expected, set) } @Test - internal fun testMultiSet() { + fun testMultiSet() { var set = MultiSet(0) { 1 } var expectedSize = 0 var expected: MultiSet = emptyMultiSet() @@ -94,7 +102,7 @@ internal class MultiSetUtilsTest { } @Test - internal fun testMutableMultiSet() { + fun testMutableMultiSet() { var set = MutableMultiSet(0) { 5 } var expectedSize = 0 var expected: MutableMultiSet = mutableMultiSetOf() diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MutableMultiSetImplTest.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MutableMultiSetImplTest.kt index c6de6145..2a32f976 100644 --- a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MutableMultiSetImplTest.kt +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/MutableMultiSetImplTest.kt @@ -3,136 +3,30 @@ package xyz.lbres.kotlinutils.set.multiset import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue internal class MutableMultiSetImplTest { - @Test - internal fun testConstructor() { - var set: MutableMultiSet = MutableMultiSetImpl(listOf()) - var expectedSize = 0 - assertEquals(expectedSize, set.size) - - set = MutableMultiSetImpl(setOf(-12)) - expectedSize = 1 - assertEquals(expectedSize, set.size) - - set = MutableMultiSetImpl(mutableListOf(10, 10, 10, 10)) - expectedSize = 4 - assertEquals(expectedSize, set.size) - - set = MutableMultiSetImpl(listOf(-12, 18, 4, 10000, 25, 25, -1, 0, 5, 25)) - expectedSize = 10 - assertEquals(expectedSize, set.size) - - val errSet = MutableMultiSetImpl(mutableSetOf(ArithmeticException(), NullPointerException())) - expectedSize = 2 - assertEquals(expectedSize, errSet.size) - - val listSet = MutableMultiSetImpl(listOf(listOf(1, 3, 4), listOf(55, 66, 77))) - expectedSize = 2 - assertEquals(expectedSize, listSet.size) - } - - @Test - internal fun testEquals() { - // equals - var set1: MutableMultiSet = mutableMultiSetOf() - assertEquals(set1, set1) - - set1 = mutableMultiSetOf(3) - assertEquals(set1, set1) - - set1 = mutableMultiSetOf(3, 3, 3) - assertEquals(set1, set1) - - set1 = mutableMultiSetOf(2, 3, 4) - assertEquals(set1, set1) - - set1 = mutableMultiSetOf(1, 2, 3) - var set2 = mutableMultiSetOf(3, 1, 2) - assertEquals(set1, set2) - assertEquals(set2, set1) - - // not equals - set1 = mutableMultiSetOf() - set2 = mutableMultiSetOf(0) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = mutableMultiSetOf(1, 1) - set2 = mutableMultiSetOf(1) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = mutableMultiSetOf(1, 2) - set2 = mutableMultiSetOf(2, 2) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - set1 = mutableMultiSetOf(-1, 3, 1, -3) - set2 = mutableMultiSetOf(2, -2) - assertNotEquals(set1, set2) - assertNotEquals(set2, set1) - - // other type - val stringSet1 = mutableMultiSetOf("", "abc") - assertEquals(stringSet1, stringSet1) - - val stringSet2 = mutableMultiSetOf("abc") - assertNotEquals(stringSet1, stringSet2) - assertNotEquals(stringSet2, stringSet1) + @Test fun testConstructor() = runMutableConstructorTests() + @Test fun testEquals() = runMutableEqualsTests() - val listSet1 = mutableMultiSetOf(listOf(12, 34, 56), listOf(77, 78, 0, 15), listOf(5)) - assertEquals(listSet1, listSet1) + @Test fun testContains() = runMutableContainsTests() + @Test fun testContainsAll() = runMutableContainsAllTests() - val listSet2 = mutableMultiSetOf(listOf(12, 34, 56)) - assertNotEquals(listSet1, listSet2) - assertNotEquals(listSet2, listSet1) - } - - @Test - internal fun testGetCountOf() { - var set: MutableMultiSet = mutableMultiSetOf() - var expected = 0 - - var value = 0 - assertEquals(expected, set.getCountOf(value)) - - value = 100 - assertEquals(expected, set.getCountOf(value)) - - set = mutableMultiSetOf(2) - - value = 2 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - - value = 1 - expected = 0 - assertEquals(expected, set.getCountOf(value)) - - set = mutableMultiSetOf(1, 1, 2, 1, -4, 5, 2) + @Test fun testClear() = runClearTests() + @Test fun testAdd() = runAddTests() + @Test fun testAddAll() = runAddAllTests() + @Test fun testRemove() = runRemoveTests() + @Test fun testRemoveAll() = runRemoveAllTests() + @Test fun testRetainAll() = runRetainAllTests() - value = 1 - expected = 3 - assertEquals(expected, set.getCountOf(value)) + @Test fun testMinus() = runMutableMinusTests() + @Test fun testPlus() = runMutablePlusTests() + @Test fun testIntersect() = runMutableIntersectTests() - value = 2 - expected = 2 - assertEquals(expected, set.getCountOf(value)) - - value = -4 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - - value = 5 - expected = 1 - assertEquals(expected, set.getCountOf(value)) - } + @Test fun testIsEmpty() = runMutableIsEmptyTests() + @Test fun testGetCountOf() = runMutableGetCountOfTests() @Test - internal fun testIterator() { + fun testIterator() { var set: MutableMultiSet = mutableMultiSetOf() var iter = set.iterator() assertFalse(iter.hasNext()) @@ -174,185 +68,8 @@ internal class MutableMultiSetImplTest { assertEquals(expected.sorted(), values.sorted()) } - @Test internal fun testClear() = runClearTests() - @Test internal fun testAdd() = runAddTests() - @Test internal fun testAddAll() = runAddAllTests() - @Test internal fun testRemove() = runRemoveTests() - @Test internal fun testRemoveAll() = runRemoveAllTests() - @Test internal fun testRetainAll() = runRetainAllTests() - - @Test - internal fun testContains() { - var set: MutableMultiSet = mutableMultiSetOf() - assertFalse(set.contains(0)) - assertFalse(set.contains(1000)) - assertFalse(set.contains(-1000)) - - set = mutableMultiSetOf(1, 2) - assertFalse(set.contains(0)) - assertTrue(set.contains(1)) - assertTrue(set.contains(2)) - - set = mutableMultiSetOf(1, 1, 1) - assertTrue(set.contains(1)) - assertFalse(set.contains(2)) - - val error = ArithmeticException() - val errSet = mutableMultiSetOf(ArithmeticException(), error, NumberFormatException()) - assertTrue(errSet.contains(error)) - - val listSet = mutableMultiSetOf(listOf(), listOf(5, 6), listOf(9, 8, 3)) - assertTrue(listSet.contains(listOf())) - assertTrue(listSet.contains(listOf(9, 8, 3))) - assertFalse(listSet.contains(listOf(6, 6))) - - // adding elements - set = mutableMultiSetOf() - set.add(1) - assertTrue(set.contains(1)) - assertFalse(set.contains(2)) - set.add(2) - assertTrue(set.contains(2)) - } - - @Test - internal fun testContainsAll() { - // equal - var set1: MutableMultiSet = mutableMultiSetOf() - assertTrue(set1.containsAll(set1)) - - set1 = mutableMultiSetOf(-445) - assertTrue(set1.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 1) - assertTrue(set1.containsAll(set1)) - - set1 = mutableMultiSetOf(2, 3, 2, 4, 3, 4, 4) - assertTrue(set1.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 2, 3) - var set2 = mutableMultiSetOf(3, 1, 2) - assertTrue(set1.containsAll(set2)) - assertTrue(set2.containsAll(set1)) - - // subset - set1 = mutableMultiSetOf(1) - set2 = mutableMultiSetOf() - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 2, 3, 4) - set2 = mutableMultiSetOf(1, 3) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 1, 1) - set2 = mutableMultiSetOf(1, 1) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 3, -1, 5) - set2 = mutableMultiSetOf(1, 3, 5) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - // overlap - set1 = mutableMultiSetOf(1, 2, 3) - set2 = mutableMultiSetOf(1, 3, 4) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(100, 100, 300, 400) - set2 = mutableMultiSetOf(100, 300, 400, 400) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(-10, 5, -10, -10) - set2 = mutableMultiSetOf(-10, -5, -10, -10) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - // no overlap - set1 = mutableMultiSetOf(1) - set2 = mutableMultiSetOf(2) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(1, 1, 1, 1) - set2 = mutableMultiSetOf(2, 2, 2, 2) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1 = mutableMultiSetOf(4, -4, 5, 7) - set2 = mutableMultiSetOf(22, 23, 22) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - // adding elements - set1 = mutableMultiSetOf(1, 2, 3) - set2 = mutableMultiSetOf(2, 4) - assertFalse(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set1.add(4) - assertTrue(set1.containsAll(set2)) - assertFalse(set2.containsAll(set1)) - - set2.add(1) - set2.add(3) - assertTrue(set1.containsAll(set2)) - assertTrue(set2.containsAll(set1)) - } - - @Test - internal fun testIsEmpty() { - // empty - var intSet: MutableMultiSet = mutableMultiSetOf() - assertTrue(intSet.isEmpty()) - - var stringSet: MutableMultiSet = mutableMultiSetOf() - assertTrue(stringSet.isEmpty()) - - // not empty - intSet = mutableMultiSetOf(0) - assertFalse(intSet.isEmpty()) - - intSet = mutableMultiSetOf(1000, -1000, 4, 2, 4) - assertFalse(intSet.isEmpty()) - - intSet = mutableMultiSetOf(3, 3, 3) - assertFalse(intSet.isEmpty()) - - stringSet = mutableMultiSetOf("123", "abc") - assertFalse(stringSet.isEmpty()) - - stringSet = mutableMultiSetOf("abcdefg", "abcdefg") - assertFalse(stringSet.isEmpty()) - - // remove elements - intSet = mutableMultiSetOf(1) - intSet.remove(1) - assertTrue(intSet.isEmpty()) - - intSet = mutableMultiSetOf(1, 1) - intSet.remove(1) - assertFalse(intSet.isEmpty()) - intSet.remove(1) - assertTrue(intSet.isEmpty()) - - intSet = mutableMultiSetOf(2, 3) - intSet.remove(3) - assertFalse(intSet.isEmpty()) - intSet.remove(2) - assertTrue(intSet.isEmpty()) - - intSet = mutableMultiSetOf(2, 3) - intSet.clear() - assertTrue(intSet.isEmpty()) - } - @Test - internal fun testToString() { + fun testToString() { var set: MutableMultiSet = mutableMultiSetOf() var expected = "[]" assertEquals(expected, set.toString()) diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmatableBinaryTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmatableBinaryTests.kt new file mode 100644 index 00000000..48486875 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmatableBinaryTests.kt @@ -0,0 +1,253 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotEquals + +private val e1 = ArithmeticException() +private val e2 = NullPointerException() +private val e3 = IllegalArgumentException() + +internal fun runImmutableEqualsTests() { + // equals + var set1: MultiSet = multiSetOf() + assertEquals(set1, set1) + + set1 = multiSetOf(3) + assertEquals(set1, set1) + + set1 = multiSetOf(3, 3, 3) + assertEquals(set1, set1) + + set1 = multiSetOf(2, 3, 4) + assertEquals(set1, set1) + + set1 = multiSetOf(1, 2, 3) + var set2 = multiSetOf(3, 1, 2) + assertEquals(set1, set2) + assertEquals(set2, set1) + + // not equals + set1 = multiSetOf() + set2 = multiSetOf(0) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = multiSetOf(1, 1) + set2 = multiSetOf(1) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = multiSetOf(1, 2) + set2 = multiSetOf(2, 2) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = multiSetOf(-1, 3, 1, -3) + set2 = multiSetOf(2, -2) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + // other type + val stringSet1 = multiSetOf("", "abc") + assertEquals(stringSet1, stringSet1) + + val stringSet2 = multiSetOf("abc") + assertNotEquals(stringSet1, stringSet2) + assertNotEquals(stringSet2, stringSet1) + + val listSet1 = multiSetOf(listOf(12, 34, 56), listOf(77, 78, 0, 15), listOf(5)) + assertEquals(listSet1, listSet1) + + val listSet2 = multiSetOf(listOf(12, 34, 56)) + assertNotEquals(listSet1, listSet2) + assertNotEquals(listSet2, listSet1) + + assertFalse(stringSet1 == set1) + + // mutable + set1 = multiSetOf(1, 2, 3) + var mutableSet = mutableMultiSetOf(1, 2, 3) + assertEquals(set1, mutableSet) + + mutableSet = mutableMultiSetOf(1) + assertNotEquals(set1, mutableSet) +} + +internal fun runImmutableMinusTests() { + // empty + var intSet1 = emptyMultiSet() + var intSet2 = emptyMultiSet() + assertEquals(emptyMultiSet(), intSet1 - intSet2) + assertEquals(emptyMultiSet(), intSet2 - intSet1) + + intSet1 = multiSetOf(1, 2, 3, 3) + assertEquals(intSet1, intSet1 - intSet2) + assertEquals(emptyMultiSet(), intSet2 - intSet1) + + // equal + intSet1 = multiSetOf(1, 2, 3, 4, 5) + assertEquals(emptyMultiSet(), intSet1 - intSet1) + + var listSet1 = multiSetOf(listOf(1, 2, 3), listOf(456, 789)) + assertEquals(emptyMultiSet(), listSet1 - listSet1) + + // all shared + intSet1 = multiSetOf(1, 1, 2, 3, 4, 4, 4) + intSet2 = multiSetOf(1, 2, 2, 3, 4, 4) + var expectedInt = multiSetOf(1, 4) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = multiSetOf(2) + assertEquals(expectedInt, intSet2 - intSet1) + + intSet1 = multiSetOf(1, 2, 2, 2, 3, 3, 5, 6, 6, 7) + intSet2 = multiSetOf(1, 1, 2, 3, 3, 5, 5, 5, 6, 7, 7) + expectedInt = multiSetOf(2, 2, 6) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = multiSetOf(1, 5, 5, 7) + assertEquals(expectedInt, intSet2 - intSet1) + + // none shared + intSet1 = multiSetOf(1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 7, 8) + intSet2 = multiSetOf(-1, -1, -1, -1, -2, -3, -4, -5, -6, -7, -7, -8) + assertEquals(intSet1, intSet1 - intSet2) + assertEquals(intSet2, intSet2 - intSet1) + + val stringSet1 = multiSetOf("hello", "world", "goodbye", "world", "hello", "goodbye") + val stringSet2 = multiSetOf("greetings", "planet", "farewell", "planet", "greetings", "farewell") + assertEquals(stringSet1, stringSet1 - stringSet2) + assertEquals(stringSet2, stringSet2 - stringSet1) + + // some shared + intSet1 = multiSetOf(1, 1, 2, 3, 4, 5, 5) + intSet2 = multiSetOf(1, 1, 5, 6, 6, 7) + expectedInt = multiSetOf(2, 3, 4, 5) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = multiSetOf(6, 6, 7) + assertEquals(expectedInt, intSet2 - intSet1) + + listSet1 = multiSetOf(listOf(1, 2, 3), listOf(2, 3, 4), listOf(1, 2, 3)) + val listSet2: MultiSet> = multiSetOf(listOf(), listOf(1, 2, 3)) + var expectedList = multiSetOf(listOf(1, 2, 3), listOf(2, 3, 4)) + assertEquals(expectedList, listSet1 - listSet2) + expectedList = multiSetOf(listOf()) + assertEquals(expectedList, listSet2 - listSet1) + + val errorSet1: MultiSet = multiSetOf(e1, e2, e1, e1, e2) + val errorSet2: MultiSet = multiSetOf(e1, e3, e3, e1, e1) + var expectedError: MultiSet = multiSetOf(e2, e2) + assertEquals(expectedError, errorSet1 - errorSet2) + expectedError = multiSetOf(e3, e3) + assertEquals(expectedError, errorSet2 - errorSet1) + + val compListSet1: MultiSet>> = multiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListSet2: MultiSet>> = multiSetOf(listOf(1, 2, 3), listOf(1, 2, 3), listOf()) + var expectedCompList: MultiSet>> = multiSetOf(listOf("abc", "def"), listOf("abc", "def")) + assertEquals(expectedCompList, compListSet1 - compListSet2) + expectedCompList = multiSetOf(listOf(1, 2, 3), listOf()) + assertEquals(expectedCompList, compListSet2 - compListSet1) +} + +internal fun runImmutablePlusTests() { + // empty + var intSet1 = emptyMultiSet() + var intSet2 = emptyMultiSet() + assertEquals(emptyMultiSet(), intSet1 + intSet2) + assertEquals(emptyMultiSet(), intSet2 + intSet1) + + intSet1 = multiSetOf(1, 2, 3, 3) + assertEquals(intSet1, intSet1 + intSet2) + assertEquals(intSet1, intSet2 + intSet1) + + // non-empty + intSet1 = multiSetOf(1) + intSet2 = multiSetOf(1) + var expectedInt = multiSetOf(1, 1) + assertEquals(expectedInt, intSet1 + intSet2) + assertEquals(expectedInt, intSet2 + intSet1) + + intSet1 = multiSetOf(1, 2, 2, 3, 3, 3) + intSet2 = multiSetOf(1, 2, 0) + expectedInt = multiSetOf(0, 1, 1, 2, 2, 2, 3, 3, 3) + assertEquals(expectedInt, intSet1 + intSet2) + assertEquals(expectedInt, intSet2 + intSet1) + + val stringSet1 = multiSetOf("", "hello", "world", "goodbye") + val stringSet2 = multiSetOf("hi", "no", "bye") + val expectedString = multiSetOf("", "bye", "goodbye", "hello", "hi", "no", "world") + assertEquals(expectedString, stringSet1 + stringSet2) + assertEquals(expectedString, stringSet2 + stringSet1) + + val listSet1 = multiSetOf(listOf(-3), listOf(2, 3, 4), listOf(1, 2, 3)) + val listSet2 = multiSetOf(listOf(), listOf(1, 2, 3)) + val expectedList = multiSetOf(listOf(), listOf(-3), listOf(1, 2, 3), listOf(1, 2, 3), listOf(2, 3, 4)) + assertEquals(expectedList, listSet1 + listSet2) + assertEquals(expectedList, listSet2 + listSet1) + + val errorSet1: MultiSet = multiSetOf(e1, e2, e1, e2) + val errorSet2: MultiSet = multiSetOf(e1, e3, e3, e2, e1, e1) + val expectedError: MultiSet = multiSetOf(e1, e1, e1, e1, e1, e2, e2, e2, e3, e3) + assertEquals(expectedError, errorSet1 + errorSet2) + assertEquals(expectedError, errorSet2 + errorSet1) + + val compListSet1: MultiSet>> = multiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListSet2: MultiSet>> = multiSetOf(listOf(1, 2, 3), listOf(1, 2, 3), listOf()) + val expectedCompList: MultiSet>> = multiSetOf(listOf(), listOf(1, 2, 3), listOf(1, 2, 3), listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + assertEquals(expectedCompList, compListSet1 + compListSet2) + assertEquals(expectedCompList, compListSet2 + compListSet1) +} + +internal fun runImmutableIntersectTests() { + // empty + var intSet1 = emptyMultiSet() + + var intSet2 = emptyMultiSet() + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + + intSet2 = multiSetOf(1, 2, 3) + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + assertEquals(emptyMultiSet(), intSet2.intersect(intSet1)) + + // none shared + intSet1 = multiSetOf(1, 2, 3) + intSet2 = multiSetOf(4, 5, 6, 7, 8) + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + assertEquals(emptyMultiSet(), intSet2.intersect(intSet1)) + + var listSet1 = multiSetOf(listOf(1, 2, 3), listOf(4, 5)) + var listSet2 = multiSetOf(listOf(1, 2), listOf(3, 4, 5)) + assertEquals(emptyMultiSet(), listSet1.intersect(listSet2)) + assertEquals(emptyMultiSet(), listSet2.intersect(listSet1)) + + // all shared + intSet1 = multiSetOf(1, 2, 3) + intSet2 = multiSetOf(1, 2, 3) + var expectedInt = multiSetOf(1, 2, 3) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + intSet1 = multiSetOf(1, 1, 2, 2, 3, 3) + intSet2 = multiSetOf(1, 2, 2, 2, 3) + expectedInt = multiSetOf(1, 2, 2, 3) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + // some shared + intSet1 = multiSetOf(1, 2, 2, 4, 5, 6, 7, -1, 10) + intSet2 = multiSetOf(-1, 14, 3, 9, 9, 6) + expectedInt = multiSetOf(-1, 6) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + listSet1 = multiSetOf(listOf(1, 2, 3), listOf(2, 3, 4), listOf(1, 2, 3)) + listSet2 = multiSetOf(listOf(), listOf(1, 2, 3)) + val expectedList = multiSetOf(listOf(1, 2, 3)) + assertEquals(expectedList, listSet1.intersect(listSet2)) + assertEquals(expectedList, listSet2.intersect(listSet1)) + + val errorSet1: MultiSet = multiSetOf(e1, e2, e1, e2) + val errorSet2: MultiSet = multiSetOf(e1, e3, e3, e2, e1, e1) + val expectedError: MultiSet = multiSetOf(e1, e1, e2) + assertEquals(expectedError, errorSet1.intersect(errorSet2)) + assertEquals(expectedError, errorSet2.intersect(errorSet1)) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableConstructorTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableConstructorTests.kt new file mode 100644 index 00000000..38a66b75 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableConstructorTests.kt @@ -0,0 +1,50 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals + +internal fun runImmutableConstructorTests() { + var set: MultiSet = MultiSetImpl(listOf()) + var expectedSize = 0 + var expectedDistinct = emptySet() + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MultiSetImpl(setOf(-12)) + expectedSize = 1 + expectedDistinct = setOf(-12) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MultiSetImpl(mutableListOf(10, 10, 10, 10)) + expectedSize = 4 + expectedDistinct = setOf(10) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MultiSetImpl(listOf(-12, 18, 4, 10000, 25, 25, -1, 0, 5, 25)) + expectedSize = 10 + expectedDistinct = setOf(-12, 18, 4, 10000, 25, -1, 0, 5) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + val e1 = ArithmeticException() + val e2 = NullPointerException() + val e3 = ArithmeticException() + val errSet = MultiSetImpl(mutableSetOf(e1, e2, e3)) + expectedSize = 3 + val expectedErrDistinct = setOf(e1, e2, e3) + assertEquals(expectedSize, errSet.size) + assertEquals(expectedErrDistinct, errSet.distinctValues) + + val listSet = MultiSetImpl(listOf(listOf(1, 3, 4), listOf(55, 66, 77))) + expectedSize = 2 + val expectedListDistinct = setOf(listOf(1, 3, 4), listOf(55, 66, 77)) + assertEquals(expectedSize, listSet.size) + assertEquals(expectedListDistinct, listSet.distinctValues) + + val compListSet = MultiSetImpl(listOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def"))) + expectedSize = 3 + val expectedCompListDistinct = setOf(listOf(1, 2, 3), listOf("abc", "def")) + assertEquals(expectedSize, compListSet.size) + assertEquals(expectedCompListDistinct, compListSet.distinctValues) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableContainsTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableContainsTests.kt new file mode 100644 index 00000000..323ac835 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableContainsTests.kt @@ -0,0 +1,102 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +internal fun runImmutableContainsTests() { + var set: MultiSet = multiSetOf() + assertFalse(set.contains(0)) + assertFalse(set.contains(1000)) + assertFalse(set.contains(-1000)) + + set = multiSetOf(1, 2) + assertFalse(set.contains(0)) + assertTrue(set.contains(1)) + assertTrue(set.contains(2)) + + set = multiSetOf(1, 1, 1) + assertTrue(set.contains(1)) + assertFalse(set.contains(2)) + + val error = ArithmeticException() + val errSet = multiSetOf(ArithmeticException(), error, NumberFormatException()) + assertTrue(errSet.contains(error)) + + val listSet = multiSetOf(listOf(), listOf(5, 6), listOf(9, 8, 3)) + assertTrue(listSet.contains(listOf())) + assertTrue(listSet.contains(listOf(9, 8, 3))) + assertFalse(listSet.contains(listOf(6, 6))) +} + +internal fun runImmutableContainsAllTests() { + // equal + var set1: MultiSet = multiSetOf() + assertTrue(set1.containsAll(set1)) + + set1 = multiSetOf(-445) + assertTrue(set1.containsAll(set1)) + + set1 = multiSetOf(1, 1) + assertTrue(set1.containsAll(set1)) + + set1 = multiSetOf(2, 3, 2, 4, 3, 4, 4) + assertTrue(set1.containsAll(set1)) + + set1 = multiSetOf(1, 2, 3) + var set2 = multiSetOf(3, 1, 2) + assertTrue(set1.containsAll(set2)) + assertTrue(set2.containsAll(set1)) + + // subset + set1 = multiSetOf(1) + set2 = multiSetOf() + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(1, 2, 3, 4) + set2 = multiSetOf(1, 3) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(1, 1, 1) + set2 = multiSetOf(1, 1) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(1, 3, -1, 5) + set2 = multiSetOf(1, 3, 5) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + // overlap + set1 = multiSetOf(1, 2, 3) + set2 = multiSetOf(1, 3, 4) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(100, 100, 300, 400) + set2 = multiSetOf(100, 300, 400, 400) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(-10, 5, -10, -10) + set2 = multiSetOf(-10, -5, -10, -10) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + // no overlap + set1 = multiSetOf(1) + set2 = multiSetOf(2) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(1, 1, 1, 1) + set2 = multiSetOf(2, 2, 2, 2) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = multiSetOf(4, -4, 5, 7) + set2 = multiSetOf(22, 23, 22) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableUnaryTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableUnaryTests.kt new file mode 100644 index 00000000..a028c2f0 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runImmutableUnaryTests.kt @@ -0,0 +1,69 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +internal fun runImmutableIsEmptyTests() { + // empty + var intSet: MultiSet = multiSetOf() + assertTrue(intSet.isEmpty()) + + var stringSet: MultiSet = multiSetOf() + assertTrue(stringSet.isEmpty()) + + // not empty + intSet = multiSetOf(0) + assertFalse(intSet.isEmpty()) + + intSet = multiSetOf(1000, -1000, 4, 2, 4) + assertFalse(intSet.isEmpty()) + + intSet = multiSetOf(3, 3, 3) + assertFalse(intSet.isEmpty()) + + stringSet = multiSetOf("123", "abc") + assertFalse(stringSet.isEmpty()) + + stringSet = multiSetOf("abcdefg", "abcdefg") + assertFalse(stringSet.isEmpty()) +} + +internal fun runImmutableGetCountOfTests() { + var set: MultiSet = multiSetOf() + var expected = 0 + + var value = 0 + assertEquals(expected, set.getCountOf(value)) + + value = 100 + assertEquals(expected, set.getCountOf(value)) + + set = multiSetOf(2) + + value = 2 + expected = 1 + assertEquals(expected, set.getCountOf(value)) + + value = 1 + expected = 0 + assertEquals(expected, set.getCountOf(value)) + + set = multiSetOf(1, 1, 2, 1, -4, 5, 2) + + value = 1 + expected = 3 + assertEquals(expected, set.getCountOf(value)) + + value = 2 + expected = 2 + assertEquals(expected, set.getCountOf(value)) + + value = -4 + expected = 1 + assertEquals(expected, set.getCountOf(value)) + + value = 5 + expected = 1 + assertEquals(expected, set.getCountOf(value)) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableBinaryTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableBinaryTests.kt new file mode 100644 index 00000000..bbe03596 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableBinaryTests.kt @@ -0,0 +1,268 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotEquals + +private val e1 = ArithmeticException() +private val e2 = NullPointerException() +private val e3 = IllegalArgumentException() + +internal fun runMutableMinusTests() { + // empty + var intSet1 = mutableMultiSetOf() + var intSet2 = mutableMultiSetOf() + assertEquals(emptyMultiSet(), intSet1 - intSet2) + assertEquals(emptyMultiSet(), intSet2 - intSet1) + + intSet1 = mutableMultiSetOf(1, 2, 3, 3) + assertEquals(intSet1, intSet1 - intSet2) + assertEquals(emptyMultiSet(), intSet2 - intSet1) + + // equal + intSet1 = mutableMultiSetOf(1, 2, 3, 4, 5) + assertEquals(emptyMultiSet(), intSet1 - intSet1) + + var listSet1 = mutableMultiSetOf(listOf(1, 2, 3), listOf(456, 789)) + assertEquals(emptyMultiSet(), listSet1 - listSet1) + + // all shared + intSet1 = mutableMultiSetOf(1, 1, 2, 3, 4, 4, 4) + intSet2 = mutableMultiSetOf(1, 2, 2, 3, 4, 4) + var expectedInt = mutableMultiSetOf(1, 4) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = mutableMultiSetOf(2) + assertEquals(expectedInt, intSet2 - intSet1) + + intSet1 = mutableMultiSetOf(1, 2, 2, 2, 3, 3, 5, 6, 6, 7) + intSet2 = mutableMultiSetOf(1, 1, 2, 3, 3, 5, 5, 5, 6, 7, 7) + expectedInt = mutableMultiSetOf(2, 2, 6) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = mutableMultiSetOf(1, 5, 5, 7) + assertEquals(expectedInt, intSet2 - intSet1) + + // none shared + intSet1 = mutableMultiSetOf(1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 7, 8) + intSet2 = mutableMultiSetOf(-1, -1, -1, -1, -2, -3, -4, -5, -6, -7, -7, -8) + assertEquals(intSet1, intSet1 - intSet2) + assertEquals(intSet2, intSet2 - intSet1) + + val stringSet1 = mutableMultiSetOf("hello", "world", "goodbye", "world", "hello", "goodbye") + val stringSet2 = mutableMultiSetOf("greetings", "planet", "farewell", "planet", "greetings", "farewell") + assertEquals(stringSet1, stringSet1 - stringSet2) + assertEquals(stringSet2, stringSet2 - stringSet1) + + // some shared + intSet1 = mutableMultiSetOf(1, 1, 2, 3, 4, 5, 5) + intSet2 = mutableMultiSetOf(1, 1, 5, 6, 6, 7) + expectedInt = mutableMultiSetOf(2, 3, 4, 5) + assertEquals(expectedInt, intSet1 - intSet2) + expectedInt = mutableMultiSetOf(6, 6, 7) + assertEquals(expectedInt, intSet2 - intSet1) + + listSet1 = mutableMultiSetOf(listOf(1, 2, 3), listOf(2, 3, 4), listOf(1, 2, 3)) + val listSet2: MutableMultiSet> = mutableMultiSetOf(listOf(), listOf(1, 2, 3)) + var expectedList = mutableMultiSetOf(listOf(1, 2, 3), listOf(2, 3, 4)) + assertEquals(expectedList, listSet1 - listSet2) + expectedList = mutableMultiSetOf(listOf()) + assertEquals(expectedList, listSet2 - listSet1) + + val errorSet1: MutableMultiSet = mutableMultiSetOf(e1, e2, e1, e1, e2) + val errorSet2: MutableMultiSet = mutableMultiSetOf(e1, e3, e3, e1, e1) + var expectedError: MutableMultiSet = mutableMultiSetOf(e2, e2) + assertEquals(expectedError, errorSet1 - errorSet2) + expectedError = mutableMultiSetOf(e3, e3) + assertEquals(expectedError, errorSet2 - errorSet1) + + val compListMs1: MutableMultiSet>> = mutableMultiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListMs2: MutableMultiSet>> = mutableMultiSetOf(listOf(1, 2, 3), listOf(1, 2, 3), listOf()) + var compListExpected: MutableMultiSet>> = mutableMultiSetOf(listOf("abc", "def"), listOf("abc", "def")) + assertEquals(compListExpected, compListMs1 - compListMs2) + compListExpected = mutableMultiSetOf(listOf(1, 2, 3), listOf()) + assertEquals(compListExpected, compListMs2 - compListMs1) + + // with immutable + intSet1 = mutableMultiSetOf(1, 2, 3, 4) + val immutable = multiSetOf(1, 4, 4, 5) + expectedInt = mutableMultiSetOf(2, 3) + assertEquals(expectedInt, intSet1 - immutable) +} + +internal fun runMutablePlusTests() { + // empty + var intSet1 = emptyMultiSet() + var intSet2 = emptyMultiSet() + assertEquals(emptyMultiSet(), intSet1 + intSet2) + assertEquals(emptyMultiSet(), intSet2 + intSet1) + + intSet1 = mutableMultiSetOf(1, 2, 3, 3) + assertEquals(intSet1, intSet1 + intSet2) + + // non-empty + intSet1 = mutableMultiSetOf(1) + intSet2 = mutableMultiSetOf(1) + var expected = mutableMultiSetOf(1, 1) + assertEquals(expected, intSet1 + intSet2) + + intSet1 = mutableMultiSetOf(1, 2, 2, 3, 3, 3) + intSet2 = mutableMultiSetOf(1, 2, 0) + expected = mutableMultiSetOf(0, 1, 1, 2, 2, 2, 3, 3, 3) + assertEquals(expected, intSet1 + intSet2) + + val sms1 = mutableMultiSetOf("", "hello", "world", "goodbye") + val sms2 = mutableMultiSetOf("hi", "no", "bye") + val sExpected = mutableMultiSetOf("", "bye", "goodbye", "hello", "hi", "no", "world") + assertEquals(sExpected, sms1 + sms2) + assertEquals(sExpected, sms2 + sms1) + + val listSet1 = mutableMultiSetOf(listOf(-3), listOf(2, 3, 4), listOf(1, 2, 3)) + val listSet2 = mutableMultiSetOf(listOf(), listOf(1, 2, 3)) + val expectedList = mutableMultiSetOf(listOf(), listOf(-3), listOf(1, 2, 3), listOf(1, 2, 3), listOf(2, 3, 4)) + assertEquals(expectedList, listSet1 + listSet2) + assertEquals(expectedList, listSet2 + listSet1) + + val errorSet1: MutableMultiSet = mutableMultiSetOf(e1, e2, e1, e2) + val errorSet2: MutableMultiSet = mutableMultiSetOf(e1, e3, e3, e2, e1, e1) + val expectedError: MutableMultiSet = mutableMultiSetOf(e1, e1, e1, e1, e1, e2, e2, e2, e3, e3) + assertEquals(expectedError, errorSet1 + errorSet2) + assertEquals(expectedError, errorSet2 + errorSet1) + + val compListMs1: MutableMultiSet>> = mutableMultiSetOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + val compListMs2: MutableMultiSet>> = mutableMultiSetOf(listOf(1, 2, 3), listOf(1, 2, 3), listOf()) + val compListExpected: MutableMultiSet>> = mutableMultiSetOf(listOf(), listOf(1, 2, 3), listOf(1, 2, 3), listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def")) + assertEquals(compListExpected, compListMs1 + compListMs2) + assertEquals(compListExpected, compListMs2 + compListMs1) + + // with immutable + intSet1 = mutableMultiSetOf(1, 2, 3) + val immutable = multiSetOf(1, 4, 5) + expected = mutableMultiSetOf(1, 1, 2, 3, 4, 5) + assertEquals(expected, intSet1 + immutable) +} + +internal fun runMutableIntersectTests() { + // empty + var intSet1 = emptyMultiSet() + + var intSet2 = emptyMultiSet() + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + + intSet2 = mutableMultiSetOf(1, 2, 3) + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + assertEquals(emptyMultiSet(), intSet2.intersect(intSet1)) + + // none shared + intSet1 = mutableMultiSetOf(1, 2, 3) + intSet2 = mutableMultiSetOf(4, 5, 6, 7, 8) + assertEquals(emptyMultiSet(), intSet1.intersect(intSet2)) + assertEquals(emptyMultiSet(), intSet2.intersect(intSet1)) + + var listSet1 = mutableMultiSetOf(listOf(1, 2, 3), listOf(4, 5)) + var listSet2 = mutableMultiSetOf(listOf(1, 2), listOf(3, 4, 5)) + assertEquals(emptyMultiSet(), listSet1.intersect(listSet2)) + assertEquals(emptyMultiSet(), listSet2.intersect(listSet1)) + + // all shared + intSet1 = mutableMultiSetOf(1, 2, 3) + intSet2 = mutableMultiSetOf(1, 2, 3) + var expectedInt = mutableMultiSetOf(1, 2, 3) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + intSet1 = mutableMultiSetOf(1, 1, 2, 2, 3, 3) + intSet2 = mutableMultiSetOf(1, 2, 2, 2, 3) + expectedInt = mutableMultiSetOf(1, 2, 2, 3) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + // some shared + intSet1 = mutableMultiSetOf(1, 2, 2, 4, 5, 6, 7, -1, 10) + intSet2 = mutableMultiSetOf(-1, 14, 3, 9, 9, 6) + expectedInt = mutableMultiSetOf(-1, 6) + assertEquals(expectedInt, intSet1.intersect(intSet2)) + assertEquals(expectedInt, intSet2.intersect(intSet1)) + + listSet1 = mutableMultiSetOf(listOf(1, 2, 3), listOf(2, 3, 4), listOf(1, 2, 3)) + listSet2 = mutableMultiSetOf(listOf(), listOf(1, 2, 3)) + val expectedList = mutableMultiSetOf(listOf(1, 2, 3)) + assertEquals(expectedList, listSet1.intersect(listSet2)) + assertEquals(expectedList, listSet2.intersect(listSet1)) + + val errorSet1: MutableMultiSet = mutableMultiSetOf(e1, e2, e1, e2) + val errorSet2: MutableMultiSet = mutableMultiSetOf(e1, e3, e3, e2, e1, e1) + val expectedError: MutableMultiSet = mutableMultiSetOf(e1, e1, e2) + assertEquals(expectedError, errorSet1.intersect(errorSet2)) + assertEquals(expectedError, errorSet2.intersect(errorSet1)) + + // with immutable + intSet1 = mutableMultiSetOf(1, 2, 3, 4) + val immutable = multiSetOf(1, 4, 4, 5) + expectedInt = mutableMultiSetOf(1, 4) + assertEquals(expectedInt, intSet1.intersect(immutable)) +} + +internal fun runMutableEqualsTests() { + // equals + var set1: MutableMultiSet = mutableMultiSetOf() + assertEquals(set1, set1) + + set1 = mutableMultiSetOf(3) + assertEquals(set1, set1) + + set1 = mutableMultiSetOf(3, 3, 3) + assertEquals(set1, set1) + + set1 = mutableMultiSetOf(2, 3, 4) + assertEquals(set1, set1) + + set1 = mutableMultiSetOf(1, 2, 3) + var set2 = mutableMultiSetOf(3, 1, 2) + assertEquals(set1, set2) + assertEquals(set2, set1) + + // not equals + set1 = mutableMultiSetOf() + set2 = mutableMultiSetOf(0) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = mutableMultiSetOf(1, 1) + set2 = mutableMultiSetOf(1) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = mutableMultiSetOf(1, 2) + set2 = mutableMultiSetOf(2, 2) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + set1 = mutableMultiSetOf(-1, 3, 1, -3) + set2 = mutableMultiSetOf(2, -2) + assertNotEquals(set1, set2) + assertNotEquals(set2, set1) + + // other type + val stringSet1 = mutableMultiSetOf("", "abc") + assertEquals(stringSet1, stringSet1) + + val stringSet2 = mutableMultiSetOf("abc") + assertNotEquals(stringSet1, stringSet2) + assertNotEquals(stringSet2, stringSet1) + + val listSet1 = mutableMultiSetOf(listOf(12, 34, 56), listOf(77, 78, 0, 15), listOf(5)) + assertEquals(listSet1, listSet1) + + val listSet2 = mutableMultiSetOf(listOf(12, 34, 56)) + assertNotEquals(listSet1, listSet2) + assertNotEquals(listSet2, listSet1) + + assertFalse(set1 == stringSet1) + + // immutable + set1 = mutableMultiSetOf(1, 2, 3) + var immutableSet = multiSetOf(1, 2, 3) + assertEquals(set1, immutableSet) + + immutableSet = multiSetOf(1) + assertNotEquals(set1, immutableSet) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableConstructorTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableConstructorTests.kt new file mode 100644 index 00000000..554c45b5 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableConstructorTests.kt @@ -0,0 +1,50 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals + +internal fun runMutableConstructorTests() { + var set: MutableMultiSet = MutableMultiSetImpl(listOf()) + var expectedSize = 0 + var expectedDistinct = emptySet() + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MutableMultiSetImpl(setOf(-12)) + expectedSize = 1 + expectedDistinct = setOf(-12) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MutableMultiSetImpl(mutableListOf(10, 10, 10, 10)) + expectedSize = 4 + expectedDistinct = setOf(10) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + set = MutableMultiSetImpl(listOf(-12, 18, 4, 10000, 25, 25, -1, 0, 5, 25)) + expectedSize = 10 + expectedDistinct = setOf(-12, 18, 4, 10000, 25, -1, 0, 5) + assertEquals(expectedSize, set.size) + assertEquals(expectedDistinct, set.distinctValues) + + val e1 = ArithmeticException() + val e2 = NullPointerException() + val e3 = ArithmeticException() + val errSet = MutableMultiSetImpl(mutableSetOf(e1, e2, e3)) + expectedSize = 3 + val expectedErrDistinct = setOf(e1, e2, e3) + assertEquals(expectedSize, errSet.size) + assertEquals(expectedErrDistinct, errSet.distinctValues) + + val listSet = MutableMultiSetImpl(listOf(listOf(1, 3, 4), listOf(55, 66, 77))) + expectedSize = 2 + val expectedListDistinct = setOf(listOf(1, 3, 4), listOf(55, 66, 77)) + assertEquals(expectedSize, listSet.size) + assertEquals(expectedListDistinct, listSet.distinctValues) + + val compListSet = MutableMultiSetImpl(listOf(listOf(1, 2, 3), listOf("abc", "def"), listOf("abc", "def"))) + expectedSize = 3 + val expectedCompListDistinct = setOf(listOf(1, 2, 3), listOf("abc", "def")) + assertEquals(expectedSize, compListSet.size) + assertEquals(expectedCompListDistinct, compListSet.distinctValues) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableContainsTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableContainsTests.kt new file mode 100644 index 00000000..87a5ab30 --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableContainsTests.kt @@ -0,0 +1,125 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +internal fun runMutableContainsTests() { + var set: MutableMultiSet = mutableMultiSetOf() + assertFalse(set.contains(0)) + assertFalse(set.contains(1000)) + assertFalse(set.contains(-1000)) + + set = mutableMultiSetOf(1, 2) + assertFalse(set.contains(0)) + assertTrue(set.contains(1)) + assertTrue(set.contains(2)) + + set = mutableMultiSetOf(1, 1, 1) + assertTrue(set.contains(1)) + assertFalse(set.contains(2)) + + val error = ArithmeticException() + val errSet = mutableMultiSetOf(ArithmeticException(), error, NumberFormatException()) + assertTrue(errSet.contains(error)) + + val listSet = mutableMultiSetOf(listOf(), listOf(5, 6), listOf(9, 8, 3)) + assertTrue(listSet.contains(listOf())) + assertTrue(listSet.contains(listOf(9, 8, 3))) + assertFalse(listSet.contains(listOf(6, 6))) + + // adding elements + set = mutableMultiSetOf() + set.add(1) + assertTrue(set.contains(1)) + assertFalse(set.contains(2)) + set.add(2) + assertTrue(set.contains(2)) +} + +internal fun runMutableContainsAllTests() { + // equal + var set1: MutableMultiSet = mutableMultiSetOf() + assertTrue(set1.containsAll(set1)) + + set1 = mutableMultiSetOf(-445) + assertTrue(set1.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 1) + assertTrue(set1.containsAll(set1)) + + set1 = mutableMultiSetOf(2, 3, 2, 4, 3, 4, 4) + assertTrue(set1.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 2, 3) + var set2 = mutableMultiSetOf(3, 1, 2) + assertTrue(set1.containsAll(set2)) + assertTrue(set2.containsAll(set1)) + + // subset + set1 = mutableMultiSetOf(1) + set2 = mutableMultiSetOf() + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 2, 3, 4) + set2 = mutableMultiSetOf(1, 3) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 1, 1) + set2 = mutableMultiSetOf(1, 1) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 3, -1, 5) + set2 = mutableMultiSetOf(1, 3, 5) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + // overlap + set1 = mutableMultiSetOf(1, 2, 3) + set2 = mutableMultiSetOf(1, 3, 4) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(100, 100, 300, 400) + set2 = mutableMultiSetOf(100, 300, 400, 400) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(-10, 5, -10, -10) + set2 = mutableMultiSetOf(-10, -5, -10, -10) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + // no overlap + set1 = mutableMultiSetOf(1) + set2 = mutableMultiSetOf(2) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(1, 1, 1, 1) + set2 = mutableMultiSetOf(2, 2, 2, 2) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1 = mutableMultiSetOf(4, -4, 5, 7) + set2 = mutableMultiSetOf(22, 23, 22) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + // adding elements + set1 = mutableMultiSetOf(1, 2, 3) + set2 = mutableMultiSetOf(2, 4) + assertFalse(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set1.add(4) + assertTrue(set1.containsAll(set2)) + assertFalse(set2.containsAll(set1)) + + set2.add(1) + set2.add(3) + assertTrue(set1.containsAll(set2)) + assertTrue(set2.containsAll(set1)) +} diff --git a/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableUnaryTests.kt b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableUnaryTests.kt new file mode 100644 index 00000000..17a466eb --- /dev/null +++ b/kotlin-utils/src/test/kotlin/xyz/lbres/kotlinutils/set/multiset/runMutableUnaryTests.kt @@ -0,0 +1,90 @@ +package xyz.lbres.kotlinutils.set.multiset + +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +internal fun runMutableIsEmptyTests() { + // empty + var intSet: MutableMultiSet = mutableMultiSetOf() + assertTrue(intSet.isEmpty()) + + var stringSet: MutableMultiSet = mutableMultiSetOf() + assertTrue(stringSet.isEmpty()) + + // not empty + intSet = mutableMultiSetOf(0) + assertFalse(intSet.isEmpty()) + + intSet = mutableMultiSetOf(1000, -1000, 4, 2, 4) + assertFalse(intSet.isEmpty()) + + intSet = mutableMultiSetOf(3, 3, 3) + assertFalse(intSet.isEmpty()) + + stringSet = mutableMultiSetOf("123", "abc") + assertFalse(stringSet.isEmpty()) + + stringSet = mutableMultiSetOf("abcdefg", "abcdefg") + assertFalse(stringSet.isEmpty()) + + // remove elements + intSet = mutableMultiSetOf(1) + intSet.remove(1) + assertTrue(intSet.isEmpty()) + + intSet = mutableMultiSetOf(1, 1) + intSet.remove(1) + assertFalse(intSet.isEmpty()) + intSet.remove(1) + assertTrue(intSet.isEmpty()) + + intSet = mutableMultiSetOf(2, 3) + intSet.remove(3) + assertFalse(intSet.isEmpty()) + intSet.remove(2) + assertTrue(intSet.isEmpty()) + + intSet = mutableMultiSetOf(2, 3) + intSet.clear() + assertTrue(intSet.isEmpty()) +} + +internal fun runMutableGetCountOfTests() { + var set: MutableMultiSet = mutableMultiSetOf() + var expected = 0 + + var value = 0 + assertEquals(expected, set.getCountOf(value)) + + value = 100 + assertEquals(expected, set.getCountOf(value)) + + set = mutableMultiSetOf(2) + + value = 2 + expected = 1 + assertEquals(expected, set.getCountOf(value)) + + value = 1 + expected = 0 + assertEquals(expected, set.getCountOf(value)) + + set = mutableMultiSetOf(1, 1, 2, 1, -4, 5, 2) + + value = 1 + expected = 3 + assertEquals(expected, set.getCountOf(value)) + + value = 2 + expected = 2 + assertEquals(expected, set.getCountOf(value)) + + value = -4 + expected = 1 + assertEquals(expected, set.getCountOf(value)) + + value = 5 + expected = 1 + assertEquals(expected, set.getCountOf(value)) +}