Best Kotest code snippet using io.kotest.matchers.collections.decreasing.test
CollectionMatchersTest.kt
Source:CollectionMatchersTest.kt
1package com.sksamuel.kotest.matchers.collections2import io.kotest.assertions.shouldFail3import io.kotest.assertions.throwables.shouldNotThrow4import io.kotest.assertions.throwables.shouldThrow5import io.kotest.assertions.withClue6import io.kotest.core.spec.style.WordSpec7import io.kotest.equals.Equality8import io.kotest.equals.types.byObjectEquality9import io.kotest.matchers.collections.atLeastSize10import io.kotest.matchers.collections.atMostSize11import io.kotest.matchers.collections.beLargerThan12import io.kotest.matchers.collections.beSameSizeAs13import io.kotest.matchers.collections.beSmallerThan14import io.kotest.matchers.collections.contain15import io.kotest.matchers.collections.containDuplicates16import io.kotest.matchers.collections.containNoNulls17import io.kotest.matchers.collections.containNull18import io.kotest.matchers.collections.containOnlyNulls19import io.kotest.matchers.collections.matchInOrder20import io.kotest.matchers.collections.existInOrder21import io.kotest.matchers.collections.haveElementAt22import io.kotest.matchers.collections.haveSize23import io.kotest.matchers.collections.matchEach24import io.kotest.matchers.collections.matchInOrderSubset25import io.kotest.matchers.collections.monotonicallyDecreasing26import io.kotest.matchers.collections.monotonicallyDecreasingWith27import io.kotest.matchers.collections.monotonicallyIncreasing28import io.kotest.matchers.collections.monotonicallyIncreasingWith29import io.kotest.matchers.collections.shouldBeIn30import io.kotest.matchers.collections.shouldBeLargerThan31import io.kotest.matchers.collections.shouldBeMonotonicallyDecreasing32import io.kotest.matchers.collections.shouldBeMonotonicallyDecreasingWith33import io.kotest.matchers.collections.shouldBeMonotonicallyIncreasing34import io.kotest.matchers.collections.shouldBeMonotonicallyIncreasingWith35import io.kotest.matchers.collections.shouldBeSameSizeAs36import io.kotest.matchers.collections.shouldBeSingleton37import io.kotest.matchers.collections.shouldBeSmallerThan38import io.kotest.matchers.collections.shouldBeSorted39import io.kotest.matchers.collections.shouldBeSortedBy40import io.kotest.matchers.collections.shouldBeSortedWith41import io.kotest.matchers.collections.shouldBeStrictlyDecreasing42import io.kotest.matchers.collections.shouldBeStrictlyDecreasingWith43import io.kotest.matchers.collections.shouldBeStrictlyIncreasing44import io.kotest.matchers.collections.shouldBeStrictlyIncreasingWith45import io.kotest.matchers.collections.shouldContainAnyOf46import io.kotest.matchers.collections.shouldContainDuplicates47import io.kotest.matchers.collections.shouldContainNoNulls48import io.kotest.matchers.collections.shouldContainNull49import io.kotest.matchers.collections.shouldContainOnlyNulls50import io.kotest.matchers.collections.shouldExist51import io.kotest.matchers.collections.shouldHaveAtLeastSize52import io.kotest.matchers.collections.shouldHaveAtMostSize53import io.kotest.matchers.collections.shouldHaveElementAt54import io.kotest.matchers.collections.shouldHaveSingleElement55import io.kotest.matchers.collections.shouldHaveSize56import io.kotest.matchers.collections.shouldMatchInOrder57import io.kotest.matchers.collections.shouldMatchInOrderSubset58import io.kotest.matchers.collections.shouldNotBeIn59import io.kotest.matchers.collections.shouldNotBeMonotonicallyDecreasing60import io.kotest.matchers.collections.shouldNotBeMonotonicallyDecreasingWith61import io.kotest.matchers.collections.shouldNotBeMonotonicallyIncreasing62import io.kotest.matchers.collections.shouldNotBeMonotonicallyIncreasingWith63import io.kotest.matchers.collections.shouldNotBeSingleton64import io.kotest.matchers.collections.shouldNotBeSorted65import io.kotest.matchers.collections.shouldNotBeSortedBy66import io.kotest.matchers.collections.shouldNotBeSortedWith67import io.kotest.matchers.collections.shouldNotBeStrictlyDecreasing68import io.kotest.matchers.collections.shouldNotBeStrictlyDecreasingWith69import io.kotest.matchers.collections.shouldNotBeStrictlyIncreasing70import io.kotest.matchers.collections.shouldNotBeStrictlyIncreasingWith71import io.kotest.matchers.collections.shouldNotContainAnyOf72import io.kotest.matchers.collections.shouldNotContainDuplicates73import io.kotest.matchers.collections.shouldNotContainNoNulls74import io.kotest.matchers.collections.shouldNotContainNull75import io.kotest.matchers.collections.shouldNotContainOnlyNulls76import io.kotest.matchers.collections.shouldNotHaveElementAt77import io.kotest.matchers.collections.shouldNotHaveSize78import io.kotest.matchers.collections.shouldNotMatchEach79import io.kotest.matchers.collections.shouldNotMatchInOrder80import io.kotest.matchers.collections.shouldNotMatchInOrderSubset81import io.kotest.matchers.collections.singleElement82import io.kotest.matchers.collections.sorted83import io.kotest.matchers.collections.strictlyDecreasing84import io.kotest.matchers.collections.strictlyDecreasingWith85import io.kotest.matchers.collections.strictlyIncreasing86import io.kotest.matchers.collections.strictlyIncreasingWith87import io.kotest.matchers.ints.shouldBeGreaterThan88import io.kotest.matchers.ints.shouldBeInRange89import io.kotest.matchers.should90import io.kotest.matchers.shouldBe91import io.kotest.matchers.shouldHave92import io.kotest.matchers.shouldNot93import io.kotest.matchers.shouldNotBe94import io.kotest.matchers.shouldNotHave95import io.kotest.matchers.throwable.shouldHaveMessage96class CollectionMatchersTest : WordSpec() {97 private val countdown = (10 downTo 0).toList()98 private val asc = { a: Int, b: Int -> a - b }99 private val desc = { a: Int, b: Int -> b - a }100 init {101 "a descending non-empty list" should {102 "fail to ascend" {103 shouldFail {104 countdown.shouldBeSortedWith(asc)105 }106 }107 "descend" {108 countdown.shouldBeSortedWith(desc)109 }110 "not ascend" {111 countdown.shouldNotBeSortedWith(asc)112 }113 "fail not to descend" {114 shouldFail {115 countdown.shouldNotBeSortedWith(desc)116 }117 }118 }119 "sortedWith" should {120 val items = listOf(121 1 to "I",122 2 to "II",123 4 to "IV",124 5 to "V",125 6 to "VI",126 9 to "IX",127 10 to "X"128 )129 "work on non-Comparable given a Comparator" {130 items.shouldBeSortedWith(Comparator { a, b -> asc(a.first, b.first) })131 }132 "work on non-Comparable given a compare function" {133 items.shouldBeSortedWith { a, b -> asc(a.first, b.first) }134 }135 }136 "haveElementAt" should {137 "test that a collection contains the specified element at the given index" {138 listOf("a", "b", "c") should haveElementAt(1, "b")139 listOf("a", "b", "c") shouldNot haveElementAt(1, "c")140 listOf("a", "b", null) should haveElementAt(2, null)141 listOf("a", "b", null) shouldNot haveElementAt(3, null)142 listOf("a", "b", "c").shouldHaveElementAt(1, "b")143 listOf("a", "b", "c").shouldNotHaveElementAt(1, "c")144 listOf("a", "b", null).shouldHaveElementAt(2, null)145 }146 "support type inference for subtypes of collection" {147 val tests = listOf(148 TestSealed.Test1("test1"),149 TestSealed.Test2(2)150 )151 tests should haveElementAt(0, TestSealed.Test1("test1"))152 tests.shouldHaveElementAt(1, TestSealed.Test2(2))153 }154 }155 "containNull()" should {156 "test that a collection contains at least one null" {157 listOf(1, 2, null) should containNull()158 listOf(null) should containNull()159 listOf(1, 2) shouldNot containNull()160 listOf(1, 2, null).shouldContainNull()161 listOf(null).shouldContainNull()162 listOf(1, 2).shouldNotContainNull()163 }164 }165 "sorted" should {166 "test that a collection is sorted" {167 emptyList<Int>() shouldBe sorted<Int>()168 listOf(1) shouldBe sorted<Int>()169 listOf(1, 2, 3, 4) shouldBe sorted<Int>()170 shouldThrow<AssertionError> {171 listOf(2, 1) shouldBe sorted<Int>()172 }.shouldHaveMessage("List [2, 1] should be sorted. Element 2 at index 0 was greater than element 1")173 listOf(1, 2, 6, 9).shouldBeSorted()174 shouldThrow<AssertionError> {175 listOf(2, 1).shouldBeSorted()176 }.shouldHaveMessage("List [2, 1] should be sorted. Element 2 at index 0 was greater than element 1")177 shouldThrow<AssertionError> {178 listOf(1, 2, 3).shouldNotBeSorted()179 }.shouldHaveMessage("List [1, 2, 3] should not be sorted")180 }181 "restrict items at the error message" {182 val longList = (1..1000).toList()183 shouldThrow<AssertionError> {184 longList.shouldNotBeSorted()185 }.shouldHaveMessage("List [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...and 980 more (set the 'kotest.assertions.collection.print.size' JVM property to see more / less items)] should not be sorted")186 }187 }188 "sortedBy" should {189 val items = listOf(190 1 to "I",191 2 to "II",192 4 to "IV",193 5 to "V",194 6 to "VI",195 9 to "IX",196 10 to "X"197 )198 "compare by the tranformed value" {199 items.shouldBeSortedBy { it.first }200 items.shouldNotBeSortedBy { it.second }201 }202 }203 "shouldBeIncreasing" should {204 "test that a collection is monotonically increasing" {205 listOf(1, 2, 2, 3) shouldBe monotonicallyIncreasing<Int>()206 listOf(6, 5) shouldNotBe monotonicallyIncreasing<Int>()207 listOf(1, 2, 2, 3).shouldBeMonotonicallyIncreasing()208 listOf(6, 5).shouldNotBeMonotonicallyIncreasing()209 }210 "test that a collection is monotonically increasing according to comparator" {211 val comparator = Comparator(desc)212 listOf(3, 2, 2, 1) shouldBe monotonicallyIncreasingWith(comparator)213 listOf(5, 6) shouldNotBe monotonicallyIncreasingWith(comparator)214 listOf(3, 2, 2, 1).shouldBeMonotonicallyIncreasingWith(comparator)215 listOf(5, 6).shouldNotBeMonotonicallyIncreasingWith(comparator)216 }217 "test that a collection is strictly increasing" {218 listOf(1, 2, 3) shouldBe strictlyIncreasing<Int>()219 listOf(1, 2, 2, 3) shouldNotBe strictlyIncreasing<Int>()220 listOf(6, 5) shouldNotBe strictlyIncreasing<Int>()221 listOf(1, 2, 3).shouldBeStrictlyIncreasing()222 listOf(1, 2, 2, 3).shouldNotBeStrictlyIncreasing()223 listOf(6, 5).shouldNotBeStrictlyIncreasing()224 }225 "test that a collection is strictly increasing according to comparator" {226 val comparator = Comparator(desc)227 listOf(3, 2, 1) shouldBe strictlyIncreasingWith(comparator)228 listOf(3, 2, 2, 1) shouldNotBe strictlyIncreasingWith(comparator)229 listOf(5, 6) shouldNotBe strictlyIncreasingWith(comparator)230 listOf(3, 2, 1).shouldBeStrictlyIncreasingWith(comparator)231 listOf(3, 2, 2, 1).shouldNotBeStrictlyIncreasingWith(comparator)232 listOf(5, 6).shouldNotBeStrictlyIncreasingWith(comparator)233 }234 }235 "shouldBeDecreasing" should {236 "test that a collection is monotonically decreasing" {237 listOf(3, 2, 2, -4) shouldBe monotonicallyDecreasing<Int>()238 listOf(5, 6) shouldNotBe monotonicallyDecreasing<Int>()239 listOf(3, 2, 2, -4).shouldBeMonotonicallyDecreasing()240 listOf(5, 6).shouldNotBeMonotonicallyDecreasing()241 }242 "test that a collection is monotonically decreasing according to comparator" {243 val comparator = Comparator(desc)244 listOf(-4, 2, 2, 3) shouldBe monotonicallyDecreasingWith(comparator)245 listOf(6, 5) shouldNotBe monotonicallyDecreasingWith(comparator)246 listOf(-4, 2, 2, 3).shouldBeMonotonicallyDecreasingWith(comparator)247 listOf(6, 5).shouldNotBeMonotonicallyDecreasingWith(comparator)248 }249 "test that a collection is strictly decreasing" {250 listOf(3, 2, -4) shouldBe strictlyDecreasing<Int>()251 listOf(3, 2, 2, -4) shouldNotBe strictlyDecreasing<Int>()252 listOf(5, 6) shouldNotBe strictlyDecreasing<Int>()253 listOf(3, 2, -4).shouldBeStrictlyDecreasing()254 listOf(3, 2, 2, -4).shouldNotBeStrictlyDecreasing()255 listOf(5, 6).shouldNotBeStrictlyDecreasing()256 }257 "test that a collection is strictly decreasing according to comparator" {258 val comparator = Comparator(desc)259 listOf(-4, 2, 3) shouldBe strictlyDecreasingWith(comparator)260 listOf(-4, 2, 2, 3) shouldNotBe strictlyDecreasingWith(comparator)261 listOf(6, 5) shouldNotBe strictlyDecreasingWith(comparator)262 listOf(-4, 2, 3).shouldBeStrictlyDecreasingWith(comparator)263 listOf(-4, 2, 2, 3).shouldNotBeStrictlyDecreasingWith(comparator)264 listOf(6, 5).shouldNotBeStrictlyDecreasingWith(comparator)265 }266 }267 "haveDuplicates" should {268 "test that a collection is unique" {269 listOf(1, 2, 3, 3) should containDuplicates()270 listOf(1, 2, 3, 4) shouldNot containDuplicates()271 listOf(1, 2, 3, 3).shouldContainDuplicates()272 listOf(1, 2, 3, 4).shouldNotContainDuplicates()273 }274 }275 "singleElement" should {276 "test that a collection contains a single given element" {277 listOf(1) shouldBe singleElement(1)278 listOf(1).shouldHaveSingleElement(1)279 shouldThrow<AssertionError> {280 listOf(1) shouldBe singleElement(2)281 }.shouldHaveMessage("Collection should be a single element of 2 but has 1 elements: [1]")282 shouldThrow<AssertionError> {283 listOf(1, 2) shouldBe singleElement(2)284 }.shouldHaveMessage("Collection should be a single element of 2 but has 2 elements: [1, 2]")285 }286 }287 "singleElement with predicate" should {288 "test that a collection contains a single element by given predicate" {289 listOf(1) shouldHave singleElement { e -> e == 1 }290 listOf(1).shouldHaveSingleElement { e -> e == 1 }291 shouldThrow<AssertionError> {292 listOf(1) shouldHave singleElement { e -> e == 2 }293 }.shouldHaveMessage("Collection should have a single element by a given predicate but has 0 elements: [1]")294 shouldThrow<AssertionError> {295 listOf(2, 2) shouldHave singleElement { e -> e == 2 }296 }.shouldHaveMessage("Collection should have a single element by a given predicate but has 2 elements: [2, 2]")297 }298 }299 "should contain element" should {300 "test that a collection contains an element" {301 val col = listOf(1, 2, 3)302 col should contain(2)303 col should contain(2.0) // uses strict num equality = false304 shouldThrow<AssertionError> {305 col should contain(4)306 }.shouldHaveMessage("Collection should contain element 4 based on object equality; but the collection is [1, 2, 3]")307 }308 }309 "should contain element based on a custom equality object" should {310 "test that a collection contains an element" {311 val col = listOf(1, 2, 3.0)312 val verifier = Equality.byObjectEquality<Number>(strictNumberEquality = true)313 col should contain(2, verifier)314 col should contain(3.0, verifier)315 shouldThrow<AssertionError> {316 col should contain(3, verifier)317 }.shouldHaveMessage("Collection should contain element 3 based on object equality; but the collection is [1, 2, 3.0]")318 }319 }320 "shouldBeLargerThan" should {321 "test that a collection is larger than another collection" {322 val col1 = listOf(1, 2, 3)323 val col2 = setOf(1, 2, 3, 4)324 col2.shouldBeLargerThan(col1)325 col2 should beLargerThan(col1)326 col1 shouldNot beLargerThan(col2)327 shouldThrow<AssertionError> {328 col1.shouldBeLargerThan(col2)329 }.shouldHaveMessage("Collection of size 3 should be larger than collection of size 4")330 }331 }332 "shouldBeSmallerThan" should {333 "test that a collection is smaller than another collection" {334 val col1 = listOf(1, 2, 3)335 val col2 = setOf(1, 2, 3, 4)336 col1.shouldBeSmallerThan(col2)337 col1 should beSmallerThan(col2)338 col2 shouldNot beSmallerThan(col1)339 shouldThrow<AssertionError> {340 col2.shouldBeSmallerThan(col1)341 }.shouldHaveMessage("Collection of size 4 should be smaller than collection of size 3")342 }343 }344 "shouldBeSameSizeAs" should {345 "test that a collection is the same size as another collection" {346 val col1 = listOf(1, 2, 3)347 val col2 = setOf(1, 2, 3)348 val col3 = listOf(1, 2, 3, 4)349 col1.shouldBeSameSizeAs(col2)350 col1 should beSameSizeAs(col2)351 col1 shouldNot beSameSizeAs(col3)352 shouldThrow<AssertionError> {353 col1.shouldBeSameSizeAs(col3)354 }.shouldHaveMessage("Collection of size 3 should be the same size as collection of size 4")355 }356 }357 "haveSize" should {358 "test that a collection has a certain size" {359 val col1 = listOf(1, 2, 3)360 col1 should haveSize(3)361 col1.shouldHaveSize(3)362 shouldThrow<AssertionError> {363 col1 should haveSize(2)364 }365 val col2 = emptyList<String>()366 col2 should haveSize(0)367 shouldThrow<AssertionError> {368 col2 should haveSize(1)369 }370 listOf(1, 2, 3).shouldNotHaveSize(1)371 listOf(1, 2, 3).shouldNotHaveSize(4)372 shouldThrow<AssertionError> {373 listOf(1, 2, 3).shouldNotHaveSize(3)374 }.shouldHaveMessage("Collection should not have size 3. Values: [1, 2, 3]")375 }376 }377 "should be singleton" should {378 "pass for collection with a single element" {379 listOf(1).shouldBeSingleton()380 }381 "fail for collection with 0 elements" {382 shouldThrow<AssertionError> {383 listOf<Int>().shouldBeSingleton()384 }.shouldHaveMessage("Collection should have size 1 but has size 0. Values: []")385 }386 "fail for collection with 2+ elements" {387 shouldThrow<AssertionError> {388 listOf(1, 2).shouldBeSingleton()389 }.shouldHaveMessage("Collection should have size 1 but has size 2. Values: [1, 2]")390 shouldThrow<AssertionError> {391 listOf(1, 2, 3, 4).shouldBeSingleton()392 }.shouldHaveMessage("Collection should have size 1 but has size 4. Values: [1, 2, 3, 4]")393 }394 }395 "should be singleton with block" should {396 "pass for collection with a single element" {397 listOf(1).shouldBeSingleton { it shouldBe 1 }398 }399 "fail for collection with 0 elements" {400 shouldThrow<AssertionError> {401 listOf<Int>().shouldBeSingleton { it shouldBe 1 }402 }.shouldHaveMessage("Collection should have size 1 but has size 0. Values: []")403 }404 "fail for collection with a single incorrect elements" {405 shouldThrow<AssertionError> {406 listOf(2).shouldBeSingleton { it shouldBe 1 }407 }.shouldHaveMessage("expected:<1> but was:<2>")408 }409 "fail for collection with 2+ elements" {410 shouldThrow<AssertionError> {411 listOf(1, 2).shouldBeSingleton { it shouldBe 1 }412 }.shouldHaveMessage("Collection should have size 1 but has size 2. Values: [1, 2]")413 shouldThrow<AssertionError> {414 listOf(1, 2, 3, 4).shouldBeSingleton { it shouldBe 1 }415 }.shouldHaveMessage("Collection should have size 1 but has size 4. Values: [1, 2, 3, 4]")416 }417 }418 "should not be singleton" should {419 "pass for collection with 0 elements" {420 listOf<Int>().shouldNotBeSingleton()421 }422 "pass for collection with 2+ elements" {423 listOf(1, 2).shouldNotBeSingleton()424 listOf(1, 2, 3, 4).shouldNotBeSingleton()425 }426 "fail for collection with a single element" {427 shouldThrow<AssertionError> {428 listOf(1).shouldNotBeSingleton()429 }.shouldHaveMessage("Collection should not have size 1. Values: [1]")430 }431 }432 "shouldExist" should {433 "test that a collection contains at least one element that matches a predicate" {434 val list = listOf(1, 2, 3)435 list.shouldExist { it == 2 }436 }437 }438 "shouldHaveAtLeastSize" should {439 "test that a collection has at least a certain number of elements" {440 val list = listOf(1, 2, 3)441 list.shouldHaveAtLeastSize(2)442 list shouldHave atLeastSize(2)443 val set = setOf(1, 2, 3)444 set.shouldHaveAtLeastSize(3)445 set shouldHave atLeastSize(3)446 shouldThrow<AssertionError> {447 list.shouldHaveAtLeastSize(4)448 }.shouldHaveMessage("Collection [1, 2, 3] should contain at least 4 elements")449 shouldThrow<AssertionError> {450 list shouldHave atLeastSize(4)451 }.shouldHaveMessage("Collection [1, 2, 3] should contain at least 4 elements")452 shouldThrow<AssertionError> {453 list shouldNotHave atLeastSize(2)454 }.shouldHaveMessage("Collection [1, 2, 3] should contain less than 2 elements")455 }456 }457 "shouldHaveAtMostSize" should {458 "test that a collection has at least a certain number of elements" {459 val list = listOf(1, 2, 3)460 list.shouldHaveAtMostSize(3)461 list shouldHave atMostSize(3)462 list.shouldHaveAtMostSize(4)463 list shouldHave atMostSize(4)464 val set = setOf(1, 2, 3)465 set.shouldHaveAtMostSize(3)466 set shouldHave atMostSize(3)467 set.shouldHaveAtMostSize(4)468 set shouldHave atMostSize(4)469 shouldThrow<AssertionError> {470 list.shouldHaveAtMostSize(2)471 }.shouldHaveMessage("Collection [1, 2, 3] should contain at most 2 elements")472 shouldThrow<AssertionError> {473 list shouldHave atMostSize(2)474 }.shouldHaveMessage("Collection [1, 2, 3] should contain at most 2 elements")475 shouldThrow<AssertionError> {476 list shouldNotHave atMostSize(4)477 }.shouldHaveMessage("Collection [1, 2, 3] should contain more than 4 elements")478 }479 }480 "containNoNulls" should {481 "test that a collection contains zero nulls" {482 emptyList<String>() should containNoNulls()483 listOf(1, 2, 3) should containNoNulls()484 listOf(null, null, null) shouldNot containNoNulls()485 listOf(1, null, null) shouldNot containNoNulls()486 emptyList<String>().shouldContainNoNulls()487 listOf(1, 2, 3).shouldContainNoNulls()488 listOf(null, null, null).shouldNotContainNoNulls()489 listOf(1, null, null).shouldNotContainNoNulls()490 shouldThrow<AssertionError> {491 listOf(null, null, null).shouldContainNoNulls()492 }.shouldHaveMessage("Collection should not contain nulls")493 shouldThrow<AssertionError> {494 listOf(1, 2, 3).shouldNotContainNoNulls()495 }.shouldHaveMessage("Collection should have at least one null")496 }497 "support type inference for subtypes of collection" {498 val tests = listOf(499 TestSealed.Test1("test1"),500 TestSealed.Test2(2)501 )502 tests should containNoNulls()503 tests.shouldContainNoNulls()504 }505 }506 "containOnlyNulls" should {507 "test that a collection contains only nulls" {508 emptyList<String>() should containOnlyNulls()509 listOf(null, null, null) should containOnlyNulls()510 listOf(1, null, null) shouldNot containOnlyNulls()511 listOf(1, 2, 3) shouldNot containOnlyNulls()512 listOf(null, 1, 2, 3).shouldNotContainOnlyNulls()513 listOf(1, 2, 3).shouldNotContainOnlyNulls()514 listOf(null, null, null).shouldContainOnlyNulls()515 }516 }517 "matchInOrder" should {518 "test that a collection matches the assertions in the given order, duplicates permitted" {519 withClue("Gaps not allowed") {520 shouldFail {521 listOf(1, 2, 2, 3) should matchInOrder(522 { it shouldBe 1 },523 { it shouldBe 2 },524 { it shouldBe 3 }525 )526 }527 }528 arrayOf(2, 2, 3).shouldMatchInOrder(529 { it shouldBe 2 },530 { it shouldBe 2 },531 { it shouldBe 3 },532 )533 }534 "failure shows best result" {535 shouldFail {536 listOf(1, 2, 3, 1, 2, 1, 2).shouldMatchInOrder(537 { it shouldBe 1 },538 { it shouldBe 2 },539 { it shouldBe 1 },540 { it shouldBe 3 },541 )542 }.message shouldBe """543 Expected a sequence of elements to pass the assertions, but failed to match all assertions544 Best result when comparing from index [3], where 3 elements passed, but the following elements failed:545 6 => expected:<3> but was:<2>546 """.trimIndent()547 }548 "Non existing element causes error" {549 shouldThrow<AssertionError> {550 listOf(1, 2, 3).shouldMatchInOrder(551 { it shouldBe 1 },552 { it shouldBe 2 },553 { it shouldBe 6 }554 )555 }556 }557 "out-of-order elements cause error" {558 shouldThrow<AssertionError> {559 listOf(1, 2, 3) should matchInOrder(560 { it shouldBe 2 },561 { it shouldBe 1 },562 { it shouldBe 3 }563 )564 }565 }566 "work with unsorted collections" {567 val actual = listOf(5, 3, 1, 2, 4, 2)568 withClue("should match 4th, 5th and 6th elements ([.., 2, 4, 2])") {569 actual should matchInOrder(570 { it shouldBe 2 },571 { it shouldBeGreaterThan 3 },572 { it shouldBeInRange 2..2 }573 )574 }575 }576 "negation should work" {577 shouldFail {578 listOf(1, 2, 3, 4).shouldNotMatchInOrder(579 { it shouldBe 2 },580 { it shouldBe 3 },581 )582 }.message shouldBe """583 Expected some assertion to fail but all passed584 """.trimIndent()585 listOf(1, 2, 3, 4).shouldNotMatchInOrder(586 { it shouldBe 2 },587 { it shouldBe 4 }588 )589 }590 }591 "matchInOrderSubset" should {592 "test that a collection matches the assertions in the given order without gaps" {593 listOf(1, 1, 2, 2, 3, 3) should matchInOrderSubset(594 { it shouldBe 1 },595 { it shouldBe 2 },596 { it shouldBe 2 },597 { it shouldBe 3 }598 )599 arrayOf(1, 1, 1).shouldMatchInOrderSubset(600 { it shouldBe 1 }601 )602 }603 "Negation should work" {604 shouldFail {605 listOf(1, 2, 3, 4).shouldNotMatchInOrderSubset(606 { it shouldBe 2 },607 { it shouldBe 4 },608 )609 }.message shouldBe """610 Expected some assertion to fail but all passed611 """.trimIndent()612 arrayOf(1, 2, 3, 4).shouldNotMatchInOrder(613 { it shouldBe 4 },614 { it shouldBe 1 }615 )616 }617 "Non existing element causes error" {618 shouldThrow<AssertionError> {619 listOf(1, 1, 2, 2, 3, 3) should matchInOrderSubset(620 { it shouldBe 1 },621 { it shouldBe 2 },622 { it shouldBe 6 }623 )624 }.message shouldBe """625 Expected a sequence of elements to pass the assertions, possibly with gaps between but failed to match all assertions626 Best result when comparing from index [0], where 2 elements passed, but the following elements failed:627 3 => expected:<6> but was:<2>628 4 => expected:<6> but was:<3>629 5 => expected:<6> but was:<3>630 """.trimIndent()631 }632 "out-of-order elements cause error" {633 shouldThrow<AssertionError> {634 listOf(1, 2, 3) should matchInOrderSubset(635 { it shouldBe 2 },636 { it shouldBe 1 },637 { it shouldBe 3 }638 )639 }640 }641 "gaps should be ok" {642 listOf(1, 1, 2, 2, 3, 3) should matchInOrderSubset(643 { it shouldBe 1 },644 { it shouldBe 2 },645 { it shouldBe 3 }646 )647 }648 "work with unsorted collections" {649 val actual = listOf(5, 3, 1, 2, 4, 2)650 withClue("should match 4th, 5th and 6th elements ([.., 2, 4, 2])") {651 actual should matchInOrderSubset(652 { it shouldBe 2 },653 { it shouldBeGreaterThan 3 },654 { it shouldBeInRange 2..2 }655 )656 }657 }658 }659 "matchEach" should {660 "test that a collection matches the assertions in the given order without gaps" {661 listOf(1, 3, 7) should matchEach(662 { it shouldBe 1 },663 { it shouldBeInRange 2..4 },664 { it shouldBeGreaterThan 2 }665 )666 }667 "Negation should work" {668 shouldFail{669 listOf(1, 2).shouldNotMatchEach(670 { it shouldBe 1 },671 { it shouldBe 2 },672 )673 }.message shouldBe """674 Expected some element to fail its assertion, but all passed.675 """.trimIndent()676 arrayOf(1, 2).shouldNotMatchEach(677 { it shouldBe 2 },678 { it shouldBe 1 }679 )680 }681 "No assertion exists for each element" {682 shouldFail {683 listOf(1, -1, 999) should matchEach(684 { it shouldBe 1 }685 )686 }.message shouldBe """687 Expected each element to pass its assertion, but found issues at indexes: [1, 2]688 1 => Element has no corresponding assertion. Only 1 assertions provided689 2 => Element has no corresponding assertion. Only 1 assertions provided690 """.trimIndent()691 }692 "Too many assertions cause error" {693 shouldFail {694 listOf(1, 3, 7) should matchEach(695 { it shouldBe 1 },696 { it shouldBe 3 },697 { it shouldBe 7 },698 { it shouldBe 7 },699 { it shouldBe 7 },700 )701 }.message shouldBe """702 Expected each element to pass its assertion, but found issues at indexes: [3, 4]703 3 => No actual element for assertion at index 3704 4 => No actual element for assertion at index 4705 """.trimIndent()706 }707 "Non matching element causes error" {708 shouldFail {709 listOf(1, 3, 7) should matchEach(710 { it shouldBe 1 },711 { it shouldBeInRange 2..4 },712 { it shouldBeGreaterThan 7 }713 )714 }.message shouldBe """715 Expected each element to pass its assertion, but found issues at indexes: [2]716 2 => 7 should be > 7717 """.trimIndent()718 }719 "out-of-order elements cause error" {720 shouldThrow<AssertionError> {721 setOf(2, 3, 1) should matchEach(722 { it shouldBe 2 },723 { it shouldBe 1 },724 { it shouldBe 3 }725 )726 }.message shouldBe """727 Expected each element to pass its assertion, but found issues at indexes: [1, 2]728 1 => expected:<1> but was:<3>729 2 => expected:<3> but was:<1>730 """.trimIndent()731 }732 "gaps cause errors" {733 shouldThrow<AssertionError> {734 listOf(1, 1, 2, 2, 3, 3) should matchEach(735 { it shouldBe 1 },736 { it shouldBe 2 },737 { it shouldBe 3 }738 )739 }.message shouldBe """740 Expected each element to pass its assertion, but found issues at indexes: [1, 2, 3, 4, 5]741 1 => expected:<2> but was:<1>742 2 => expected:<3> but was:<2>743 3 => Element has no corresponding assertion. Only 3 assertions provided744 4 => Element has no corresponding assertion. Only 3 assertions provided745 5 => Element has no corresponding assertion. Only 3 assertions provided746 """.trimIndent()747 }748 }749 "existInOrder" should {750 "test that a collection matches the predicates in the given order, duplicates permitted" {751 val col = listOf(1, 1, 2, 2, 3, 3)752 col should existInOrder(753 { it == 1 },754 { it == 2 },755 { it == 3 }756 )757 col should existInOrder({ it == 1 })758 shouldThrow<AssertionError> {759 col should existInOrder(760 { it == 1 },761 { it == 2 },762 { it == 6 }763 )764 }...
RGATest.kt
Source:RGATest.kt
...19package crdtlib.crdt20import crdtlib.utils.ClientUId21import crdtlib.utils.SimpleEnvironment22import crdtlib.utils.VersionVector23import io.kotest.assertions.throwables.shouldThrow24import io.kotest.core.spec.style.StringSpec25import io.kotest.matchers.*26import io.kotest.matchers.collections.*27import io.kotest.matchers.iterator.shouldBeEmpty28import io.kotest.matchers.iterator.shouldHaveNext29/**30* Represents a suite test for RGA.31**/32class RGATest : StringSpec({33 val uid1 = ClientUId("clientid1")34 val uid2 = ClientUId("clientid2")35 val uid3 = ClientUId("clientid3")36 var client1 = SimpleEnvironment(uid1)37 var client2 = SimpleEnvironment(uid2)38 var client3 = SimpleEnvironment(uid3)39 beforeTest {40 client1 = SimpleEnvironment(uid1)41 client2 = SimpleEnvironment(uid2)42 client3 = SimpleEnvironment(uid3)43 }44 /**45 * This test evaluates the scenario: create, get/iterator.46 * Call to get should return an empty array.47 * Call to get at 0 should raise a IndexOutOfBoundsException.48 * Call to iterator should return an empty iterator.49 */50 "create and get/iterator" {51 val rga = RGA()52 rga.get().shouldBeEmpty()53 shouldThrow<IndexOutOfBoundsException> {54 rga.get(0)55 }56 rga.iterator().shouldBeEmpty()57 }58 /**59 * This test evaluates the scenario: insert at 0, get/iterator.60 * Call to get should return an array containing the inserted value.61 * Call to get at 0 should return the inserted value.62 * Call to iterator should return an iterator containing the inserted value.63 */64 "insert at 0 and get/iterator" {65 val rga = RGA(client1)66 rga.insertAt(0, "A")67 rga.get().shouldHaveSingleElement("A")68 rga.get(0).shouldBe("A")69 val it = rga.iterator()70 it.shouldHaveNext()71 it.next().shouldBe("A")72 it.shouldBeEmpty()73 }74 /**75 * This test evaluates the scenario: insert at 0 twice, get/iterator.76 * Call to get should return an array containing the two inserted values.77 * Second value should be at index 0 and first value at index 1.78 * Call to get at 0 should return the second inserted value.79 * Call to get at 1 should return the first inserted value.80 * Call to iterator should return an iterator containing the two inserted value.81 */82 "insert at 0, insert at 0, get/iterator" {83 val rga = RGA(client1)84 rga.insertAt(0, "B")85 rga.insertAt(0, "A")86 rga.get().shouldContainExactly("A", "B")87 rga.get(0).shouldBe("A")88 rga.get(1).shouldBe("B")89 val it = rga.iterator()90 for (value in rga.get()) {91 it.shouldHaveNext()92 it.next().shouldBe(value)93 }94 it.shouldBeEmpty()95 }96 /**97 * This test evaluates the scenario: insert at 0, insert at 1, get/iterator.98 * Call to get should return an array containing the two inserted values.99 * First value should be at index 0 and second value at index 1.100 * Call to get at 0 should return the first inserted value.101 * Call to get at 1 should return the second inserted value.102 * Call to iterator should return an iterator containing the two inserted value.103 */104 "insert at 0, insert at 1, get/iterator" {105 val rga = RGA(client1)106 rga.insertAt(0, "A")107 rga.insertAt(1, "B")108 rga.get().shouldContainExactly("A", "B")109 rga.get(0).shouldBe("A")110 rga.get(1).shouldBe("B")111 val it = rga.iterator()112 for (value in rga.get()) {113 it.shouldHaveNext()114 it.next().shouldBe(value)115 }116 it.shouldBeEmpty()117 }118 /**119 * This test evaluates the scenario: insert at 0, remove at 0, get/iterator.120 * Call to get should return an empty array.121 * Call to get at 0 should raise a IndexOutOfBoundsException.122 * Call to iterator should return an empty iterator.123 */124 "insert at 0, remove at 0, get/iterator" {125 val rga = RGA(client1)126 rga.insertAt(0, "A")127 rga.removeAt(0)128 rga.get().shouldBeEmpty()129 shouldThrow<IndexOutOfBoundsException> {130 rga.get(0)131 }132 rga.iterator().shouldBeEmpty()133 }134 /**135 * This test evaluates the scenario: insert at 0 twice, remove at 0 twice, get/iterator.136 * Call to get should return an empty array.137 * Call to get at 0 should raise a IndexOutOfBoundsException.138 * Call to iterator should return an empty iterator.139 */140 "insert at 0, insert at 0, remove at 0, remove at 0, get/iterator" {141 val rga = RGA(client1)142 rga.insertAt(0, "A")143 rga.insertAt(0, "B")144 rga.removeAt(0)145 rga.removeAt(0)146 rga.get().shouldBeEmpty()147 shouldThrow<IndexOutOfBoundsException> {148 rga.get(0)149 }150 rga.iterator().shouldBeEmpty()151 }152 /**153 * This test evaluates the scenario: insert at 0, insert at 1, remove at 0, insert at 1, get/iterator.154 * Call to get should return an array containing the two last inserted values.155 * Second inserted value should be at index 0 and third inserted value at index 1.156 * Call to get at 1 should return the second inserted value.157 * Call to get at 2 should return the third inserted value.158 * Call to iterator should return an iterator containing the two last inserted values.159 */160 "insert at 0, insert at 1, remove at 0, insert at 1, get/iterator" {161 val rga = RGA(client1)162 rga.insertAt(0, "A")163 rga.insertAt(1, "B")164 rga.removeAt(0)165 rga.insertAt(1, "C")166 rga.get().shouldContainExactly("B", "C")167 rga.get(0).shouldBe("B")168 rga.get(1).shouldBe("C")169 val it = rga.iterator()170 for (value in rga.get()) {171 it.shouldHaveNext()172 it.next().shouldBe(value)173 }174 it.shouldBeEmpty()175 }176 /**177 * This test evaluates the scenario: insert at 0, insert at 1, remove at 1, insert at 1, get/iterator.178 * Call to get should return an array containing the first and third inserted values.179 * First inserted value should be at index 0 and third inserted value at index 1.180 * Call to get at 0 should return the first inserted value.181 * Call to get at 1 should return the third inserted value.182 * Call to iterator should return an iterator containing the first and third inserted values.183 */184 "insert at 0, insert at 1, remove at 1, insert at 1, get/iterator" {185 val rga = RGA(client1)186 rga.insertAt(0, "A")187 rga.insertAt(1, "B")188 rga.removeAt(1)189 rga.insertAt(1, "C")190 rga.get().shouldContainExactly("A", "C")191 rga.get(0).shouldBe("A")192 rga.get(1).shouldBe("C")193 val it = rga.iterator()194 for (value in rga.get()) {195 it.shouldHaveNext()196 it.next().shouldBe(value)197 }198 it.shouldBeEmpty()199 }200 /**201 * This test evaluates the scenario: insert at 0 || merge, get/iterator.202 * Call to get should return an array containing the value inserted in replica 1.203 * Call to get at 0 should return the value inserted in replica 1.204 * Call to iterator should return an iterator containing the value inserted in replica 1.205 */206 "R1: insert at 0; R2: merge, get/iterator" {207 val rga1 = RGA(client1)208 val rga2 = RGA(client1)209 rga1.insertAt(0, "A")210 rga2.merge(rga1)211 rga2.get().shouldHaveSingleElement("A")212 rga2.get(0).shouldBe("A")213 val it = rga2.iterator()214 it.shouldHaveNext()215 it.next().shouldBe("A")216 it.shouldBeEmpty()217 }218 /**219 * This test evaluates the scenario: insert at 0 twice || merge, get/iterator.220 * Call to get should return an array containing the two values inserted in replica 1.221 * Call to get at 0 should return the second value inserted in replica 1.222 * Call to get at 1 should return the first value inserted in replica 1.223 * Call to iterator should return an iterator containing the two values inserted in replica 1.224 */225 "R1: insert at 0, insert at 0; R2: merge, get/iterator" {226 val rga1 = RGA(client1)227 val rga2 = RGA(client1)228 rga1.insertAt(0, "B")229 rga1.insertAt(0, "A")230 rga2.merge(rga1)231 rga2.get().shouldContainExactly("A", "B")232 rga2.get(0).shouldBe("A")233 rga2.get(1).shouldBe("B")234 val it = rga2.iterator()235 for (value in rga2.get()) {236 it.shouldHaveNext()237 it.next().shouldBe(value)238 }239 it.shouldBeEmpty()240 }241 /**242 * This test evaluates the scenario: insert at 0, insert at 1, insert at 2 || merge, get/iterator.243 * Call to get should return an array containing the three values inserted in replica 1.244 * Call to get at 0 should return the first value inserted in replica 1.245 * Call to get at 1 should return the second value inserted in replica 1.246 * Call to get at 2 should return the third value inserted in replica 1.247 * Call to iterator should return an iterator containing the three values inserted in replica 1.248 */249 "R1: insert at 0, insert at 1, insert at 2; R2: merge, get/iterator" {250 val rga1 = RGA(client1)251 val rga2 = RGA(client1)252 rga1.insertAt(0, "A")253 rga1.insertAt(1, "B")254 rga1.insertAt(2, "C")255 rga2.merge(rga1)256 rga2.get().shouldContainExactly("A", "B", "C")257 rga2.get(0).shouldBe("A")258 rga2.get(1).shouldBe("B")259 rga2.get(2).shouldBe("C")260 val it = rga2.iterator()261 for (value in rga2.get()) {262 it.shouldHaveNext()263 it.next().shouldBe(value)264 }265 it.shouldBeEmpty()266 }267 "R1: insert at 0; R2: insert at 0, merge, get/iterator" {268 val rga1 = RGA(client1)269 val rga2 = RGA(client2)270 rga1.insertAt(0, "B")271 rga2.insertAt(0, "A")272 rga2.merge(rga1)273 rga2.get().shouldContainExactly("A", "B")274 rga2.get(0).shouldBe("A")275 rga2.get(1).shouldBe("B")276 val it = rga2.iterator()277 for (value in rga2.get()) {278 it.shouldHaveNext()279 it.next().shouldBe(value)280 }281 it.shouldBeEmpty()282 }283 /**284 * This test evaluates the scenario: insert at 0 twice || insert at 0 twice, merge, get/iterator.285 * Call to get should return an array containing the four values. Values should be ordered286 * according to decreasing order of their associated timestamp.287 * Call to get at 0 should return the second value inserted in replica 2.288 * Call to get at 1 should return the second value inserted in replica 1.289 * Call to get at 2 should return the first value inserted in replica 2.290 * Call to get at 3 should return the first value inserted in replica 1.291 * Call to iterator should return an iterator containing the four values.292 */293 "R1: insert at 0, insert at 0; R2: insert at 0, insert at 0, merge, get/iterator" {294 val rga1 = RGA(client1)295 val rga2 = RGA(client2)296 rga1.insertAt(0, "D")297 rga1.insertAt(0, "B")298 rga2.insertAt(0, "C")299 rga2.insertAt(0, "A")300 rga2.merge(rga1)301 rga2.get().shouldContainExactly("A", "B", "C", "D")302 rga2.get(0).shouldBe("A")303 rga2.get(1).shouldBe("B")304 rga2.get(2).shouldBe("C")305 rga2.get(3).shouldBe("D")306 val it = rga2.iterator()307 for (value in rga2.get()) {308 it.shouldHaveNext()309 it.next().shouldBe(value)310 }311 it.shouldBeEmpty()312 }313 "R1: insert at 0, 1; R2: insert at 0, 1, merge, get/iterator" {314 val rga1 = RGA(client1)315 val rga2 = RGA(client2)316 rga1.insertAt(0, "C")317 rga1.insertAt(1, "D")318 rga2.insertAt(0, "A")319 rga2.insertAt(1, "B")320 rga1.merge(rga2)321 rga1.get().shouldContainExactly("A", "B", "C", "D")322 rga1.get(0).shouldBe("A")323 rga1.get(1).shouldBe("B")324 rga1.get(2).shouldBe("C")325 rga1.get(3).shouldBe("D")326 val it = rga1.iterator()327 for (value in rga1.get()) {328 it.shouldHaveNext()329 it.next().shouldBe(value)330 }331 it.shouldBeEmpty()332 rga2.merge(rga1)333 rga2.get(0).shouldBe("A")334 rga2.get(1).shouldBe("B")335 rga2.get(2).shouldBe("C")336 rga2.get(3).shouldBe("D")337 }338 /**339 * This test evaluates the scenario: insert four times, remove at 1 || merge (after adds in340 * replica 1), remove at 2, merge, get/iterator.341 * Call to get should return an array containing the two values that have not been remove (the342 * first and the fourth one).343 * Call to get at 0 should return the first inserted value.344 * Call to get at 1 should return the fourth inserted value.345 * Call to iterator should return an iterator containing the two values that have not been remove (the346 * first and the fourth one).347 */348 "R1: insert four times, remove at 1; R2: merge after inserts, remove at 2, merge, get/iterator" {349 val rga1 = RGA(client1)350 val rga2 = RGA(client2)351 rga1.insertAt(0, "A")352 rga1.insertAt(1, "B")353 rga1.insertAt(2, "C")354 rga1.insertAt(3, "D")355 rga2.merge(rga1)356 rga1.removeAt(1)357 rga2.removeAt(2)358 rga2.merge(rga1)359 rga2.get().shouldContainExactly("A", "D")360 rga2.get(0).shouldBe("A")361 rga2.get(1).shouldBe("D")362 val it = rga2.iterator()363 for (value in rga2.get()) {364 it.shouldHaveNext()365 it.next().shouldBe(value)366 }367 it.shouldBeEmpty()368 }369 /**370 * This test evaluates the scenario: insert at 0 and 1 in all replicas,371 * then merge first and second replica into the third one.372 * Call to get in the third replica should return an array containing the373 * six values correctly ordered: third replica's values first, then second374 * replica's values, and finally first replica's values.375 * Call to iterator should return an iterator containing the six values376 * correctly ordered.377 */378 "R1, R2, R3: insert 0, 1 ; merge R1, R2 -> R3" {379 val rga1 = RGA(client1)380 val rga2 = RGA(client2)381 val rga3 = RGA(client3)382 // client3 has the largest uid â will be first in merged RGA383 rga3.insertAt(0, "A")384 rga3.insertAt(1, "B")385 rga2.insertAt(0, "C")386 rga2.insertAt(1, "D")387 rga1.insertAt(0, "E")388 rga1.insertAt(1, "F")389 rga3.merge(rga1)390 rga3.merge(rga2)391 rga3.get().shouldContainExactly("A", "B", "C", "D", "E", "F")392 rga3.get(0).shouldBe("A")393 rga3.get(1).shouldBe("B")394 rga3.get(2).shouldBe("C")395 rga3.get(3).shouldBe("D")396 rga3.get(4).shouldBe("E")397 rga3.get(5).shouldBe("F")398 val it = rga3.iterator()399 for (value in rga3.get()) {400 it.shouldHaveNext()401 it.next().shouldBe(value)402 }403 it.shouldBeEmpty()404 }405 /**406 * This test evaluates the scenario: insert at 0 and 1 in all replicas,407 * then merge second and third replica into the first one.408 * Call to get in the first replica should return an array containing the409 * six values correctly ordered: third replica's values first, then second410 * replica's values, and finally first replica's values.411 * Call to iterator should return an iterator containing the six values412 * correctly ordered.413 */414 "R1, R2, R3: insert 0, 1 ; merge R3, R2 -> R1" {415 val rga1 = RGA(client1)416 val rga2 = RGA(client2)417 val rga3 = RGA(client3)418 // client3 has the largest uid â will be first in merged RGA419 rga3.insertAt(0, "A")420 rga3.insertAt(1, "B")421 rga2.insertAt(0, "C")422 rga2.insertAt(1, "D")423 rga1.insertAt(0, "E")424 rga1.insertAt(1, "F")425 rga1.merge(rga3)426 rga1.merge(rga2)427 rga1.get().shouldContainExactly("A", "B", "C", "D", "E", "F")428 rga1.get(0).shouldBe("A")429 rga1.get(1).shouldBe("B")430 rga1.get(2).shouldBe("C")431 rga1.get(3).shouldBe("D")432 rga1.get(4).shouldBe("E")433 rga1.get(5).shouldBe("F")434 val it = rga1.iterator()435 for (value in rga1.get()) {436 it.shouldHaveNext()437 it.next().shouldBe(value)438 }439 it.shouldBeEmpty()440 }441 /**442 * This test evaluates the scenario of issue #35443 *444 * 1362 13452 134562445 * 1 1 1446 * / \ / \ / \447 * 3 2 3 2 3 2448 * | / / \449 * 6 4 4 6450 * | |451 * 5 5452 *453 * (assuming element 6 has a smaller timestamp than element 4)454 * - 1, 2 and 3 are added and synchronized455 * - 6 is added on R1, 4 and 5 on R2 (concurrently)456 * - R1 to R2 are merged457 */458 "merge R1: 1362 and R2: 13452" {459 val rga1 = RGA(client1)460 val rga2 = RGA(client2)461 // add 132 to R1462 rga1.insertAt(0, "1")463 rga1.insertAt(1, "2")464 rga1.insertAt(1, "3")465 // merge R1 â R2466 rga2.merge(rga1)467 // add 6 to R1 (1362)468 rga1.insertAt(2, "6")469 rga1.get().shouldContainExactly("1", "3", "6", "2")470 rga1.get(0).shouldBe("1")471 rga1.get(1).shouldBe("3")472 rga1.get(2).shouldBe("6")473 rga1.get(3).shouldBe("2")474 var it1 = rga1.iterator()475 for (value in rga1.get()) {476 it1.shouldHaveNext()477 it1.next().shouldBe(value)478 }479 it1.shouldBeEmpty()480 // add 4,5 to R2 (13452)481 rga2.insertAt(2, "4")482 rga2.insertAt(3, "5")483 rga2.get().shouldContainExactly("1", "3", "4", "5", "2")484 rga2.get(0).shouldBe("1")485 rga2.get(1).shouldBe("3")486 rga2.get(2).shouldBe("4")487 rga2.get(3).shouldBe("5")488 rga2.get(4).shouldBe("2")489 var it2 = rga2.iterator()490 for (value in rga2.get()) {491 it2.shouldHaveNext()492 it2.next().shouldBe(value)493 }494 it2.shouldBeEmpty()495 // merge R1 and R2496 rga2.merge(rga1)497 rga1.merge(rga2)498 rga1.get().shouldContainExactly("1", "3", "4", "5", "6", "2")499 rga1.get(0).shouldBe("1")500 rga1.get(1).shouldBe("3")501 rga1.get(2).shouldBe("4")502 rga1.get(3).shouldBe("5")503 rga1.get(4).shouldBe("6")504 rga1.get(5).shouldBe("2")505 it1 = rga1.iterator()506 for (value in rga1.get()) {507 it1.shouldHaveNext()508 it1.next().shouldBe(value)509 }510 it1.shouldBeEmpty()511 rga2.get().shouldContainExactly("1", "3", "4", "5", "6", "2")512 rga2.get(0).shouldBe("1")513 rga2.get(1).shouldBe("3")514 rga2.get(2).shouldBe("4")515 rga2.get(3).shouldBe("5")516 rga2.get(4).shouldBe("6")517 rga2.get(5).shouldBe("2")518 it2 = rga2.iterator()519 for (value in rga2.get()) {520 it2.shouldHaveNext()521 it2.next().shouldBe(value)522 }523 it2.shouldBeEmpty()524 }525 /**526 * A similar scenario with a deeper tree527 *528 * 1346572 13465982 134659872529 * 1 1 1530 * / \ / \ / \531 * 3 2 3 2 3 2532 * / / /533 * 4 4 4534 * / \ / \ / \535 * 6 5 6 5 6 5536 * | / \ /|\537 * 7 9 8 9 8 7538 *539 * (assuming element 7 has a smaller timestamp than element 8)540 * - 1 to 5 are added and synchronized541 * - 7 is added on R1, 8 and 9 on R2 (concurrently)542 * - R1 to R2 are merged543 */544 "merge R1: 1346572 and R@: 13465982" {545 val rga1 = RGA(client1)546 val rga2 = RGA(client2)547 // add 134652 to R1548 rga1.insertAt(0, "1")549 rga1.insertAt(1, "2")550 rga1.insertAt(1, "3")551 rga1.insertAt(2, "4")552 rga1.insertAt(3, "5")553 rga1.insertAt(3, "6")554 // merge R1 â R2555 rga2.merge(rga1)556 // add 7 to R1 (1346572)557 rga1.insertAt(5, "7")558 rga1.get().shouldContainExactly("1", "3", "4", "6", "5", "7", "2")559 rga1.get(0).shouldBe("1")560 rga1.get(1).shouldBe("3")561 rga1.get(2).shouldBe("4")562 rga1.get(3).shouldBe("6")563 rga1.get(4).shouldBe("5")564 rga1.get(5).shouldBe("7")565 rga1.get(6).shouldBe("2")566 var it1 = rga1.iterator()567 for (value in rga1.get()) {568 it1.shouldHaveNext()569 it1.next().shouldBe(value)570 }571 it1.shouldBeEmpty()572 // add 8,9 to R2 (13465982)573 rga2.insertAt(5, "8")574 rga2.insertAt(5, "9")575 rga2.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8", "2")576 rga2.get(0).shouldBe("1")577 rga2.get(1).shouldBe("3")578 rga2.get(2).shouldBe("4")579 rga2.get(3).shouldBe("6")580 rga2.get(4).shouldBe("5")581 rga2.get(5).shouldBe("9")582 rga2.get(6).shouldBe("8")583 rga2.get(7).shouldBe("2")584 var it2 = rga2.iterator()585 for (value in rga2.get()) {586 it2.shouldHaveNext()587 it2.next().shouldBe(value)588 }589 it2.shouldBeEmpty()590 // merge R1 and R2591 rga2.merge(rga1)592 rga1.merge(rga2)593 rga1.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8", "7", "2")594 rga1.get(0).shouldBe("1")595 rga1.get(1).shouldBe("3")596 rga1.get(2).shouldBe("4")597 rga1.get(3).shouldBe("6")598 rga1.get(4).shouldBe("5")599 rga1.get(5).shouldBe("9")600 rga1.get(6).shouldBe("8")601 rga1.get(7).shouldBe("7")602 rga1.get(8).shouldBe("2")603 it1 = rga1.iterator()604 for (value in rga1.get()) {605 it1.shouldHaveNext()606 it1.next().shouldBe(value)607 }608 it1.shouldBeEmpty()609 rga2.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8", "7", "2")610 rga2.get(0).shouldBe("1")611 rga2.get(1).shouldBe("3")612 rga2.get(2).shouldBe("4")613 rga2.get(3).shouldBe("6")614 rga2.get(4).shouldBe("5")615 rga2.get(5).shouldBe("9")616 rga2.get(6).shouldBe("8")617 rga2.get(7).shouldBe("7")618 rga2.get(8).shouldBe("2")619 it2 = rga2.iterator()620 for (value in rga2.get()) {621 it2.shouldHaveNext()622 it2.next().shouldBe(value)623 }624 it2.shouldBeEmpty()625 }626 /**627 * Same scenario without the 2 (up to the root)628 *629 * 134657 1346598 13465987630 * 1 1 1631 * / / /632 * 3 3 3633 * / / /634 * 4 4 4635 * / \ / \ / \636 * 6 5 6 5 6 5637 * | / \ /|\638 * 7 9 8 9 8 7639 *640 * (assuming element 7 has a smaller timestamp than element 8)641 * - 1 to 5 are added and synchronized642 * - 7 is added on R1, 8 and 9 on R2 (concurrently)643 * - R1 to R2 are merged644 */645 "merge R1: 134657 and R2: 1346598" {646 val rga1 = RGA(client1)647 val rga2 = RGA(client2)648 // add 13465 to R1649 rga1.insertAt(0, "1")650 rga1.insertAt(1, "3")651 rga1.insertAt(2, "4")652 rga1.insertAt(3, "5")653 rga1.insertAt(3, "6")654 // merge R1 â R2655 rga2.merge(rga1)656 // add 7 to R1 (134657)657 rga1.insertAt(5, "7")658 rga1.get().shouldContainExactly("1", "3", "4", "6", "5", "7")659 rga1.get(0).shouldBe("1")660 rga1.get(1).shouldBe("3")661 rga1.get(2).shouldBe("4")662 rga1.get(3).shouldBe("6")663 rga1.get(4).shouldBe("5")664 rga1.get(5).shouldBe("7")665 var it1 = rga1.iterator()666 for (value in rga1.get()) {667 it1.shouldHaveNext()668 it1.next().shouldBe(value)669 }670 it1.shouldBeEmpty()671 // add 8,9 to R2 (1346598)672 rga2.insertAt(5, "8")673 rga2.insertAt(5, "9")674 rga2.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8")675 rga2.get(0).shouldBe("1")676 rga2.get(1).shouldBe("3")677 rga2.get(2).shouldBe("4")678 rga2.get(3).shouldBe("6")679 rga2.get(4).shouldBe("5")680 rga2.get(5).shouldBe("9")681 rga2.get(6).shouldBe("8")682 var it2 = rga2.iterator()683 for (value in rga2.get()) {684 it2.shouldHaveNext()685 it2.next().shouldBe(value)686 }687 it2.shouldBeEmpty()688 // merge R1 and R2689 rga2.merge(rga1)690 rga1.merge(rga2)691 rga1.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8", "7")692 rga1.get(0).shouldBe("1")693 rga1.get(1).shouldBe("3")694 rga1.get(2).shouldBe("4")695 rga1.get(3).shouldBe("6")696 rga1.get(4).shouldBe("5")697 rga1.get(5).shouldBe("9")698 rga1.get(6).shouldBe("8")699 rga1.get(7).shouldBe("7")700 it1 = rga1.iterator()701 for (value in rga1.get()) {702 it1.shouldHaveNext()703 it1.next().shouldBe(value)704 }705 it1.shouldBeEmpty()706 rga2.get().shouldContainExactly("1", "3", "4", "6", "5", "9", "8", "7")707 rga2.get(0).shouldBe("1")708 rga2.get(1).shouldBe("3")709 rga2.get(2).shouldBe("4")710 rga2.get(3).shouldBe("6")711 rga2.get(4).shouldBe("5")712 rga2.get(5).shouldBe("9")713 rga2.get(6).shouldBe("8")714 rga2.get(7).shouldBe("7")715 it2 = rga2.iterator()716 for (value in rga2.get()) {717 it2.shouldHaveNext()718 it2.next().shouldBe(value)719 }720 it2.shouldBeEmpty()721 }722 /**723 * This test evaluates the use of delta return by call to insertAt method.724 * Call to get should return an array containing the value inserted in replica 1.725 * Call to get at 0 should return the value inserted in replica 1.726 * Call to iterator should return an iterator containing the value inserted in replica 1.727 */728 "use delta returned by insert" {729 val rga1 = RGA(client1)730 val rga2 = RGA(client1)731 val returnedInsertOp = rga1.insertAt(0, "A")732 val insertOp = client1.popWrite().second733 returnedInsertOp.shouldBe(insertOp)734 rga2.merge(insertOp)735 rga2.merge(insertOp)736 rga1.get().shouldHaveSingleElement("A")737 rga2.get().shouldHaveSingleElement("A")738 rga1.get(0).shouldBe("A")739 rga2.get(0).shouldBe("A")740 val it1 = rga1.iterator()741 it1.shouldHaveNext()742 it1.next().shouldBe("A")743 it1.shouldBeEmpty()744 val it2 = rga2.iterator()745 it2.shouldHaveNext()746 it2.next().shouldBe("A")747 it2.shouldBeEmpty()748 }749 /**750 * This test evaluates the use of delta return by call to removeAt method.751 * Call to get should return an empty array.752 * Call to get at 0 should raise a IndexOutOfBoundsException.753 * Call to iterator should return an empty iterator.754 */755 "use delta returned by remove" {756 val rga1 = RGA(client1)757 val rga2 = RGA(client1)758 rga1.insertAt(0, "A")759 rga2.merge(rga1)760 val returnedRemoveOp = rga1.removeAt(0)761 val removeOp = client1.popWrite().second762 returnedRemoveOp.shouldBe(removeOp)763 rga1.merge(removeOp)764 rga2.merge(removeOp)765 rga1.get().shouldBeEmpty()766 rga2.get().shouldBeEmpty()767 shouldThrow<IndexOutOfBoundsException> {768 rga1.get(0)769 }770 shouldThrow<IndexOutOfBoundsException> {771 rga2.get(0)772 }773 rga1.iterator().shouldBeEmpty()774 rga2.iterator().shouldBeEmpty()775 }776 /**777 * This test evaluates the use of delta return by call to insertAt and removeAt methods.778 * Call to get should return an empty array.779 * Call to get at 0 should raise a IndexOutOfBoundsException.780 * Call to iterator should return an empty iterator.781 */782 "use delta returned by insert and remove" {783 val rga1 = RGA(client1)784 val rga2 = RGA(client1)785 val returnedInsertOp = rga1.insertAt(0, "A")786 val insertOp = client1.popWrite().second787 returnedInsertOp.shouldBe(insertOp)788 val returnedRemoveOp = rga1.removeAt(0)789 val removeOp = client1.popWrite().second790 returnedRemoveOp.shouldBe(removeOp)791 rga1.merge(insertOp)792 rga1.merge(removeOp)793 rga2.merge(insertOp)794 rga2.merge(removeOp)795 rga1.get().shouldBeEmpty()796 rga2.get().shouldBeEmpty()797 shouldThrow<IndexOutOfBoundsException> {798 rga1.get(0)799 }800 shouldThrow<IndexOutOfBoundsException> {801 rga2.get(0)802 }803 rga1.iterator().shouldBeEmpty()804 rga2.iterator().shouldBeEmpty()805 }806 /**807 * This test evaluates the merge of deltas returned by call to insertAt and removeAt methods.808 * Call to get should return an empty array.809 * Call to get at 0 should raise a IndexOutOfBoundsException.810 * Call to iterator should return an empty iterator.811 */812 "merge from delta insert to delta remove" {813 val rga1 = RGA(client1)814 val rga2 = RGA(client1)815 val returnedOp1 = rga1.insertAt(0, "A")816 val op1 = client1.popWrite().second817 returnedOp1.shouldBe(op1)818 val returnedOp2 = rga1.removeAt(0)819 val op2 = client1.popWrite().second820 returnedOp2.shouldBe(op2)821 op1.merge(op2)822 rga1.merge(op1)823 rga2.merge(op1)824 rga1.get().shouldBeEmpty()825 rga2.get().shouldBeEmpty()826 shouldThrow<IndexOutOfBoundsException> {827 rga1.get(0)828 }829 shouldThrow<IndexOutOfBoundsException> {830 rga2.get(0)831 }832 rga1.iterator().shouldBeEmpty()833 rga2.iterator().shouldBeEmpty()834 }835 /**836 * This test evaluates the merge of deltas returned by call to removeAt and insertAt methods.837 * Call to get should return an empty array.838 * Call to get at 0 should raise a IndexOutOfBoundsException.839 * Call to iterator should return an empty iterator.840 */841 "merge from delta remove to delta import" {842 val rga1 = RGA(client1)843 val rga2 = RGA(client1)844 val returnedOp1 = rga1.insertAt(0, "A")845 val op1 = client1.popWrite().second846 returnedOp1.shouldBe(op1)847 val returnedOp2 = rga1.removeAt(0)848 val op2 = client1.popWrite().second849 returnedOp2.shouldBe(op2)850 op2.merge(op1)851 rga1.merge(op2)852 rga2.merge(op2)853 rga1.get().shouldBeEmpty()854 rga2.get().shouldBeEmpty()855 shouldThrow<IndexOutOfBoundsException> {856 rga1.get(0)857 }858 shouldThrow<IndexOutOfBoundsException> {859 rga2.get(0)860 }861 rga1.iterator().shouldBeEmpty()862 rga2.iterator().shouldBeEmpty()863 }864 /**865 * This test evaluates the generation of delta plus its merging into another replica.866 * Call to get should return an array containing the values set by insertAt w.r.t the given867 * context.868 * Call to get at 0 should return the fourth value set by insertAt.869 * Call to get at 1 should return the second value set by insertAt.870 * Call to iterator should return an iterator containing the values set by insertAt w.r.t the given871 * context.872 */873 "generate delta" {874 val vv = VersionVector()875 val rga1 = RGA(client1)876 val rga2 = RGA(client1)877 rga1.insertAt(0, "A")878 rga1.insertAt(0, "B")879 vv.update(client1.tick())880 rga1.insertAt(0, "C")881 rga1.insertAt(0, "D")882 val delta = rga1.generateDelta(vv)883 rga2.merge(delta)884 rga2.get().shouldContainExactly("D", "C")885 rga2.get(0).shouldBe("D")886 rga2.get(1).shouldBe("C")887 val it = rga2.iterator()888 for (value in rga2.get()) {889 it.shouldHaveNext()890 it.next().shouldBe(value)891 }892 it.shouldBeEmpty()893 }894 /**895 * This test evaluates JSON serialization of an empty RGA.896 **/897 "empty JSON serialization" {898 val rga = RGA()899 val rgaJson = rga.toJson()900 rgaJson.shouldBe("""{"type":"RGA","metadata":[],"value":[]}""")901 }902 /**903 * This test evaluates JSON deserialization of an empty RGA.904 **/905 "empty JSON deserialization" {906 val rgaJson = RGA.fromJson("""{"type":"RGA","metadata":[],"value":[]}""")907 rgaJson.get().shouldBeEmpty()908 }909 /**910 * This test evaluates JSON serialization of an RGA.911 **/912 "JSON serialization" {913 val uid = ClientUId("clientid")914 val client = SimpleEnvironment(uid)915 val rga = RGA(client)916 rga.insertAt(0, "A")917 rga.insertAt(1, "B")918 rga.removeAt(1)919 rga.insertAt(1, "C")920 val rgaJson = rga.toJson()921 rgaJson.shouldBe("""{"type":"RGA","metadata":[{"anchor":null,"uid":{"uid":{"name":"clientid"},"cnt":-2147483647},"ts":{"uid":{"name":"clientid"},"cnt":-2147483647},"removed":false},{"anchor":{"uid":{"name":"clientid"},"cnt":-2147483647},"uid":{"uid":{"name":"clientid"},"cnt":-2147483644},"ts":{"uid":{"name":"clientid"},"cnt":-2147483644},"removed":false},{"atom":"B","anchor":{"uid":{"name":"clientid"},"cnt":-2147483647},"uid":{"uid":{"name":"clientid"},"cnt":-2147483646},"ts":{"uid":{"name":"clientid"},"cnt":-2147483645},"removed":true}],"value":["A","C"]}""")922 }923 /**924 * This test evaluates JSON deserialization of an RGA.925 **/926 "JSON deserialization" {927 val rgaJson = RGA.fromJson("""{"type":"RGA","metadata":[{"anchor":null,"uid":{"uid":{"name":"clientid"},"cnt":-2147483647},"ts":{"uid":{"name":"clientid"},"cnt":-2147483647},"removed":false},{"anchor":{"uid":{"name":"clientid"},"cnt":-2147483647},"uid":{"uid":{"name":"clientid"},"cnt":-2147483644},"ts":{"uid":{"name":"clientid"},"cnt":-2147483644},"removed":false},{"atom":"B","anchor":{"uid":{"name":"clientid"},"cnt":-2147483647},"uid":{"uid":{"name":"clientid"},"cnt":-2147483646},"ts":{"uid":{"name":"clientid"},"cnt":-2147483645},"removed":true}],"value":["A","C"]}""")928 rgaJson.get().shouldContainExactly("A", "C")929 }930})...
matchers.kt
Source:matchers.kt
1package io.kotest.matchers.collections2import io.kotest.assertions.show.show3import io.kotest.matchers.Matcher4import io.kotest.matchers.MatcherResult5import io.kotest.matchers.neverNullMatcher6import io.kotest.matchers.should7import io.kotest.matchers.shouldHave8import io.kotest.matchers.shouldNot9import kotlin.jvm.JvmName10fun <T> Iterable<T>.shouldContainOnlyNulls() = toList().shouldContainOnlyNulls()11fun <T> Array<T>.shouldContainOnlyNulls() = asList().shouldContainOnlyNulls()12fun <T> Collection<T>.shouldContainOnlyNulls() = this should containOnlyNulls()13fun <T> Iterable<T>.shouldNotContainOnlyNulls() = toList().shouldNotContainOnlyNulls()14fun <T> Array<T>.shouldNotContainOnlyNulls() = asList().shouldNotContainOnlyNulls()15fun <T> Collection<T>.shouldNotContainOnlyNulls() = this shouldNot containOnlyNulls()16fun <T> containOnlyNulls() = object : Matcher<Collection<T>> {17 override fun test(value: Collection<T>) =18 MatcherResult(19 value.all { it == null },20 "Collection should contain only nulls",21 "Collection should not contain only nulls"22 )23}24fun <T> Iterable<T>.shouldContainNull() = toList().shouldContainNull()25fun <T> Array<T>.shouldContainNull() = asList().shouldContainNull()26fun <T> Collection<T>.shouldContainNull() = this should containNull()27fun <T> Iterable<T>.shouldNotContainNull() = toList().shouldNotContainNull()28fun <T> Array<T>.shouldNotContainNull() = asList().shouldNotContainNull()29fun <T> Collection<T>.shouldNotContainNull() = this shouldNot containNull()30fun <T> containNull() = object : Matcher<Collection<T>> {31 override fun test(value: Collection<T>) =32 MatcherResult(33 value.any { it == null },34 "Collection should contain at least one null",35 "Collection should not contain any nulls"36 )37}38fun <T> Iterable<T>.shouldHaveElementAt(index: Int, element: T) = toList().shouldHaveElementAt(index, element)39fun <T> Array<T>.shouldHaveElementAt(index: Int, element: T) = asList().shouldHaveElementAt(index, element)40fun <T> List<T>.shouldHaveElementAt(index: Int, element: T) = this should haveElementAt(index, element)41fun <T> Iterable<T>.shouldNotHaveElementAt(index: Int, element: T) = toList().shouldNotHaveElementAt(index, element)42fun <T> Array<T>.shouldNotHaveElementAt(index: Int, element: T) = asList().shouldNotHaveElementAt(index, element)43fun <T> List<T>.shouldNotHaveElementAt(index: Int, element: T) = this shouldNot haveElementAt(index, element)44fun <T, L : List<T>> haveElementAt(index: Int, element: T) = object : Matcher<L> {45 override fun test(value: L) =46 MatcherResult(47 value[index] == element,48 { "Collection should contain ${element.show().value} at index $index" },49 { "Collection should not contain ${element.show().value} at index $index" }50 )51}52fun <T> Iterable<T>.shouldContainNoNulls() = toList().shouldContainNoNulls()53fun <T> Array<T>.shouldContainNoNulls() = asList().shouldContainNoNulls()54fun <T> Collection<T>.shouldContainNoNulls() = this should containNoNulls()55fun <T> Iterable<T>.shouldNotContainNoNulls() = toList().shouldNotContainNoNulls()56fun <T> Array<T>.shouldNotContainNoNulls() = asList().shouldNotContainNoNulls()57fun <T> Collection<T>.shouldNotContainNoNulls() = this shouldNot containNoNulls()58fun <T> containNoNulls() = object : Matcher<Collection<T>> {59 override fun test(value: Collection<T>) =60 MatcherResult(61 value.all { it != null },62 { "Collection should not contain nulls" },63 { "Collection should have at least one null" }64 )65}66infix fun <T> Array<T>.shouldNotContainExactlyInAnyOrder(expected: Array<T>) =67 asList().shouldNotContainExactlyInAnyOrder(expected.asList())68infix fun <T, C : Collection<T>> C?.shouldNotContainExactlyInAnyOrder(expected: C) =69 this shouldNot containExactlyInAnyOrder(expected)70fun <T, C : Collection<T>> C?.shouldNotContainExactlyInAnyOrder(vararg expected: T) =71 this shouldNot containExactlyInAnyOrder(*expected)72infix fun <T> Array<T>.shouldContainExactlyInAnyOrder(expected: Array<T>) =73 asList().shouldContainExactlyInAnyOrder(expected.asList())74infix fun <T, C : Collection<T>> C?.shouldContainExactlyInAnyOrder(expected: C) =75 this should containExactlyInAnyOrder(expected)76fun <T, C : Collection<T>> C?.shouldContainExactlyInAnyOrder(vararg expected: T) =77 this should containExactlyInAnyOrder(*expected)78fun <T> containExactlyInAnyOrder(vararg expected: T): Matcher<Collection<T>?> =79 containExactlyInAnyOrder(expected.asList())80/** Assert that a collection contains exactly the given values and nothing else, in any order. */81fun <T, C : Collection<T>> containExactlyInAnyOrder(expected: C): Matcher<C?> = neverNullMatcher { value ->82 val valueGroupedCounts: Map<T, Int> = value.groupBy { it }.mapValues { it.value.size }83 val expectedGroupedCounts: Map<T, Int> = expected.groupBy { it }.mapValues { it.value.size }84 val passed = expectedGroupedCounts.size == valueGroupedCounts.size85 && expectedGroupedCounts.all { valueGroupedCounts[it.key] == it.value }86 MatcherResult(87 passed,88 "Collection should contain ${expected.show().value} in any order, but was ${value.show().value}",89 "Collection should not contain exactly ${expected.show().value} in any order"90 )91}92infix fun <T : Comparable<T>> Iterable<T>.shouldHaveUpperBound(t: T) = toList().shouldHaveUpperBound(t)93infix fun <T : Comparable<T>> Array<T>.shouldHaveUpperBound(t: T) = asList().shouldHaveUpperBound(t)94infix fun <T : Comparable<T>, C : Collection<T>> C.shouldHaveUpperBound(t: T) = this should haveUpperBound(t)95fun <T : Comparable<T>, C : Collection<T>> haveUpperBound(t: T) = object : Matcher<C> {96 override fun test(value: C) = MatcherResult(97 value.all { it <= t },98 "Collection should have upper bound $t",99 "Collection should not have upper bound $t"100 )101}102infix fun <T : Comparable<T>> Iterable<T>.shouldHaveLowerBound(t: T) = toList().shouldHaveLowerBound(t)103infix fun <T : Comparable<T>> Array<T>.shouldHaveLowerBound(t: T) = asList().shouldHaveLowerBound(t)104infix fun <T : Comparable<T>, C : Collection<T>> C.shouldHaveLowerBound(t: T) = this should haveLowerBound(t)105fun <T : Comparable<T>, C : Collection<T>> haveLowerBound(t: T) = object : Matcher<C> {106 override fun test(value: C) = MatcherResult(107 value.all { t <= it },108 "Collection should have lower bound $t",109 "Collection should not have lower bound $t"110 )111}112fun <T> Iterable<T>.shouldBeUnique() = toList().shouldBeUnique()113fun <T> Array<T>.shouldBeUnique() = asList().shouldBeUnique()114fun <T> Collection<T>.shouldBeUnique() = this should beUnique()115fun <T> Iterable<T>.shouldNotBeUnique() = toList().shouldNotBeUnique()116fun <T> Array<T>.shouldNotBeUnique() = asList().shouldNotBeUnique()117fun <T> Collection<T>.shouldNotBeUnique() = this shouldNot beUnique()118fun <T> beUnique() = object : Matcher<Collection<T>> {119 override fun test(value: Collection<T>) = MatcherResult(120 value.toSet().size == value.size,121 "Collection should be Unique",122 "Collection should contain at least one duplicate element"123 )124}125fun <T> Iterable<T>.shouldContainDuplicates() = toList().shouldContainDuplicates()126fun <T> Array<T>.shouldContainDuplicates() = asList().shouldContainDuplicates()127fun <T> Collection<T>.shouldContainDuplicates() = this should containDuplicates()128fun <T> Iterable<T>.shouldNotContainDuplicates() = toList().shouldNotContainDuplicates()129fun <T> Array<T>.shouldNotContainDuplicates() = asList().shouldNotContainDuplicates()130fun <T> Collection<T>.shouldNotContainDuplicates() = this shouldNot containDuplicates()131fun <T> containDuplicates() = object : Matcher<Collection<T>> {132 override fun test(value: Collection<T>) = MatcherResult(133 value.toSet().size < value.size,134 "Collection should contain duplicates",135 "Collection should not contain duplicates"136 )137}138fun <T> beSortedWith(comparator: Comparator<in T>): Matcher<List<T>> = sortedWith(comparator)139fun <T> beSortedWith(cmp: (T, T) -> Int): Matcher<List<T>> = sortedWith(cmp)140fun <T> sortedWith(comparator: Comparator<in T>): Matcher<List<T>> = sortedWith { a, b ->141 comparator.compare(a, b)142}143fun <T> sortedWith(cmp: (T, T) -> Int): Matcher<List<T>> = object : Matcher<List<T>> {144 override fun test(value: List<T>): MatcherResult {145 val failure = value.withIndex().firstOrNull { (i, it) -> i != value.lastIndex && cmp(it, value[i + 1]) > 0 }146 val snippet = value.joinToString(",", limit = 10)147 val elementMessage = when (failure) {148 null -> ""149 else -> ". Element ${failure.value} at index ${failure.index} shouldn't precede element ${value[failure.index + 1]}"150 }151 return MatcherResult(152 failure == null,153 "List [$snippet] should be sorted$elementMessage",154 "List [$snippet] should not be sorted"155 )156 }157}158fun <T : Comparable<T>> Iterable<T>.shouldBeSorted() = toList().shouldBeSorted()159fun <T : Comparable<T>> Array<T>.shouldBeSorted() = asList().shouldBeSorted()160fun <T : Comparable<T>> List<T>.shouldBeSorted() = this should beSorted<T>()161fun <T : Comparable<T>> Iterable<T>.shouldNotBeSorted() = toList().shouldNotBeSorted()162fun <T : Comparable<T>> Array<T>.shouldNotBeSorted() = asList().shouldNotBeSorted()163fun <T : Comparable<T>> List<T>.shouldNotBeSorted() = this shouldNot beSorted<T>()164infix fun <T> Iterable<T>.shouldBeSortedWith(comparator: Comparator<in T>) = toList().shouldBeSortedWith(comparator)165infix fun <T> Array<T>.shouldBeSortedWith(comparator: Comparator<in T>) = asList().shouldBeSortedWith(comparator)166infix fun <T> List<T>.shouldBeSortedWith(comparator: Comparator<in T>) = this should beSortedWith(comparator)167infix fun <T> Iterable<T>.shouldNotBeSortedWith(comparator: Comparator<in T>) = toList().shouldNotBeSortedWith(comparator)168infix fun <T> Array<T>.shouldNotBeSortedWith(comparator: Comparator<in T>) = asList().shouldNotBeSortedWith(comparator)169infix fun <T> List<T>.shouldNotBeSortedWith(comparator: Comparator<in T>) = this shouldNot beSortedWith(comparator)170infix fun <T> Iterable<T>.shouldBeSortedWith(cmp: (T, T) -> Int) = toList().shouldBeSortedWith(cmp)171infix fun <T> Array<T>.shouldBeSortedWith(cmp: (T, T) -> Int) = asList().shouldBeSortedWith(cmp)172infix fun <T> List<T>.shouldBeSortedWith(cmp: (T, T) -> Int) = this should beSortedWith(cmp)173infix fun <T> Iterable<T>.shouldNotBeSortedWith(cmp: (T, T) -> Int) = toList().shouldNotBeSortedWith(cmp)174infix fun <T> Array<T>.shouldNotBeSortedWith(cmp: (T, T) -> Int) = asList().shouldNotBeSortedWith(cmp)175infix fun <T> List<T>.shouldNotBeSortedWith(cmp: (T, T) -> Int) = this shouldNot beSortedWith(cmp)176fun <T : Comparable<T>> Iterable<T>.shouldBeMonotonicallyIncreasing() = toList().shouldBeMonotonicallyIncreasing()177fun <T : Comparable<T>> Array<T>.shouldBeMonotonicallyIncreasing() = asList().shouldBeMonotonicallyIncreasing()178fun <T : Comparable<T>> List<T>.shouldBeMonotonicallyIncreasing() = this should beMonotonicallyIncreasing<T>()179fun <T : Comparable<T>> Iterable<T>.shouldNotBeMonotonicallyIncreasing() = toList().shouldNotBeMonotonicallyIncreasing()180fun <T : Comparable<T>> Array<T>.shouldNotBeMonotonicallyIncreasing() = asList().shouldNotBeMonotonicallyIncreasing()181fun <T : Comparable<T>> List<T>.shouldNotBeMonotonicallyIncreasing() = this shouldNot beMonotonicallyIncreasing<T>()182fun <T> List<T>.shouldBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =183 this should beMonotonicallyIncreasingWith(comparator)184fun <T> Iterable<T>.shouldBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =185 toList().shouldBeMonotonicallyIncreasingWith(comparator)186fun <T> Array<T>.shouldBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =187 asList().shouldBeMonotonicallyIncreasingWith(comparator)188fun <T> List<T>.shouldNotBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =189 this shouldNot beMonotonicallyIncreasingWith(comparator)190fun <T> Iterable<T>.shouldNotBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =191 toList().shouldNotBeMonotonicallyIncreasingWith(comparator)192fun <T> Array<T>.shouldNotBeMonotonicallyIncreasingWith(comparator: Comparator<in T>) =193 asList().shouldNotBeMonotonicallyIncreasingWith(comparator)194fun <T : Comparable<T>> Iterable<T>.shouldBeMonotonicallyDecreasing() = toList().shouldBeMonotonicallyDecreasing()195fun <T : Comparable<T>> Array<T>.shouldBeMonotonicallyDecreasing() = asList().shouldBeMonotonicallyDecreasing()196fun <T : Comparable<T>> List<T>.shouldBeMonotonicallyDecreasing() = this should beMonotonicallyDecreasing<T>()197fun <T : Comparable<T>> Iterable<T>.shouldNotBeMonotonicallyDecreasing() = toList().shouldNotBeMonotonicallyDecreasing()198fun <T : Comparable<T>> Array<T>.shouldNotBeMonotonicallyDecreasing() = asList().shouldNotBeMonotonicallyDecreasing()199fun <T : Comparable<T>> List<T>.shouldNotBeMonotonicallyDecreasing() = this shouldNot beMonotonicallyDecreasing<T>()200fun <T> List<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =201 this should beMonotonicallyDecreasingWith(comparator)202fun <T> Iterable<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =203 toList().shouldBeMonotonicallyDecreasingWith(comparator)204fun <T> Array<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =205 asList().shouldBeMonotonicallyDecreasingWith(comparator)206fun <T> List<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =207 this shouldNot beMonotonicallyDecreasingWith(comparator)208fun <T> Iterable<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =209 toList().shouldNotBeMonotonicallyDecreasingWith(comparator)210fun <T> Array<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>) =211 asList().shouldNotBeMonotonicallyDecreasingWith(comparator)212fun <T : Comparable<T>> Iterable<T>.shouldBeStrictlyIncreasing() = toList().shouldBeStrictlyIncreasing()213fun <T : Comparable<T>> Array<T>.shouldBeStrictlyIncreasing() = asList().shouldBeStrictlyIncreasing()214fun <T : Comparable<T>> List<T>.shouldBeStrictlyIncreasing() = this should beStrictlyIncreasing<T>()215fun <T : Comparable<T>> Iterable<T>.shouldNotBeStrictlyIncreasing() = toList().shouldNotBeStrictlyIncreasing()216fun <T : Comparable<T>> Array<T>.shouldNotBeStrictlyIncreasing() = asList().shouldNotBeStrictlyIncreasing()217fun <T : Comparable<T>> List<T>.shouldNotBeStrictlyIncreasing() = this shouldNot beStrictlyIncreasing<T>()218fun <T> List<T>.shouldBeStrictlyIncreasingWith(comparator: Comparator<in T>) =219 this should beStrictlyIncreasingWith(comparator)220fun <T> Iterable<T>.shouldBeStrictlyIncreasingWith(comparator: Comparator<in T>) =221 toList().shouldBeStrictlyIncreasingWith(comparator)222fun <T> Array<T>.shouldBeStrictlyIncreasingWith(comparator: Comparator<in T>) =223 asList().shouldBeStrictlyIncreasingWith(comparator)224fun <T> List<T>.shouldNotBeStrictlyIncreasingWith(comparator: Comparator<in T>) =225 this shouldNot beStrictlyIncreasingWith(comparator)226fun <T> Iterable<T>.shouldNotBeStrictlyIncreasingWith(comparator: Comparator<in T>) =227 toList().shouldNotBeStrictlyIncreasingWith(comparator)228fun <T> Array<T>.shouldNotBeStrictlyIncreasingWith(comparator: Comparator<in T>) =229 asList().shouldNotBeStrictlyIncreasingWith(comparator)230fun <T : Comparable<T>> Iterable<T>.shouldBeStrictlyDecreasing() = toList().shouldBeStrictlyDecreasing()231fun <T : Comparable<T>> List<T>.shouldBeStrictlyDecreasing() = this should beStrictlyDecreasing<T>()232fun <T : Comparable<T>> Iterable<T>.shouldNotBeStrictlyDecreasing() = toList().shouldNotBeStrictlyDecreasing()233fun <T : Comparable<T>> List<T>.shouldNotBeStrictlyDecreasing() = this shouldNot beStrictlyDecreasing<T>()234fun <T> List<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>) =235 this should beStrictlyDecreasingWith(comparator)236fun <T> Iterable<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>) =237 toList().shouldBeStrictlyDecreasingWith(comparator)238fun <T> Array<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>) =239 asList().shouldBeStrictlyDecreasingWith(comparator)240fun <T> List<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =241 this shouldNot beStrictlyDecreasingWith(comparator)242fun <T> Iterable<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =243 toList().shouldNotBeStrictlyDecreasingWith(comparator)244fun <T> Array<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =245 asList().shouldNotBeStrictlyDecreasingWith(comparator)246infix fun <T> Iterable<T>.shouldHaveSingleElement(t: T) = toList().shouldHaveSingleElement(t)247infix fun <T> Array<T>.shouldHaveSingleElement(t: T) = asList().shouldHaveSingleElement(t)248infix fun <T> Iterable<T>.shouldHaveSingleElement(p: (T) -> Boolean) = toList().shouldHaveSingleElement(p)249infix fun <T> Array<T>.shouldHaveSingleElement(p: (T) -> Boolean) = asList().shouldHaveSingleElement(p)250infix fun <T> Collection<T>.shouldHaveSingleElement(t: T) = this should singleElement(t)251infix fun <T> Collection<T>.shouldHaveSingleElement(p: (T) -> Boolean) = this should singleElement(p)252infix fun <T> Iterable<T>.shouldNotHaveSingleElement(t: T) = toList().shouldNotHaveSingleElement(t)253infix fun <T> Array<T>.shouldNotHaveSingleElement(t: T) = asList().shouldNotHaveSingleElement(t)254infix fun <T> Collection<T>.shouldNotHaveSingleElement(t: T) = this shouldNot singleElement(t)255infix fun <T> Iterable<T>.shouldHaveSize(size: Int) = toList().shouldHaveSize(size)256infix fun <T> Array<T>.shouldHaveSize(size: Int) = asList().shouldHaveSize(size)257infix fun <T> Collection<T>.shouldHaveSize(size: Int) = this should haveSize(size = size)258infix fun <T> Iterable<T>.shouldNotHaveSize(size: Int) = toList().shouldNotHaveSize(size)259infix fun <T> Array<T>.shouldNotHaveSize(size: Int) = asList().shouldNotHaveSize(size)260infix fun <T> Collection<T>.shouldNotHaveSize(size: Int) = this shouldNot haveSize(size)261/**262 * Verifies this collection contains only one element263 *264 * This assertion is an alias to `collection shouldHaveSize 1`. This will pass if the collection have exactly one element265 * (definition of a Singleton Collection)266 *267 * ```268 * listOf(1).shouldBeSingleton() // Assertion passes269 * listOf(1, 2).shouldBeSingleton() // Assertion fails270 * ```271 *272 * @see [shouldHaveSize]273 * @see [shouldNotBeSingleton]274 * @see [shouldHaveSingleElement]275 */276fun <T> Collection<T>.shouldBeSingleton() = this shouldHaveSize 1277fun <T> Iterable<T>.shouldBeSingleton() = toList().shouldBeSingleton()278fun <T> Array<T>.shouldBeSingleton() = asList().shouldBeSingleton()279inline fun <T> Collection<T>.shouldBeSingleton(fn: (T) -> Unit) {280 this.shouldBeSingleton()281 fn(this.first())282}283inline fun <T> Iterable<T>.shouldBeSingleton(fn: (T) -> Unit) {284 toList().shouldBeSingleton(fn)285}286inline fun <T> Array<T>.shouldBeSingleton(fn: (T) -> Unit) {287 asList().shouldBeSingleton(fn)288}289/**290 * Verifies this collection doesn't contain only one element291 *292 * This assertion is an alias to `collection shouldNotHaveSize 1`. This will pass if the collection doesn't have exactly one element293 * (definition of a Singleton Collection)294 *295 * ```296 * listOf(1, 2).shouldNotBeSingleton() // Assertion passes297 * listOf<Int>().shouldNotBeSingleton() // Assertion passes298 * listOf(1).shouldNotBeSingleton() // Assertion fails299 * ```300 *301 * @see [shouldNotHaveSize]302 * @see [shouldBeSingleton]303 * @see [shouldNotHaveSingleElement]304 */305fun <T> Collection<T>.shouldNotBeSingleton() = this shouldNotHaveSize 1306fun <T> Iterable<T>.shouldNotBeSingleton() = toList().shouldNotBeSingleton()307fun <T> Array<T>.shouldNotBeSingleton() = asList().shouldNotBeSingleton()308infix fun <T, U> Iterable<T>.shouldBeLargerThan(other: Collection<U>) = toList().shouldBeLargerThan(other)309infix fun <T, U> Array<T>.shouldBeLargerThan(other: Collection<U>) = asList().shouldBeLargerThan(other)310infix fun <T, U> Iterable<T>.shouldBeLargerThan(other: Iterable<U>) = toList().shouldBeLargerThan(other.toList())311infix fun <T, U> Array<T>.shouldBeLargerThan(other: Array<U>) = asList().shouldBeLargerThan(other.asList())312infix fun <T, U> Collection<T>.shouldBeLargerThan(other: Collection<U>) = this should beLargerThan(other)313fun <T, U> beLargerThan(other: Collection<U>) = object : Matcher<Collection<T>> {314 override fun test(value: Collection<T>) = MatcherResult(315 value.size > other.size,316 "Collection of size ${value.size} should be larger than collection of size ${other.size}",317 "Collection of size ${value.size} should not be larger than collection of size ${other.size}"318 )319}320infix fun <T, U> Iterable<T>.shouldBeSmallerThan(other: Collection<U>) = toList().shouldBeSmallerThan(other)321infix fun <T, U> Array<T>.shouldBeSmallerThan(other: Collection<U>) = asList().shouldBeSmallerThan(other)322infix fun <T, U> Iterable<T>.shouldBeSmallerThan(other: Iterable<U>) = toList().shouldBeSmallerThan(other.toList())323infix fun <T, U> Array<T>.shouldBeSmallerThan(other: Array<U>) = asList().shouldBeSmallerThan(other.asList())324infix fun <T, U> Collection<T>.shouldBeSmallerThan(other: Collection<U>) = this should beSmallerThan(other)325fun <T, U> beSmallerThan(other: Collection<U>) = object : Matcher<Collection<T>> {326 override fun test(value: Collection<T>) = MatcherResult(327 value.size < other.size,328 "Collection of size ${value.size} should be smaller than collection of size ${other.size}",329 "Collection of size ${value.size} should not be smaller than collection of size ${other.size}"330 )331}332infix fun <T, U> Iterable<T>.shouldBeSameSizeAs(other: Collection<U>) = toList().shouldBeSameSizeAs(other)333infix fun <T, U> Array<T>.shouldBeSameSizeAs(other: Collection<U>) = asList().shouldBeSameSizeAs(other)334infix fun <T, U> Iterable<T>.shouldBeSameSizeAs(other: Iterable<U>) = toList().shouldBeSameSizeAs(other.toList())335infix fun <T, U> Array<T>.shouldBeSameSizeAs(other: Array<U>) = asList().shouldBeSameSizeAs(other.asList())336infix fun <T, U> Collection<T>.shouldBeSameSizeAs(other: Collection<U>) = this should beSameSizeAs(other)337fun <T, U> beSameSizeAs(other: Collection<U>) = object : Matcher<Collection<T>> {338 override fun test(value: Collection<T>) = MatcherResult(339 value.size == other.size,340 "Collection of size ${value.size} should be the same size as collection of size ${other.size}",341 "Collection of size ${value.size} should not be the same size as collection of size ${other.size}"342 )343}344infix fun <T> Iterable<T>.shouldHaveAtLeastSize(n: Int) = toList().shouldHaveAtLeastSize(n)345infix fun <T> Array<T>.shouldHaveAtLeastSize(n: Int) = asList().shouldHaveAtLeastSize(n)346infix fun <T> Collection<T>.shouldHaveAtLeastSize(n: Int) = this shouldHave atLeastSize(n)347fun <T> atLeastSize(n: Int) = object : Matcher<Collection<T>> {348 override fun test(value: Collection<T>) = MatcherResult(349 value.size >= n,350 "Collection should contain at least $n elements",351 "Collection should contain less than $n elements"352 )353}354infix fun <T> Iterable<T>.shouldHaveAtMostSize(n: Int) = toList().shouldHaveAtMostSize(n)355infix fun <T> Array<T>.shouldHaveAtMostSize(n: Int) = asList().shouldHaveAtMostSize(n)356infix fun <T> Collection<T>.shouldHaveAtMostSize(n: Int) = this shouldHave atMostSize(n)357fun <T> atMostSize(n: Int) = object : Matcher<Collection<T>> {358 override fun test(value: Collection<T>) = MatcherResult(359 value.size <= n,360 "Collection should contain at most $n elements",361 "Collection should contain more than $n elements"362 )363}364infix fun <T> Iterable<T>.shouldExist(p: (T) -> Boolean) = toList().shouldExist(p)365infix fun <T> Array<T>.shouldExist(p: (T) -> Boolean) = asList().shouldExist(p)366infix fun <T> Collection<T>.shouldExist(p: (T) -> Boolean) = this should exist(p)367fun <T> exist(p: (T) -> Boolean) = object : Matcher<Collection<T>> {368 override fun test(value: Collection<T>) = MatcherResult(369 value.any { p(it) },370 "Collection should contain an element that matches the predicate $p",371 "Collection should not contain an element that matches the predicate $p"372 )373}374fun <T> Iterable<T>.shouldExistInOrder(vararg ps: (T) -> Boolean) = toList().shouldExistInOrder(ps.toList())375fun <T> Array<T>.shouldExistInOrder(vararg ps: (T) -> Boolean) = asList().shouldExistInOrder(ps.toList())376fun <T> List<T>.shouldExistInOrder(vararg ps: (T) -> Boolean) = this.shouldExistInOrder(ps.toList())377infix fun <T> Iterable<T>.shouldExistInOrder(expected: List<(T) -> Boolean>) = toList().shouldExistInOrder(expected)378infix fun <T> Array<T>.shouldExistInOrder(expected: List<(T) -> Boolean>) = asList().shouldExistInOrder(expected)379infix fun <T> List<T>.shouldExistInOrder(expected: List<(T) -> Boolean>) = this should existInOrder(expected)380infix fun <T> Iterable<T>.shouldNotExistInOrder(expected: Iterable<(T) -> Boolean>) = toList().shouldNotExistInOrder(expected.toList())381infix fun <T> Array<T>.shouldNotExistInOrder(expected: Array<(T) -> Boolean>) = asList().shouldNotExistInOrder(expected.asList())382infix fun <T> Iterable<T>.shouldNotExistInOrder(expected: List<(T) -> Boolean>) = toList().shouldNotExistInOrder(expected)383infix fun <T> Array<T>.shouldNotExistInOrder(expected: List<(T) -> Boolean>) = asList().shouldNotExistInOrder(expected)384infix fun <T> List<T>.shouldNotExistInOrder(expected: List<(T) -> Boolean>) = this shouldNot existInOrder(expected)385fun <T> Iterable<T>.shouldBeEmpty() = toList().shouldBeEmpty()386fun <T> Array<T>.shouldBeEmpty() = asList().shouldBeEmpty()387fun <T> Collection<T>.shouldBeEmpty() = this should beEmpty()388fun <T> Iterable<T>.shouldNotBeEmpty() = toList().shouldNotBeEmpty()389fun <T> Array<T>.shouldNotBeEmpty() = asList().shouldNotBeEmpty()390fun <T> Collection<T>.shouldNotBeEmpty() = this shouldNot beEmpty()391fun <T> Iterable<T>.shouldContainAnyOf(vararg ts: T) = toList().shouldContainAnyOf(ts)392fun <T> Array<T>.shouldContainAnyOf(vararg ts: T) = asList().shouldContainAnyOf(ts)393fun <T> Collection<T>.shouldContainAnyOf(vararg ts: T) = this should containAnyOf(ts.asList())394fun <T> Iterable<T>.shouldNotContainAnyOf(vararg ts: T) = toList().shouldNotContainAnyOf(ts)395fun <T> Array<T>.shouldNotContainAnyOf(vararg ts: T) = asList().shouldNotContainAnyOf(ts)396fun <T> Collection<T>.shouldNotContainAnyOf(vararg ts: T) = this shouldNot containAnyOf(ts.asList())397infix fun <T> Iterable<T>.shouldContainAnyOf(ts: Collection<T>) = toList().shouldContainAnyOf(ts)398infix fun <T> Array<T>.shouldContainAnyOf(ts: Collection<T>) = asList().shouldContainAnyOf(ts)399infix fun <T> Collection<T>.shouldContainAnyOf(ts: Collection<T>) = this should containAnyOf(ts)400infix fun <T> Iterable<T>.shouldNotContainAnyOf(ts: Collection<T>) = toList().shouldNotContainAnyOf(ts)401infix fun <T> Array<T>.shouldNotContainAnyOf(ts: Collection<T>) = asList().shouldNotContainAnyOf(ts)402infix fun <T> Collection<T>.shouldNotContainAnyOf(ts: Collection<T>) = this shouldNot containAnyOf(ts)403fun <T> containAnyOf(ts: Collection<T>) = object : Matcher<Collection<T>> {404 override fun test(value: Collection<T>): MatcherResult {405 if (ts.isEmpty()) throwEmptyCollectionError()406 return MatcherResult(407 ts.any { it in value },408 { "Collection should contain any of ${ts.joinToString(separator = ", ", limit = 10) { it.show().value }}" },409 { "Collection should not contain any of ${ts.joinToString(separator = ", ", limit = 10) { it.show().value }}" }410 )411 }412}413/**414 * Verifies that this instance is in [collection]415 *416 * Assertion to check that this instance is in [collection]. This assertion checks by reference, and not by value,417 * therefore the exact instance must be in [collection], or this will fail.418 *419 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]420 *421 * @see [shouldNotBeOneOf]422 * @see [beOneOf]423 */424infix fun <T> T.shouldBeOneOf(collection: Collection<T>) = this should beOneOf(collection)425/**426 * Verifies that this instance is NOT in [collection]427 *428 * Assertion to check that this instance is not in [collection]. This assertion checks by reference, and not by value,429 * therefore the exact instance must not be in [collection], or this will fail.430 *431 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]432 *433 * @see [shouldBeOneOf]434 * @see [beOneOf]435 */436infix fun <T> T.shouldNotBeOneOf(collection: Collection<T>) = this shouldNot beOneOf(collection)437/**438 * Verifies that this instance is any of [any]439 *440 * Assertion to check that this instance is any of [any]. This assertion checks by reference, and not by value,441 * therefore the exact instance must be in [any], or this will fail.442 *443 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]444 *445 * @see [shouldNotBeOneOf]446 * @see [beOneOf]447 */448fun <T> T.shouldBeOneOf(vararg any: T) = this should beOneOf(any.toList())449/**450 * Verifies that this instance is NOT any of [any]451 *452 * Assertion to check that this instance is not any of [any]. This assertion checks by reference, and not by value,453 * therefore the exact instance must not be in [any], or this will fail.454 *455 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]456 *457 * @see [shouldNotBeOneOf]458 * @see [beOneOf]459 */460fun <T> T.shouldNotBeOneOf(vararg any: T) = this shouldNot beOneOf(any.toList())461/**462 * Matcher that verifies that this instance is in [collection]463 *464 * Assertion to check that this instance is in [collection]. This matcher checks by reference, and not by value,465 * therefore the exact instance must be in [collection], or this will fail.466 *467 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]468 *469 * @see [shouldBeOneOf]470 * @see [shouldNotBeOneOf]471 */472fun <T> beOneOf(collection: Collection<T>) = object : Matcher<T> {473 override fun test(value: T): MatcherResult {474 if (collection.isEmpty()) throwEmptyCollectionError()475 val match = collection.any { it === value }476 return MatcherResult(477 match,478 "Collection should contain the instance of value, but doesn't.",479 "Collection should not contain the instance of value, but does."480 )481 }482}483/**484 * Verifies that this element is in [collection] by comparing value485 *486 * Assertion to check that this element is in [collection]. This assertion checks by value, and not by reference,487 * therefore even if the exact instance is not in [collection] but another instance with same value is present, the488 * test will pass.489 *490 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]491 *492 * @see [shouldNotBeIn]493 * @see [beIn]494 */495infix fun <T> T.shouldBeIn(collection: Collection<T>) = this should beIn(collection)496/**497 * Verifies that this element is NOT any of [collection]498 *499 * Assertion to check that this element is not any of [collection]. This assertion checks by value, and not by reference,500 * therefore any instance with same value must not be in [collection], or this will fail.501 *502 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]503 *504 * @see [shouldNotBeIn]505 * @see [beIn]506 */507infix fun <T> T.shouldNotBeIn(collection: Collection<T>) = this shouldNot beIn(collection.toList())508/**509 * Verifies that this element is any of [any] by comparing value510 *511 * Assertion to check that this element is any of [any]. This assertion checks by value, and not by reference,512 * therefore even if the exact instance is not any of [any] but another instance with same value is present, the513 * test will pass.514 *515 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]516 *517 * @see [shouldNotBeIn]518 * @see [beIn]519 */520fun <T> T.shouldBeIn(vararg any: T) = this should beIn(any.toList())521/**522 * Verifies that this element is NOT any of [any]523 *524 * Assertion to check that this element is not any of [any]. This assertion checks by value, and not by reference,525 * therefore any instance with same value must not be in [any], or this will fail.526 *527 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]528 *529 * @see [shouldNotBeIn]530 * @see [beIn]531 */532fun <T> T.shouldNotBeIn(vararg any: T) = this shouldNot beIn(any.toList())533/**534 * Verifies that this element is in [array] by comparing value535 *536 * Assertion to check that this element is in [array]. This assertion checks by value, and not by reference,537 * therefore even if the exact instance is not in [array] but another instance with same value is present, the538 * test will pass.539 *540 * An empty array will always fail. If you need to check for empty array, use [Array.shouldBeEmpty]541 *542 * @see [shouldNotBeIn]543 * @see [beIn]544 */545@JvmName("shouldBeInArray")546infix fun <T> T.shouldBeIn(array: Array<T>) = this should beIn(array.toList())547/**548 * Verifies that this element is NOT any of [array]549 *550 * Assertion to check that this element is not any of [array]. This assertion checks by value, and not by reference,551 * therefore any instance with same value must not be in [array], or this will fail.552 *553 * An empty array will always fail. If you need to check for empty array, use [Array.shouldBeEmpty]554 *555 * @see [shouldNotBeIn]556 * @see [beIn]557 */558@JvmName("shouldNotBeInArray")559infix fun <T> T.shouldNotBeIn(array: Array<T>) = this shouldNot beIn(array.toList())560/**561 * Matcher that verifies that this element is in [collection] by comparing value562 *563 * Assertion to check that this element is in [collection]. This assertion checks by value, and not by reference,564 * therefore even if the exact instance is not in [collection] but another instance with same value is present, the565 * test will pass.566 *567 * An empty collection will always fail. If you need to check for empty collection, use [Collection.shouldBeEmpty]568 *569 * @see [shouldBeOneOf]570 * @see [shouldNotBeOneOf]571 */572fun <T> beIn(collection: Collection<T>) = object : Matcher<T> {573 override fun test(value: T): MatcherResult {574 if (collection.isEmpty()) throwEmptyCollectionError()575 val match = value in collection576 return MatcherResult(577 match,578 "Collection should contain ${value.show().value}, but doesn't. Possible values: ${collection.show().value}",579 "Collection should not contain ${value.show().value}, but does. Forbidden values: ${collection.show().value}"580 )581 }582}583private fun throwEmptyCollectionError(): Nothing {584 throw AssertionError("Asserting content on empty collection. Use Collection.shouldBeEmpty() instead.")585}...
RateLimitedDispatcherTest.kt
Source:RateLimitedDispatcherTest.kt
1package ru.fix.stdlib.ratelimiter2import io.kotest.assertions.assertSoftly3import io.kotest.assertions.throwables.shouldThrow4import io.kotest.matchers.booleans.shouldBeFalse5import io.kotest.matchers.booleans.shouldBeTrue6import io.kotest.matchers.collections.shouldContain7import io.kotest.matchers.doubles.shouldBeBetween8import io.kotest.matchers.nulls.shouldNotBeNull9import io.kotest.matchers.shouldBe10import io.kotest.matchers.types.shouldBeInstanceOf11import kotlinx.coroutines.CoroutineScope12import kotlinx.coroutines.async13import kotlinx.coroutines.delay14import kotlinx.coroutines.future.await15import kotlinx.coroutines.future.future16import kotlinx.coroutines.runBlocking17import mu.KLogging18import org.awaitility.Awaitility.await19import org.junit.jupiter.api.Test20import org.junit.jupiter.api.TestInstance21import org.junit.jupiter.api.assertTimeoutPreemptively22import org.junit.jupiter.api.parallel.Execution23import org.junit.jupiter.api.parallel.ExecutionMode24import ru.fix.aggregating.profiler.AggregatingProfiler...
CollectionMatchers.kt
Source:CollectionMatchers.kt
1package io.kotest.matchers.collections2import io.kotest.assertions.show.show3import io.kotest.matchers.Matcher4import io.kotest.matchers.MatcherResult5import io.kotest.matchers.neverNullMatcher6fun <T> haveSizeMatcher(size: Int) = object : Matcher<Collection<T>> {7 override fun test(value: Collection<T>) =8 MatcherResult(9 value.size == size,10 { "Collection should have size $size but has size ${value.size}. Values: ${value.show().value}" },11 { "Collection should not have size $size. Values: ${value.show().value}" }12 )13}14fun <T> beEmpty(): Matcher<Collection<T>> = object : Matcher<Collection<T>> {15 override fun test(value: Collection<T>): MatcherResult = MatcherResult(16 value.isEmpty(),17 { "Collection should be empty but contained ${value.show().value}" },18 { "Collection should not be empty" }19 )20}21fun <T> existInOrder(vararg ps: (T) -> Boolean): Matcher<Collection<T>?> = existInOrder(ps.asList())22/**23 * Assert that a collections contains a subsequence that matches the given subsequence of predicates, possibly with24 * values in between.25 */26fun <T> existInOrder(predicates: List<(T) -> Boolean>): Matcher<Collection<T>?> = neverNullMatcher { actual ->27 require(predicates.isNotEmpty()) { "predicates must not be empty" }28 var subsequenceIndex = 029 val actualIterator = actual.iterator()30 while (actualIterator.hasNext() && subsequenceIndex < predicates.size) {31 if (predicates[subsequenceIndex](actualIterator.next())) subsequenceIndex += 132 }33 MatcherResult(34 subsequenceIndex == predicates.size,35 { "${actual.show().value} did not match the predicates ${predicates.show().value} in order" },36 { "${actual.show().value} should not match the predicates ${predicates.show().value} in order" }37 )38}39fun <T> haveSize(size: Int): Matcher<Collection<T>> = haveSizeMatcher(size)40fun <T> singleElement(t: T): Matcher<Collection<T>> = object : Matcher<Collection<T>> {41 override fun test(value: Collection<T>) = MatcherResult(42 value.size == 1 && value.first() == t,43 { "Collection should be a single element of $t but has ${value.size} elements: ${value.show().value}" },44 { "Collection should not be a single element of $t" }45 )46}47fun <T> singleElement(p: (T) -> Boolean): Matcher<Collection<T>> = object : Matcher<Collection<T>> {48 override fun test(value: Collection<T>): MatcherResult {49 val filteredValue: List<T> = value.filter(p)50 return MatcherResult(51 filteredValue.size == 1,52 { "Collection should have a single element by a given predicate but has ${filteredValue.size} elements: ${value.show().value}" },53 { "Collection should not have a single element by a given predicate" }54 )55 }56}57fun <T : Comparable<T>> beSorted(): Matcher<List<T>> = sorted()58fun <T : Comparable<T>> sorted(): Matcher<List<T>> = object : Matcher<List<T>> {59 override fun test(value: List<T>): MatcherResult {60 val failure = value.withIndex().firstOrNull { (i, it) -> i != value.lastIndex && it > value[i + 1] }61 val elementMessage = when (failure) {62 null -> ""63 else -> ". Element ${failure.value} at index ${failure.index} was greater than element ${value[failure.index + 1]}"64 }65 return MatcherResult(66 failure == null,67 { "List ${value.show().value} should be sorted$elementMessage" },68 { "List ${value.show().value} should not be sorted" }69 )70 }71}72fun <T : Comparable<T>> beMonotonicallyIncreasing(): Matcher<List<T>> = monotonicallyIncreasing()73fun <T : Comparable<T>> monotonicallyIncreasing(): Matcher<List<T>> = object : Matcher<List<T>> {74 override fun test(value: List<T>): MatcherResult {75 return testMonotonicallyIncreasingWith(value,76 Comparator { a, b -> a.compareTo(b) })77 }78}79fun <T> beMonotonicallyIncreasingWith(comparator: Comparator<in T>): Matcher<List<T>> =80 monotonicallyIncreasingWith(comparator)81fun <T> monotonicallyIncreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {82 override fun test(value: List<T>): MatcherResult {83 return testMonotonicallyIncreasingWith(value, comparator)84 }85}86private fun<T> testMonotonicallyIncreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {87 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) > 0 }88 val snippet = value.show().value89 val elementMessage = when (failure) {90 null -> ""91 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not monotonically increased from previous element."92 }93 return MatcherResult(94 failure == null,95 { "List [$snippet] should be monotonically increasing$elementMessage" },96 { "List [$snippet] should not be monotonically increasing" }97 )98}99fun <T : Comparable<T>> beMonotonicallyDecreasing(): Matcher<List<T>> = monotonicallyDecreasing()100fun <T : Comparable<T>> monotonicallyDecreasing(): Matcher<List<T>> = object : Matcher<List<T>> {101 override fun test(value: List<T>): MatcherResult {102 return testMonotonicallyDecreasingWith(value,103 Comparator { a, b -> a.compareTo(b) })104 }105}106fun <T> beMonotonicallyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = monotonicallyDecreasingWith(107 comparator)108fun <T> monotonicallyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {109 override fun test(value: List<T>): MatcherResult {110 return testMonotonicallyDecreasingWith(value, comparator)111 }112}113private fun <T> testMonotonicallyDecreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {114 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) < 0 }115 val snippet = value.show().value116 val elementMessage = when (failure) {117 null -> ""118 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not monotonically decreased from previous element."119 }120 return MatcherResult(121 failure == null,122 { "List [$snippet] should be monotonically decreasing$elementMessage" },123 { "List [$snippet] should not be monotonically decreasing" }124 )125}126fun <T : Comparable<T>> beStrictlyIncreasing(): Matcher<List<T>> = strictlyIncreasing()127fun <T : Comparable<T>> strictlyIncreasing(): Matcher<List<T>> = object : Matcher<List<T>> {128 override fun test(value: List<T>): MatcherResult {129 return testStrictlyIncreasingWith(value, Comparator { a, b -> a.compareTo(b) })130 }131}132fun <T> beStrictlyIncreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = strictlyIncreasingWith(133 comparator)134fun <T> strictlyIncreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {135 override fun test(value: List<T>): MatcherResult {136 return testStrictlyIncreasingWith(value, comparator)137 }138}139private fun <T> testStrictlyIncreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {140 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) >= 0 }141 val snippet = value.show().value142 val elementMessage = when (failure) {143 null -> ""144 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not strictly increased from previous element."145 }146 return MatcherResult(147 failure == null,148 { "List [$snippet] should be strictly increasing$elementMessage" },149 { "List [$snippet] should not be strictly increasing" }150 )151}152fun <T : Comparable<T>> beStrictlyDecreasing(): Matcher<List<T>> = strictlyDecreasing()153fun <T : Comparable<T>> strictlyDecreasing(): Matcher<List<T>> = object : Matcher<List<T>> {154 override fun test(value: List<T>): MatcherResult {155 return testStrictlyDecreasingWith(value, Comparator { a, b -> a.compareTo(b) })156 }157}158fun <T> beStrictlyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = strictlyDecreasingWith(159 comparator)160fun <T> strictlyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {161 override fun test(value: List<T>): MatcherResult {162 return testStrictlyDecreasingWith(value, comparator)163 }164}165private fun <T> testStrictlyDecreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {166 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) <= 0 }167 val snippet = value.show().value168 val elementMessage = when (failure) {169 null -> ""170 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not strictly decreased from previous element."171 }172 return MatcherResult(173 failure == null,174 { "List [$snippet] should be strictly decreasing$elementMessage" },175 { "List [$snippet] should not be strictly decreasing" }176 )177}...
decreasing.kt
Source:decreasing.kt
1package io.kotest.matchers.collections2import io.kotest.assertions.print.print3import io.kotest.matchers.Matcher4import io.kotest.matchers.MatcherResult5import io.kotest.matchers.should6import io.kotest.matchers.shouldNot7fun <T : Comparable<T>> Iterable<T>.shouldBeMonotonicallyDecreasing(): Iterable<T> {8 toList().shouldBeMonotonicallyDecreasing()9 return this10}11fun <T : Comparable<T>> Array<T>.shouldBeMonotonicallyDecreasing(): Array<T> {12 asList().shouldBeMonotonicallyDecreasing()13 return this14}15fun <T : Comparable<T>> List<T>.shouldBeMonotonicallyDecreasing(): List<T> {16 this should beMonotonicallyDecreasing()17 return this18}19fun <T : Comparable<T>> Iterable<T>.shouldNotBeMonotonicallyDecreasing(): Iterable<T> {20 toList().shouldNotBeMonotonicallyDecreasing()21 return this22}23fun <T : Comparable<T>> Array<T>.shouldNotBeMonotonicallyDecreasing(): Array<T> {24 asList().shouldNotBeMonotonicallyDecreasing()25 return this26}27fun <T : Comparable<T>> List<T>.shouldNotBeMonotonicallyDecreasing(): List<T> {28 this shouldNot beMonotonicallyDecreasing<T>()29 return this30}31fun <T> List<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): List<T> {32 this should beMonotonicallyDecreasingWith(comparator)33 return this34}35fun <T> Iterable<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): Iterable<T> {36 toList().shouldBeMonotonicallyDecreasingWith(comparator)37 return this38}39fun <T> Array<T>.shouldBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): Array<T> {40 asList().shouldBeMonotonicallyDecreasingWith(comparator)41 return this42}43fun <T> List<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): List<T> {44 this shouldNot beMonotonicallyDecreasingWith(comparator)45 return this46}47fun <T> Iterable<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): Iterable<T> {48 toList().shouldNotBeMonotonicallyDecreasingWith(comparator)49 return this50}51fun <T> Array<T>.shouldNotBeMonotonicallyDecreasingWith(comparator: Comparator<in T>): Array<T> {52 asList().shouldNotBeMonotonicallyDecreasingWith(comparator)53 return this54}55fun <T : Comparable<T>> Iterable<T>.shouldBeStrictlyDecreasing() = toList().shouldBeStrictlyDecreasing()56fun <T : Comparable<T>> List<T>.shouldBeStrictlyDecreasing() = this should beStrictlyDecreasing<T>()57fun <T : Comparable<T>> Iterable<T>.shouldNotBeStrictlyDecreasing() = toList().shouldNotBeStrictlyDecreasing()58fun <T : Comparable<T>> List<T>.shouldNotBeStrictlyDecreasing() = this shouldNot beStrictlyDecreasing<T>()59fun <T> List<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>) =60 this should beStrictlyDecreasingWith(comparator)61fun <T> Iterable<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>) =62 toList().shouldBeStrictlyDecreasingWith(comparator)63fun <T> Array<T>.shouldBeStrictlyDecreasingWith(comparator: Comparator<in T>): Array<T> {64 asList().shouldBeStrictlyDecreasingWith(comparator)65 return this66}67fun <T> List<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =68 this shouldNot beStrictlyDecreasingWith(comparator)69fun <T> Iterable<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =70 toList().shouldNotBeStrictlyDecreasingWith(comparator)71fun <T> Array<T>.shouldNotBeStrictlyDecreasingWith(comparator: Comparator<in T>) =72 asList().shouldNotBeStrictlyDecreasingWith(comparator)73fun <T : Comparable<T>> beMonotonicallyDecreasing(): Matcher<List<T>> = monotonicallyDecreasing()74fun <T : Comparable<T>> monotonicallyDecreasing(): Matcher<List<T>> = object : Matcher<List<T>> {75 override fun test(value: List<T>): MatcherResult {76 return testMonotonicallyDecreasingWith(value) { a, b -> a.compareTo(b) }77 }78}79fun <T> beMonotonicallyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> =80 monotonicallyDecreasingWith(comparator)81fun <T> monotonicallyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {82 override fun test(value: List<T>): MatcherResult {83 return testMonotonicallyDecreasingWith(value, comparator)84 }85}86private fun <T> testMonotonicallyDecreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {87 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) < 0 }88 val snippet = value.print().value89 val elementMessage = when (failure) {90 null -> ""91 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not monotonically decreased from previous element."92 }93 return MatcherResult(94 failure == null,95 { "List [$snippet] should be monotonically decreasing$elementMessage" },96 { "List [$snippet] should not be monotonically decreasing" }97 )98}99fun <T : Comparable<T>> beStrictlyDecreasing(): Matcher<List<T>> = strictlyDecreasing()100fun <T : Comparable<T>> strictlyDecreasing(): Matcher<List<T>> = object : Matcher<List<T>> {101 override fun test(value: List<T>): MatcherResult {102 return testStrictlyDecreasingWith(value) { a, b -> a.compareTo(b) }103 }104}105fun <T> beStrictlyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> =106 strictlyDecreasingWith(comparator)107fun <T> strictlyDecreasingWith(comparator: Comparator<in T>): Matcher<List<T>> = object : Matcher<List<T>> {108 override fun test(value: List<T>): MatcherResult {109 return testStrictlyDecreasingWith(value, comparator)110 }111}112private fun <T> testStrictlyDecreasingWith(value: List<T>, comparator: Comparator<in T>): MatcherResult {113 val failure = value.zipWithNext().withIndex().find { (_, pair) -> comparator.compare(pair.first, pair.second) <= 0 }114 val snippet = value.print().value115 val elementMessage = when (failure) {116 null -> ""117 else -> ". Element ${failure.value.second} at index ${failure.index + 1} was not strictly decreased from previous element."118 }119 return MatcherResult(120 failure == null,121 { "List [$snippet] should be strictly decreasing$elementMessage" },122 { "List [$snippet] should not be strictly decreasing" }123 )124}...
LineTest.kt
Source:LineTest.kt
1package day052import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder3import org.junit.jupiter.api.Test4internal class LineTest {5 @Test6 fun create__success__horizontalIncreasingNumbersOnly() {7 val definition = LineDefinition(Position(3, 5), Position(5, 5))8 val line = Line(definition)9 line.positions shouldContainExactlyInAnyOrder listOf(Position(3, 5), Position(4, 5), Position(5, 5))10 }11 @Test12 fun create__success__verticalDecreasingX() {13 val definition = LineDefinition(Position(3, 5), Position(3, 3))14 val line = Line(definition)15 line.positions shouldContainExactlyInAnyOrder listOf(Position(3, 3), Position(3, 4), Position(3, 5))16 }...
test
Using AI Code Generation
1 decreasing(listOf(1, 2, 3)) shouldBe true2 decreasing(listOf(3, 2, 1)) shouldBe true3 decreasing(listOf(3, 3, 1)) shouldBe false4 decreasing(listOf(3, 3, 3)) shouldBe false5 decreasing(listOf(1, 2, 1)) shouldBe false6 decreasing(listOf(1, 2, 3, 2, 1)) shouldBe true7 decreasing(listOf(1, 2, 3, 3, 1)) shouldBe false8 increasing(listOf(1, 2, 3)) shouldBe true9 increasing(listOf(3, 2, 1)) shouldBe false10 increasing(listOf(3, 3, 1)) shouldBe false11 increasing(listOf(3, 3, 3)) shouldBe false12 increasing(listOf(1, 2, 1)) shouldBe false13 increasing(listOf(1, 2, 3, 2, 1)) shouldBe false14 increasing(listOf(1, 2, 3, 3, 1)) shouldBe false15}16Test Passed: decreasing(listOf(1, 2, 3)) shouldBe true17Test Passed: decreasing(listOf(3, 2, 1)) shouldBe true18Test Passed: decreasing(listOf(3, 3, 1)) shouldBe false19Test Passed: decreasing(listOf(3, 3, 3)) shouldBe false20Test Passed: decreasing(listOf(1, 2, 1)) shouldBe false21Test Passed: decreasing(listOf(1, 2, 3, 2, 1)) shouldBe true22Test Passed: decreasing(listOf(1, 2, 3, 3, 1)) shouldBe false23Test Passed: increasing(listOf(1, 2, 3)) shouldBe true24Test Passed: increasing(listOf(3, 2, 1)) shouldBe false25Test Passed: increasing(listOf(3, 3, 1)) shouldBe false26Test Passed: increasing(listOf(3, 3, 3)) shouldBe false27Test Passed: increasing(listOf(1,
test
Using AI Code Generation
1 test("should pass when collection is decreasing") {2 decreasing(4, 3, 2, 1) shouldBe true3 }4 test("should fail when collection is not decreasing") {5 decreasing(4, 3, 2, 3) shouldBe true6 }7})8 test("should pass when collection is increasing") {9 increasing(1, 2, 3, 4) shouldBe true10 }11 test("should fail when collection is not increasing") {12 increasing(4, 3, 2, 3) shouldBe true13 }14})15 test("should pass when collection is sorted") {16 isSorted(listOf(1, 2, 3, 4)) shouldBe true17 }18 test("should fail when collection is not sorted") {19 isSorted(listOf(4, 3, 2, 3)) shouldBe true20 }21})22 test("should pass when collection is sorted by specified function") {23 isSortedBy(listOf(1, 2, 3, 4)) { it } shouldBe true24 }25 test("should fail when collection is not sorted by specified function") {26 isSortedBy(listOf(4, 3, 2, 3)) { it } shouldBe true27 }28})29 test("should pass when collection is sorted with specified comparator") {30 isSortedWith(listOf(1, 2, 3, 4), compareBy { it }) shouldBe true31 }32 test("should fail when collection is not sorted with specified comparator") {33 isSortedWith(listOf(4, 3, 2, 3), compareBy { it }) shouldBe true34 }35})
test
Using AI Code Generation
1Expected: (an instance of java.lang.AssertionError and exception with message a string containing "Expected [1, 2, 3] to be decreasing")2at io.kotest.matchers.collections.decreasingTest$Decreasing should test if the collection is decreasing$1.invokeSuspend(decreasingTest.kt:10)3at io.kotest.matchers.collections.decreasingTest$Decreasing should test if the collection is decreasing$1.invoke(decreasingTest.kt)4at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)5at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)6at kotlinx.coroutines.test.TestCoroutineDispatcher.dispatch(TestCoroutineDispatcher.kt:50)7at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:340)8at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)9at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)10at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!