From 2404156e735c1e311a4cfca63bce72ca3f41d20a Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Tue, 10 Mar 2020 22:02:55 +0100 Subject: [PATCH] add missing specs for feature functions for the new infix API ...and fix some issues: - add the missing function for FeatureWithCreator for 5 params - use method call formatter for KFunctionX --- .../api/infix/en_GB/featureAssertions.kt | 31 +++-- ...sertionsBoundedReferenceAlternativeSpec.kt | 127 +++++++++++++++++ .../FeatureAssertionsBoundedReferenceSpec.kt | 130 ++++++++++++++++++ .../FeatureAssertionsClassReferenceSpec.kt | 126 +++++++++++++++++ .../en_GB/FeatureAssertionsManualSpec.kt | 118 ++++++++++++++++ .../api/infix/en_GB/FeatureWorstCaseTest.kt | 27 ++++ 6 files changed, 548 insertions(+), 11 deletions(-) create mode 100644 apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceAlternativeSpec.kt create mode 100644 apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceSpec.kt create mode 100644 apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsClassReferenceSpec.kt create mode 100644 apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsManualSpec.kt create mode 100644 apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureWorstCaseTest.kt diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/featureAssertions.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/featureAssertions.kt index 4b3c61686..3488d9004 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/featureAssertions.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/featureAssertions.kt @@ -4,6 +4,7 @@ import ch.tutteli.atrium.api.infix.en_GB.creating.feature.Feature import ch.tutteli.atrium.api.infix.en_GB.creating.feature.FeatureWithCreator import ch.tutteli.atrium.api.infix.en_GB.creating.feature.MetaFeatureOptionWithCreator import ch.tutteli.atrium.assertions.AssertionGroup +import ch.tutteli.atrium.core.coreFactory import ch.tutteli.atrium.creating.Expect import ch.tutteli.atrium.creating.FeatureExpect import ch.tutteli.atrium.domain.builders.ExpectImpl @@ -159,31 +160,31 @@ fun MetaFeatureOption.f(description: String, provider: R): MetaFeature * Helper function to create a [Feature] based on a [KFunction2] + arguments. */ fun of(f: KFunction2, a1: A1): Feature = - Feature(f.name) { f.invoke(it, a1) } + Feature(formatMethodCall(f, a1)) { f.invoke(it, a1) } /** * Helper function to create a [Feature] based on a [KFunction3] + arguments. */ fun of(f: KFunction3, a1: A1, a2: A2): Feature = - Feature(f.name) { f.invoke(it, a1, a2) } + Feature(formatMethodCall(f, a1, a2)) { f.invoke(it, a1, a2) } /** * Helper function to create a [Feature] based on a [KFunction4] + arguments. */ fun of(f: KFunction4, a1: A1, a2: A2, a3: A3): Feature = - Feature(f.name) { f.invoke(it, a1, a2, a3) } + Feature(formatMethodCall(f, a1, a2, a3)) { f.invoke(it, a1, a2, a3) } /** * Helper function to create a [Feature] based on a [KFunction5] + arguments. */ fun of(f: KFunction5, a1: A1, a2: A2, a3: A3, a4: A4): Feature = - Feature(f.name) { f.invoke(it, a1, a2, a3, a4) } + Feature(formatMethodCall(f, a1, a2, a3, a4)) { f.invoke(it, a1, a2, a3, a4) } /** - * Helper function to create a [Feature] based on a [KFunction5] + arguments. + * Helper function to create a [Feature] based on a [KFunction6] + arguments. */ fun of(f: KFunction6, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): Feature = - Feature(f.name) { f.invoke(it, a1, a2, a3, a4, a5) } + Feature(formatMethodCall(f, a1, a2, a3, a4, a5)) { f.invoke(it, a1, a2, a3, a4, a5) } /** * Helper function to create a [FeatureWithCreator] based on a [KProperty1] + [assertionCreator]. @@ -195,33 +196,41 @@ fun of(property: KProperty1, assertionCreator: Expect.() -> U * Helper function to create a [FeatureWithCreator] based on a [KFunction1] + [assertionCreator]. */ fun of(f: KFunction1, assertionCreator: Expect.() -> Unit): FeatureWithCreator = - FeatureWithCreator(f.name, { f.invoke(it) }, assertionCreator) + FeatureWithCreator(formatMethodCall(f), { f.invoke(it) }, assertionCreator) /** * Helper function to create a [FeatureWithCreator] based on a [KFunction2] + arguments + [assertionCreator]. */ fun of(f: KFunction2, a1: A1, assertionCreator: Expect.() -> Unit): FeatureWithCreator = - FeatureWithCreator(f.name, { f.invoke(it, a1) }, assertionCreator) + FeatureWithCreator(formatMethodCall(f, a1), { f.invoke(it, a1) }, assertionCreator) /** * Helper function to create a [FeatureWithCreator] based on a [KFunction3] + arguments + [assertionCreator]. */ fun of(f: KFunction3, a1: A1, a2: A2, assertionCreator: Expect.() -> Unit): FeatureWithCreator = - FeatureWithCreator(f.name, { f.invoke(it, a1, a2) }, assertionCreator) + FeatureWithCreator(formatMethodCall(f, a1, a2), { f.invoke(it, a1, a2) }, assertionCreator) /** * Helper function to create a [FeatureWithCreator] based on a [KFunction4] + arguments + [assertionCreator]. */ fun of(f: KFunction4, a1: A1, a2: A2, a3: A3, assertionCreator: Expect.() -> Unit): FeatureWithCreator = - FeatureWithCreator(f.name, { f.invoke(it, a1, a2, a3) }, assertionCreator) + FeatureWithCreator(formatMethodCall(f, a1, a2, a3), { f.invoke(it, a1, a2, a3) }, assertionCreator) /** * Helper function to create a [FeatureWithCreator] based on a [KFunction5] + arguments + [assertionCreator]. */ fun of(f: KFunction5, a1: A1, a2: A2, a3: A3, a4: A4, assertionCreator: Expect.() -> Unit): FeatureWithCreator = - FeatureWithCreator(f.name, { f.invoke(it, a1, a2, a3, a4) }, assertionCreator) + FeatureWithCreator(formatMethodCall(f, a1, a2, a3, a4), { f.invoke(it, a1, a2, a3, a4) }, assertionCreator) + +/** + * Helper function to create a [FeatureWithCreator] based on a [KFunction6] + arguments + [assertionCreator]. + */ +fun of(f: KFunction6, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, assertionCreator: Expect.() -> Unit): FeatureWithCreator = + FeatureWithCreator(formatMethodCall(f, a1, a2, a3, a4, a5), { f.invoke(it, a1, a2, a3, a4, a5) }, assertionCreator) //@formatter:on +private fun formatMethodCall(k: KCallable<*>, vararg args: Any?) = + coreFactory.newMethodCallFormatter().formatCall(k.name, args) /** * Helper function to create a [MetaFeatureOptionWithCreator] based on a lambda with diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceAlternativeSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceAlternativeSpec.kt new file mode 100644 index 000000000..5019cbc67 --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceAlternativeSpec.kt @@ -0,0 +1,127 @@ +package ch.tutteli.atrium.api.infix.en_GB + +import ch.tutteli.atrium.api.infix.en_GB.workaround.it +import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.integration.TestData +import ch.tutteli.atrium.specs.notImplemented +import ch.tutteli.atrium.specs.testutils.WithAsciiReporter + +class FeatureAssertionsBoundedReferenceAlternativeSpec : ch.tutteli.atrium.specs.integration.FeatureAssertionsSpec( + propertyImmediate, + propertyLazy, + f0Immediate, + f1Immediate, + f2Immediate, + f3Immediate, + f4Immediate, + f5Immediate, + f0Lazy, + f1Lazy, + f2Lazy, + f3Lazy, + f4Lazy, + f5Lazy, + + propertyNullableDoesNotHold, + f0NullableDoesNotHold, + f1NullableDoesNotHold, + f2NullableDoesNotHold, + f3NullableDoesNotHold, + f4NullableDoesNotHold, + f5NullableDoesNotHold, + + propertyNullableHolds, + f0NullableHolds, + f1NullableHolds, + f2NullableHolds, + f3NullableHolds, + f4NullableHolds, + f5NullableHolds, + + propertyLazyWithNestedImmediate, + propertyLazyWithNestedLazy, + + propertyEmptyAssertionCreator, + f0EmptyAssertionCreator, + f1EmptyAssertionCreator, + f2EmptyAssertionCreator, + f3EmptyAssertionCreator, + f4EmptyAssertionCreator, + f5EmptyAssertionCreator, + + isAbleToEvaluateDescription = false +) { + + //TODO remove type parameters for `of` with Kotiln 1.4 including parentheses (make the calls infix again + companion object : WithAsciiReporter() { + //@formatter:off + val propertyImmediate: F = { o feature { p(it::nonNullValue) } contains "hello" } + val propertyLazy: F = { o feature of({ p(it::nonNullValue) }) { o contains "hello" } } + val f0Immediate: F = { o feature { f0(it::return0) } contains "hello" } + val f1Immediate: F = { o feature { f1(it::return1, "a") } contains "hello" } + val f2Immediate: F = { o feature { f2(it::return2, "a", 1) } contains "hello" } + val f3Immediate: F = { o feature { f3(it::return3, "a", 1, true) } contains "hello" } + val f4Immediate: F = { o feature { f4(it::return4, "a", 1, true, 1.2) } contains "hello" } + val f5Immediate: F = { o feature { f5(it::return5, "a", 1, true, 1.2, 'b') } contains "hello" } + val f0Lazy: F = { o feature of({ f0(it::return0) }) { o contains "hello" } } + val f1Lazy: F = { o feature of({ f1(it::return1, "a") }) { o contains "hello" } } + val f2Lazy: F = { o feature of({ f2(it::return2, "a", 1) }) { o contains "hello" } } + val f3Lazy: F = { o feature of({ f3(it::return3, "a", 1, true) }) { o contains "hello" } } + val f4Lazy: F = { o feature of({ f4(it::return4, "a", 1, true, 1.2) }) { o contains "hello" } } + val f5Lazy: F = { o feature of({ f5(it::return5, "a", 1, true, 1.2, 'b') }) { o contains "hello" } } + + val propertyNullableDoesNotHold: F = { o feature { p(it::nullableValue) } toBe null } + val f0NullableDoesNotHold: F = { o feature { f0(it::returnNullable0) } toBe null } + val f1NullableDoesNotHold: F = { o feature { f1(it::returnNullable1, "a") } toBe null } + val f2NullableDoesNotHold: F = { o feature { f2(it::returnNullable2, "a", 1) } toBe null } + val f3NullableDoesNotHold: F = { o feature { f3(it::returnNullable3, "a", 1, true) } toBe null } + val f4NullableDoesNotHold: F = { o feature { f4(it::returnNullable4, "a", 1, true, 1.2) } toBe null } + val f5NullableDoesNotHold: F = { o feature { f5(it::returnNullable5, "a", 1, true, 1.2, 'b') } toBe null } + + val propertyNullableHolds: F = { o feature { p(it::nullableValue) } notToBeNull { o toBe 1 } } + val f0NullableHolds: F = { o feature { f0(it::returnNullable0) } notToBeNull { o toBe 1 } } + val f1NullableHolds: F = { o feature { f1(it::returnNullable1, "a") } notToBeNull { o toBe 1 } } + val f2NullableHolds: F = { o feature { f2(it::returnNullable2, "a", 1) } notToBeNull { o toBe 1 } } + val f3NullableHolds: F = { o feature { f3(it::returnNullable3, "a", 1, true) } notToBeNull { o toBe 1 } } + val f4NullableHolds: F = { o feature { f4(it::returnNullable4, "a", 1, true, 1.2) } notToBeNull { o toBe 1 } } + val f5NullableHolds: F = { o feature { f5(it::returnNullable5, "a", 1, true, 1.2, 'b') } notToBeNull { o toBe 1 } } + //@formatter:on + + val propertyLazyWithNestedImmediate: F = { + o feature { p(it::nonNullValue) } it { + o feature { p(it::length) } toBe 12 + } + } + val propertyLazyWithNestedLazy: F = { + o feature { p(it::nonNullValue) } it { + o feature { p(it::length) } it { o toBe 12 } + } + } + + val propertyEmptyAssertionCreator: F = { o feature of({ p(it::nonNullValue) }) {} } + val f0EmptyAssertionCreator: F = { o feature of({ f0(it::return0) }) {} } + val f1EmptyAssertionCreator: F = { o feature of({ f1(it::return1, "a") }) {} } + val f2EmptyAssertionCreator: F = { o feature of({ f2(it::return2, "a", 1) }) {} } + val f3EmptyAssertionCreator: F = { o feature of({ f3(it::return3, "a", 1, true) }) {} } + val f4EmptyAssertionCreator: F = { o feature of({ f4(it::return4, "a", 1, true, 1.2) }) {} } + val f5EmptyAssertionCreator: F = + { o feature (of({ f5(it::return5, "a", 1, true, 1.2, 'b') }) {}) } + } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + val a1: Expect> = notImplemented() + val a1b: Expect> = notImplemented() + + val star: Expect> = notImplemented() + + a1 feature { p(it::size) } + a1 feature { p(it::size) } it {} + + a1b feature { p(it::size) } + a1b feature { p(it::size) } it {} + + star feature { p(it::size) } + star feature { p(it::size) } it {} + } +} diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceSpec.kt new file mode 100644 index 000000000..9fa1463b9 --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsBoundedReferenceSpec.kt @@ -0,0 +1,130 @@ +package ch.tutteli.atrium.api.infix.en_GB + +import ch.tutteli.atrium.api.infix.en_GB.workaround.it +import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.integration.TestData +import ch.tutteli.atrium.specs.notImplemented +import ch.tutteli.atrium.specs.testutils.WithAsciiReporter + +internal typealias F = Expect.() -> Unit + +class FeatureAssertionsBoundedReferenceSpec : ch.tutteli.atrium.specs.integration.FeatureAssertionsSpec( + propertyImmediate, + propertyLazy, + f0Immediate, + f1Immediate, + f2Immediate, + f3Immediate, + f4Immediate, + f5Immediate, + f0Lazy, + f1Lazy, + f2Lazy, + f3Lazy, + f4Lazy, + f5Lazy, + + propertyNullableDoesNotHold, + f0NullableDoesNotHold, + f1NullableDoesNotHold, + f2NullableDoesNotHold, + f3NullableDoesNotHold, + f4NullableDoesNotHold, + f5NullableDoesNotHold, + + propertyNullableHolds, + f0NullableHolds, + f1NullableHolds, + f2NullableHolds, + f3NullableHolds, + f4NullableHolds, + f5NullableHolds, + + propertyLazyWithNestedImmediate, + propertyLazyWithNestedLazy, + + propertyEmptyAssertionCreator, + f0EmptyAssertionCreator, + f1EmptyAssertionCreator, + f2EmptyAssertionCreator, + f3EmptyAssertionCreator, + f4EmptyAssertionCreator, + f5EmptyAssertionCreator, + + isAbleToEvaluateDescription = false +) { + + //TODO remove type parameters for `of` with Kotiln 1.4 including parentheses (make the calls infix again + companion object : WithAsciiReporter() { + //@formatter:off + val propertyImmediate: F = { o feature { f(it::nonNullValue) } contains "hello" } + val propertyLazy: F = { o feature of({ f(it::nonNullValue) }) { o contains "hello" } } + val f0Immediate: F = { o feature { f(it::return0) } contains "hello" } + val f1Immediate: F = { o feature { f(it::return1, "a") } contains "hello" } + val f2Immediate: F = { o feature { f(it::return2, "a", 1) } contains "hello" } + val f3Immediate: F = { o feature { f(it::return3, "a", 1, true) } contains "hello" } + val f4Immediate: F = { o feature { f(it::return4, "a", 1, true, 1.2) } contains "hello" } + val f5Immediate: F = { o feature { f(it::return5, "a", 1, true, 1.2, 'b') } contains "hello" } + val f0Lazy: F = { o feature of({ f(it::return0) }) { o contains "hello" } } + val f1Lazy: F = { o feature of({ f(it::return1, "a") }) { o contains "hello" } } + val f2Lazy: F = { o feature of({ f(it::return2, "a", 1) }) { o contains "hello" } } + val f3Lazy: F = { o feature of({ f(it::return3, "a", 1, true) }) { o contains "hello" } } + val f4Lazy: F = { o feature of({ f(it::return4, "a", 1, true, 1.2) }) { o contains "hello" } } + val f5Lazy: F = { o feature of({ f(it::return5, "a", 1, true, 1.2, 'b') }) { o contains "hello" } } + + val propertyNullableDoesNotHold: F = { o feature { f(it::nullableValue) } toBe null } + val f0NullableDoesNotHold: F = { o feature { f(it::returnNullable0) } toBe null } + val f1NullableDoesNotHold: F = { o feature { f(it::returnNullable1, "a") } toBe null } + val f2NullableDoesNotHold: F = { o feature { f(it::returnNullable2, "a", 1) } toBe null } + val f3NullableDoesNotHold: F = { o feature { f(it::returnNullable3, "a", 1, true) } toBe null } + val f4NullableDoesNotHold: F = { o feature { f(it::returnNullable4, "a", 1, true, 1.2) } toBe null } + val f5NullableDoesNotHold: F = { o feature { f(it::returnNullable5, "a", 1, true, 1.2, 'b') } toBe null } + + val propertyNullableHolds: F = { o feature { f(it::nullableValue) } notToBeNull { o toBe 1 } } + val f0NullableHolds: F = { o feature { f(it::returnNullable0) } notToBeNull { o toBe 1 } } + val f1NullableHolds: F = { o feature { f(it::returnNullable1, "a") } notToBeNull { o toBe 1 } } + val f2NullableHolds: F = { o feature { f(it::returnNullable2, "a", 1) } notToBeNull { o toBe 1 } } + val f3NullableHolds: F = { o feature { f(it::returnNullable3, "a", 1, true) } notToBeNull { o toBe 1 } } + val f4NullableHolds: F = { o feature { f(it::returnNullable4, "a", 1, true, 1.2) } notToBeNull { o toBe 1 } } + val f5NullableHolds: F = { o feature { f(it::returnNullable5, "a", 1, true, 1.2, 'b') } notToBeNull { o toBe 1 } } + //@formatter:on + + val propertyLazyWithNestedImmediate: F = { + o feature of({ f(it::nonNullValue) }) { + feature { f(it::length) } toBe 12 + } + } + val propertyLazyWithNestedLazy: F = { + o feature of({ f(it::nonNullValue) }) { + feature { f(it::length) } it { o toBe 12 } + } + } + + val propertyEmptyAssertionCreator: F = { o feature of({ f(it::nonNullValue) }) {} } + val f0EmptyAssertionCreator: F = { o feature of({ f(it::return0) }) {} } + val f1EmptyAssertionCreator: F = { o feature of({ f(it::return1, "a") }) {} } + val f2EmptyAssertionCreator: F = { o feature of({ f(it::return2, "a", 1) }) {} } + val f3EmptyAssertionCreator: F = { o feature of({ f(it::return3, "a", 1, true) }) {} } + val f4EmptyAssertionCreator: F = { o feature of({ f(it::return4, "a", 1, true, 1.2) }) {} } + val f5EmptyAssertionCreator: F = + { o feature of({ f(it::return5, "a", 1, true, 1.2, 'b') }) {} } + } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + val a1: Expect> = notImplemented() + val a1b: Expect> = notImplemented() + + val star: Expect> = notImplemented() + + a1 feature { f(it::size) } + a1 feature { f(it::size) } it {} + + a1b feature { f(it::size) } + a1b feature { f(it::size) } it {} + + star feature { f(it::size) } + star feature { f(it::size) } it {} + } +} + diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsClassReferenceSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsClassReferenceSpec.kt new file mode 100644 index 000000000..901cde901 --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsClassReferenceSpec.kt @@ -0,0 +1,126 @@ +package ch.tutteli.atrium.api.infix.en_GB + +import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.integration.TestData +import ch.tutteli.atrium.specs.notImplemented +import ch.tutteli.atrium.specs.testutils.WithAsciiReporter + +class FeatureAssertionsClassReferenceSpec : ch.tutteli.atrium.specs.integration.FeatureAssertionsSpec( + propertyImmediate, + propertyLazy, + return0ValueImmediate, + return1ValueImmediate, + return2ValueImmediate, + return3ValueImmediate, + return4ValueImmediate, + return5ValueImmediate, + return0ValueLazy, + return1ValueLazy, + return2ValueLazy, + return3ValueLazy, + return4ValueLazy, + return5ValueLazy, + + propertyNullableDoesNotHold, + return0ValueNullableDoesNotHold, + return1ValueNullableDoesNotHold, + return2ValueNullableDoesNotHold, + return3ValueNullableDoesNotHold, + return4ValueNullableDoesNotHold, + return5ValueNullableDoesNotHold, + + propertyNullableHolds, + return0ValueNullableHolds, + return1ValueNullableHolds, + return2ValueNullableHolds, + return3ValueNullableHolds, + return4ValueNullableHolds, + return5ValueNullableHolds, + + propertyLazyWithNestedImmediate, + propertyLazyWithNestedLazy, + + propertyEmptyAssertionCreator, + f0EmptyAssertionCreator, + f1EmptyAssertionCreator, + f2EmptyAssertionCreator, + f3EmptyAssertionCreator, + f4EmptyAssertionCreator, + f5EmptyAssertionCreator, + + isAbleToEvaluateDescription = true +) { + + //TODO remove type parameters for `of` with Kotiln 1.4 including parentheses (make the calls infix again + companion object : WithAsciiReporter() { + //@formatter:off + val propertyImmediate: F = { o feature TestData::nonNullValue contains "hello" } + val propertyLazy: F = { o feature of(TestData::nonNullValue) { o contains "hello" } } + val return0ValueImmediate: F = { o feature TestData::return0 contains "hello" } + val return1ValueImmediate: F = { o feature of(TestData::return1, "a") contains "hello" } + val return2ValueImmediate: F = { o feature of(TestData::return2, "a", 1) contains "hello" } + val return3ValueImmediate: F = { o feature of(TestData::return3, "a", 1, true) contains "hello" } + val return4ValueImmediate: F = { o feature of(TestData::return4, "a", 1, true, 1.2) contains "hello" } + val return5ValueImmediate: F = { o feature of(TestData::return5, "a", 1, true, 1.2, 'b') contains "hello" } + val return0ValueLazy: F = { o feature of(TestData::return0) { contains("hello") } } + val return1ValueLazy: F = { o feature of(TestData::return1, "a") { contains("hello") } } + val return2ValueLazy: F = { o feature of(TestData::return2, "a", 1) { contains("hello") } } + val return3ValueLazy: F = { o feature of(TestData::return3, "a", 1, true) { contains("hello") } } + val return4ValueLazy: F = { o feature of(TestData::return4, "a", 1, true, 1.2) { contains("hello") } } + val return5ValueLazy: F = { o feature of(TestData::return5, "a", 1, true, 1.2, 'b') { contains("hello") } } + + val propertyNullableDoesNotHold: F = { o feature TestData::nullableValue toBe null } + val return0ValueNullableDoesNotHold: F = { o feature TestData::returnNullable0 toBe null } + val return1ValueNullableDoesNotHold: F = { o feature of(TestData::returnNullable1, "a") toBe null } + val return2ValueNullableDoesNotHold: F = { o feature of(TestData::returnNullable2, "a", 1) toBe null } + val return3ValueNullableDoesNotHold: F = { o feature of(TestData::returnNullable3, "a", 1, true) toBe null } + val return4ValueNullableDoesNotHold: F = { o feature of(TestData::returnNullable4, "a", 1, true, 1.2) toBe null } + val return5ValueNullableDoesNotHold: F = { o feature of(TestData::returnNullable5, "a", 1, true, 1.2, 'b') toBe null } + + val propertyNullableHolds: F = { o feature TestData::nullableValue notToBeNull { o toBe 1 } } + val return0ValueNullableHolds: F = { o feature TestData::returnNullable0 notToBeNull { o toBe 1 } } + val return1ValueNullableHolds: F = { o feature of(TestData::returnNullable1, "a") notToBeNull { o toBe 1 } } + val return2ValueNullableHolds: F = { o feature of(TestData::returnNullable2, "a", 1) notToBeNull { o toBe 1 } } + val return3ValueNullableHolds: F = { o feature of(TestData::returnNullable3, "a", 1, true) notToBeNull { o toBe 1 } } + val return4ValueNullableHolds: F = { o feature of(TestData::returnNullable4, "a", 1, true, 1.2) notToBeNull { o toBe 1 } } + val return5ValueNullableHolds: F = { o feature of(TestData::returnNullable5, "a", 1, true, 1.2, 'b') notToBeNull { o toBe 1 } } + //@formatter:on + + val propertyLazyWithNestedImmediate: F = { + o feature of(TestData::nonNullValue) { + o feature String::length toBe 12 + } + } + val propertyLazyWithNestedLazy: F = { + o feature of(TestData::nonNullValue) { + o feature of(String::length) { o toBe (12) } + } + } + + val propertyEmptyAssertionCreator: F = { o feature of(TestData::nonNullValue) {} } + val f0EmptyAssertionCreator: F = { o feature of(TestData::return0) {} } + val f1EmptyAssertionCreator: F = { o feature of(TestData::return1, "a") {} } + val f2EmptyAssertionCreator: F = { o feature of(TestData::return2, "a", 1) {} } + val f3EmptyAssertionCreator: F = { o feature of(TestData::return3, "a", 1, true) {} } + val f4EmptyAssertionCreator: F = { o feature of(TestData::return4, "a", 1, true, 1.2) {} } + val f5EmptyAssertionCreator: F = { o feature of(TestData::return5, "a", 1, true, 1.2, 'b') {} } + } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + val a1: Expect> = notImplemented() + val a1b: Expect> = notImplemented() + + val star: Expect> = notImplemented() + + a1 feature Collection<*>::size + a1 feature of(Collection<*>::size) {} + + a1b feature Collection<*>::size + a1b feature of(Collection<*>::size) {} + + star feature Collection<*>::size + star feature of(Collection<*>::size) {} + } +} + diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsManualSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsManualSpec.kt new file mode 100644 index 000000000..9a544d521 --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureAssertionsManualSpec.kt @@ -0,0 +1,118 @@ +package ch.tutteli.atrium.api.infix.en_GB + +import ch.tutteli.atrium.api.infix.en_GB.workaround.it +import ch.tutteli.atrium.specs.integration.TestData +import ch.tutteli.atrium.specs.testutils.WithAsciiReporter + + +class FeatureAssertionsManualSpec : ch.tutteli.atrium.specs.integration.FeatureAssertionsSpec( + propertyImmediate, + propertyLazy, + f0Immediate, + f1Immediate, + f2Immediate, + f3Immediate, + f4Immediate, + f5Immediate, + f0Lazy, + f1Lazy, + f2Lazy, + f3Lazy, + f4Lazy, + f5Lazy, + + propertyNullableDoesNotHold, + f0NullableDoesNotHold, + f1NullableDoesNotHold, + f2NullableDoesNotHold, + f3NullableDoesNotHold, + f4NullableDoesNotHold, + f5NullableDoesNotHold, + + propertyNullableHolds, + f0NullableHolds, + f1NullableHolds, + f2NullableHolds, + f3NullableHolds, + f4NullableHolds, + f5NullableHolds, + + propertyLazyWithNestedImmediate, + propertyLazyWithNestedLazy, + + propertyEmptyAssertionCreator, + f0EmptyAssertionCreator, + f1EmptyAssertionCreator, + f2EmptyAssertionCreator, + f3EmptyAssertionCreator, + f4EmptyAssertionCreator, + f5EmptyAssertionCreator, + + isAbleToEvaluateDescription = false +) { + //TODO remove type parameters for `of` with Kotiln 1.4 including parentheses (make the calls infix again + companion object : WithAsciiReporter() { + //@formatter:off + val propertyImmediate: F = { o feature { f("nonNullValue", it.nonNullValue) } contains "hello" } + + val propertyLazy: F = { o feature(of({ f("nonNullValue", it.nonNullValue) }) { o contains "hello" }) } + val f0Immediate: F = { o feature { f("return0()", it.return0()) } contains "hello" } + val f1Immediate: F = { o feature { f("return1(\"a\")", it.return1("a")) } contains "hello" } + val f2Immediate: F = { o feature { f("return2(\"a\", 1)", it.return2("a", 1)) } contains "hello" } + val f3Immediate: F = { o feature { f("return3(\"a\", 1, true)", it.return3("a", 1, true)) } contains "hello" } + val f4Immediate: F = { o feature { f("return4(\"a\", 1, true, 1.2)", it.return4("a", 1, true, 1.2)) } contains "hello" } + val f5Immediate: F = { o feature { f("return5(\"a\", 1, true, 1.2, 'b')", it.return5("a", 1, true, 1.2, 'b')) } contains "hello" } + val f0Lazy: F = { o feature of({ f("return0()", it.return0()) }) { o contains "hello" } } + val f1Lazy: F = { o feature of({ f("return1(\"a\")", it.return1("a")) }) { o contains "hello" } } + val f2Lazy: F = { o feature of({ f("return2(\"a\", 1)", it.return2("a", 1)) }) { o contains "hello" } } + val f3Lazy: F = { o feature of({ f("return3(\"a\", 1, true)", it.return3("a", 1, true)) }) { o contains "hello" } } + val f4Lazy: F = { o feature of({ f("return4(\"a\", 1, true, 1.2)", it.return4("a", 1, true, 1.2)) }) { o contains "hello" } } + val f5Lazy: F = { o feature of({ f("return5(\"a\", 1, true, 1.2, 'b')", it.return5("a", 1, true, 1.2, 'b')) }) { o contains "hello" } } + + val propertyNullableDoesNotHold: F = { o feature { f("nullableValue", it.nullableValue) } toBe null } + val f0NullableDoesNotHold: F = { o feature { f("returnNullable0()", it.returnNullable0()) } toBe null } + val f1NullableDoesNotHold: F = { o feature { f("returnNullable1(\"a\")", it.returnNullable1("a")) } toBe null } + val f2NullableDoesNotHold: F = { o feature { f("returnNullable2(\"a\", 1)", it.returnNullable2("a", 1)) } toBe null } + val f3NullableDoesNotHold: F = { o feature { f("returnNullable3(\"a\", 1, true)", it.returnNullable3("a", 1, true)) } toBe null } + val f4NullableDoesNotHold: F = { o feature { f("returnNullable4(\"a\", 1, true, 1.2)", it.returnNullable4("a", 1, true, 1.2)) } toBe null } + val f5NullableDoesNotHold: F = { o feature { f("returnNullable5(\"a\", 1, true, 1.2, 'b')", it.returnNullable5("a", 1, true, 1.2, 'b')) } toBe null } + + val propertyNullableHolds: F = { o feature { f("nullableValue", it.nullableValue) } notToBeNull { o toBe 1 } } + val f0NullableHolds: F = { o feature { f("returnNullable0()", it.returnNullable0()) } notToBeNull { o toBe 1 } } + val f1NullableHolds: F = { o feature { f("returnNullable1(\"a\")", it.returnNullable1("a")) } notToBeNull { o toBe 1 } } + val f2NullableHolds: F = { o feature { f("returnNullable2(\"a\", 1)", it.returnNullable2("a", 1)) } notToBeNull { o toBe 1 } } + val f3NullableHolds: F = { o feature { f("returnNullable3(\"a\", 1, true)", it.returnNullable3("a", 1, true)) } notToBeNull { o toBe 1 } } + val f4NullableHolds: F = { o feature { f("returnNullable4(\"a\", 1, true, 1.2)", it.returnNullable4("a", 1, true, 1.2)) } notToBeNull { o toBe 1 } } + val f5NullableHolds: F = { o feature { f("returnNullable5(\"a\", 1, true, 1.2, 'b')", it.returnNullable5("a", 1, true, 1.2, 'b')) } notToBeNull { o toBe 1 } } + //@formatter:on + + val propertyLazyWithNestedImmediate: F = { + o feature of({ f("nonNullValue", it.nonNullValue) }) { + feature { f("length", it.length) } toBe 12 + } + } + val propertyLazyWithNestedLazy: F = { + o feature of({ f("nonNullValue", it.nonNullValue) }) { + feature { f("length", it.length) } it { o toBe 12 } + } + } + + val propertyEmptyAssertionCreator: F = + { o feature of({ f("nonNullValue", it.nonNullValue) }) {} } + val f0EmptyAssertionCreator: F = { o feature of({ f("return0()", it.return0()) }) {} } + val f1EmptyAssertionCreator: F = { o feature of({ f("return1(\"a\")", it.return1("a")) }) {} } + val f2EmptyAssertionCreator: F = + { o feature of({ f("return2(\"a\", 1)", it.return2("a", 1)) }) {} } + val f3EmptyAssertionCreator: F = + { o feature of({ f("return3(\"a\", 1, true)", it.return3("a", 1, true)) }) {} } + val f4EmptyAssertionCreator: F = + { o feature of({ f("return4(\"a\", 1, true, 1.2)", it.return4("a", 1, true, 1.2)) }) {} } + val f5EmptyAssertionCreator: F = + { + o feature of({ + f("return5(\"a\", 1, true, 1.2, 'b')", it.return5("a", 1, true, 1.2, 'b')) + }) {} + } + } +} + diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureWorstCaseTest.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureWorstCaseTest.kt new file mode 100644 index 000000000..7d69a4bd0 --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/FeatureWorstCaseTest.kt @@ -0,0 +1,27 @@ +@file:Suppress("UNUSED_PARAMETER", "unused") + +package ch.tutteli.atrium.api.infix.en_GB + +import ch.tutteli.atrium.api.verbs.internal.expect +import kotlin.js.JsName + +class WorstCase { + + val propAndFun: Int = 1 + @JsName("propFun") + fun propAndFun(): Int = 1 + + fun overloaded(): Int = 1 + fun overloaded(b: Boolean): Int = 1 +} + + +@Suppress(/* requires new type inference */ "RemoveExplicitTypeArguments") +fun testOverloadAmbiguity() { + expect(WorstCase()) { + feature { p(it::propAndFun) } + feature { f0(it::propAndFun) } + feature { f0(it::overloaded) } + feature { f1(it::overloaded, true) } + } +}