From d7ad27ac3bb488f9c66f24570c33216b92b940bd Mon Sep 17 00:00:00 2001 From: Vsevolod Date: Mon, 10 Oct 2016 22:49:40 +0300 Subject: [PATCH] KT-5044 implement missing Range#contains tests and move it to separate package --- .../box/collections/inSetWithSmartCast.kt | 15 +++ .../box/ranges/contains/inComparableRange.kt | 18 ++++ .../box/ranges/contains/inExtensionRange.kt | 18 ++++ .../box/ranges/{ => contains}/inIntRange.kt | 0 .../contains/inOptimizableDoubleRange.kt | 33 +++++++ .../contains/inOptimizableFloatRange.kt | 33 +++++++ .../ranges/contains/inOptimizableIntRange.kt | 26 ++++++ .../ranges/contains/inOptimizableLongRange.kt | 26 ++++++ .../contains/inRangeWithCustomContains.kt | 24 +++++ .../contains/inRangeWithImplicitReceiver.kt | 19 ++++ .../inRangeWithNonmatchingArguments.kt | 12 +++ .../{ => contains}/rangeContainsString.kt | 0 .../codegen/BlackBoxCodegenTestGenerated.java | 93 ++++++++++++++++--- 13 files changed, 305 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/codegen/box/collections/inSetWithSmartCast.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inComparableRange.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inExtensionRange.kt rename compiler/testData/codegen/box/ranges/{ => contains}/inIntRange.kt (100%) create mode 100644 compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inOptimizableFloatRange.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inOptimizableIntRange.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inOptimizableLongRange.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inRangeWithImplicitReceiver.kt create mode 100644 compiler/testData/codegen/box/ranges/contains/inRangeWithNonmatchingArguments.kt rename compiler/testData/codegen/box/ranges/{ => contains}/rangeContainsString.kt (100%) diff --git a/compiler/testData/codegen/box/collections/inSetWithSmartCast.kt b/compiler/testData/codegen/box/collections/inSetWithSmartCast.kt new file mode 100644 index 00000000000..ee4987608d6 --- /dev/null +++ b/compiler/testData/codegen/box/collections/inSetWithSmartCast.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +fun contains(set: Set, x: Int): Boolean = when { + set.size == 0 -> false + else -> x in set as Set +} + +fun box(): String { + val set = setOf(1) + if (contains(set, 1)) { + return "OK" + } + + return "Fail" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inComparableRange.kt b/compiler/testData/codegen/box/ranges/contains/inComparableRange.kt new file mode 100644 index 00000000000..ef2591e7e15 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inComparableRange.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +class ComparablePair>(val first: T, val second: T) : Comparable> { + override fun compareTo(other: ComparablePair): Int { + val result = first.compareTo(other.first) + return if (result != 0) result else second.compareTo(other.second) + } +} + +fun box(): String { + assert("a" !in "b".."c") + assert("b" in "a".."d") + + assert(ComparablePair(2, 2) !in ComparablePair(1, 10)..ComparablePair(2, 1)) + assert(ComparablePair(2, 2) in ComparablePair(2, 0)..ComparablePair(2, 10)) + + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inExtensionRange.kt b/compiler/testData/codegen/box/ranges/contains/inExtensionRange.kt new file mode 100644 index 00000000000..5d53bb1a9fc --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inExtensionRange.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +operator fun Int.rangeTo(right: String): ClosedRange = this..this + 1 +operator fun Long.rangeTo(right: Double): ClosedRange = this..right.toLong() + 1 +operator fun String.rangeTo(right: Int): ClosedRange = this..this + +fun box(): String { + assert(0 !in 1.."a") + assert(1 in 1.."a") + + assert(0L !in 1L..2.0) + assert(2L in 1L..3.0) + + assert("a" !in "b"..1) + assert("a" in "a"..1) + + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/inIntRange.kt b/compiler/testData/codegen/box/ranges/contains/inIntRange.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/inIntRange.kt rename to compiler/testData/codegen/box/ranges/contains/inIntRange.kt diff --git a/compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt b/compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt new file mode 100644 index 00000000000..6466d5dca01 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +fun check(x: Double, left: Double, right: Double): Boolean { + val result = x in left..right + assert(result == checkUnoptimized(x, left..right)) + return result +} + +fun checkUnoptimized(x: Double, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1.0, 0.0, 2.0)) + assert(!check(1.0, -1.0, 0.0)) + + assert(check(Double.MIN_VALUE, 0.0, 1.0)) + assert(check(Double.MAX_VALUE, Double.MAX_VALUE - Double.MIN_VALUE, Double.MAX_VALUE)) + assert(check(Double.NaN, Double.NaN, Double.NaN)) + assert(!check(0.0, Double.NaN, Double.NaN)) + + assert(check(-0.0, -0.0, +0.0)) + assert(check(-0.0, -0.0, -0.0)) + assert(!check(-0.0, +0.0, +0.0)) + assert(!check(+0.0, -0.0, -0.0)) + assert(check(+0.0, +0.0, +0.0)) + assert(check(+0.0, -0.0, +0.0)) + + var value = 0.0 + assert(++value in 1.0..1.0) + assert(++value !in 1.0..1.0) + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inOptimizableFloatRange.kt b/compiler/testData/codegen/box/ranges/contains/inOptimizableFloatRange.kt new file mode 100644 index 00000000000..5088045945b --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inOptimizableFloatRange.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +fun check(x: Float, left: Float, right: Float): Boolean { + val result = x in left..right + assert(result == checkUnoptimized(x, left..right)) + return result +} + +fun checkUnoptimized(x: Float, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1.0f, 0.0f, 2.0f)) + assert(!check(1.0f, -1.0f, 0.0f)) + + assert(check(Float.MIN_VALUE, 0.0f, 1.0f)) + assert(check(Float.MAX_VALUE, Float.MAX_VALUE - Float.MIN_VALUE, Float.MAX_VALUE)) + assert(check(Float.NaN, Float.NaN, Float.NaN)) + assert(!check(0.0f, Float.NaN, Float.NaN)) + + assert(check(-0.0f, -0.0f, +0.0f)) + assert(check(-0.0f, -0.0f, -0.0f)) + assert(!check(-0.0f, +0.0f, +0.0f)) + assert(!check(+0.0f, -0.0f, -0.0f)) + assert(check(+0.0f, +0.0f, +0.0f)) + assert(check(+0.0f, -0.0f, +0.0f)) + + var value = 0.0f + assert(++value in 1.0f..1.0f) + assert(++value !in 1.0f..1.0f) + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inOptimizableIntRange.kt b/compiler/testData/codegen/box/ranges/contains/inOptimizableIntRange.kt new file mode 100644 index 00000000000..b1987e88213 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inOptimizableIntRange.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +fun check(x: Int, left: Int, right: Int): Boolean { + val result = x in left..right + assert(result == checkUnoptimized(x, left..right)) + return result +} + +fun checkUnoptimized(x: Int, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1, 0, 2)) + assert(!check(1, -1, 0)) + assert(!check(239, 239, 238)) + assert(check(239, 238, 239)) + + assert(check(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE)) + assert(check(Int.MAX_VALUE, Int.MIN_VALUE, Int.MAX_VALUE)) + + var value = 0 + assert(++value in 1..1) + assert(++value !in 1..1) + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inOptimizableLongRange.kt b/compiler/testData/codegen/box/ranges/contains/inOptimizableLongRange.kt new file mode 100644 index 00000000000..60fe9659d8f --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inOptimizableLongRange.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +fun check(x: Long, left: Long, right: Long): Boolean { + val result = x in left..right + assert(result == checkUnoptimized(x, left..right)) + return result +} + +fun checkUnoptimized(x: Long, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1L, 0L, 2L)) + assert(!check(1L, -1L, 0L)) + assert(!check(239L, 239L, 238L)) + assert(check(239L, 238L, 239L)) + + assert(check(Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE)) + assert(check(Long.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE)) + + var value = 0L + assert(++value in 1L..1L) + assert(++value !in 1L..1L) + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt b/compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt new file mode 100644 index 00000000000..2cf5c52bca2 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +class Value(val x: Int) : Comparable { + override fun compareTo(other: Value): Int { + throw AssertionError("Should not be called") + } +} + +class ValueRange(override val start: Value, + override val endInclusive: Value) : ClosedRange { + + override fun contains(value: Value): Boolean { + return value.x == 42 + } +} + +operator fun Value.rangeTo(other: Value): ClosedRange = ValueRange(this, other) + +fun box(): String { + assert(Value(42) in Value(1)..Value(2)) + assert(Value(41) !in Value(40)..Value(42)) + + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inRangeWithImplicitReceiver.kt b/compiler/testData/codegen/box/ranges/contains/inRangeWithImplicitReceiver.kt new file mode 100644 index 00000000000..7894f58f882 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inRangeWithImplicitReceiver.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +fun Long.inLongs(l: Long, r: Long): Boolean { + return this in l..r +} + +fun Double.inDoubles(l: Double, r: Double): Boolean { + return this in l..r +} + +fun box(): String { + assert(2L.inLongs(1L, 3L)) + assert(!2L.inLongs(0L, 1L)) + + assert(2.0.inDoubles(1.0, 3.0)) + assert(!2.0.inDoubles(0.0, 1.0)) + + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/contains/inRangeWithNonmatchingArguments.kt b/compiler/testData/codegen/box/ranges/contains/inRangeWithNonmatchingArguments.kt new file mode 100644 index 00000000000..7a95a32b8b2 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inRangeWithNonmatchingArguments.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +fun box(): String { + assert(Long.MAX_VALUE !in Int.MIN_VALUE..Int.MAX_VALUE) + assert(Int.MAX_VALUE in Long.MIN_VALUE..Long.MAX_VALUE) + assert(Double.MAX_VALUE !in Float.MIN_VALUE..Float.MAX_VALUE) + assert(Float.MIN_VALUE in 0..1) + assert(2.0 !in 1..0) + assert(1.0f in 0L..2L) + + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/rangeContainsString.kt b/compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/rangeContainsString.kt rename to compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index be8627c7cd0..f06eabea490 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -3550,6 +3550,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("inSetWithSmartCast.kt") + public void testInSetWithSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/collections/inSetWithSmartCast.kt"); + doTest(fileName); + } + @TestMetadata("irrelevantImplCharSequence.kt") public void testIrrelevantImplCharSequence() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/collections/irrelevantImplCharSequence.kt"); @@ -11185,30 +11191,93 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } - @TestMetadata("inIntRange.kt") - public void testInIntRange() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/inIntRange.kt"); - doTest(fileName); - } - @TestMetadata("multiAssignmentIterationOverIntRange.kt") public void testMultiAssignmentIterationOverIntRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt"); doTest(fileName); } - @TestMetadata("rangeContainsString.kt") - public void testRangeContainsString() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/rangeContainsString.kt"); - doTest(fileName); - } - @TestMetadata("safeCallRangeTo.kt") public void testSafeCallRangeTo() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/safeCallRangeTo.kt"); doTest(fileName); } + @TestMetadata("compiler/testData/codegen/box/ranges/contains") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contains extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInContains() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("inComparableRange.kt") + public void testInComparableRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt"); + doTest(fileName); + } + + @TestMetadata("inExtensionRange.kt") + public void testInExtensionRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inExtensionRange.kt"); + doTest(fileName); + } + + @TestMetadata("inIntRange.kt") + public void testInIntRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inIntRange.kt"); + doTest(fileName); + } + + @TestMetadata("inOptimizableDoubleRange.kt") + public void testInOptimizableDoubleRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt"); + doTest(fileName); + } + + @TestMetadata("inOptimizableFloatRange.kt") + public void testInOptimizableFloatRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableFloatRange.kt"); + doTest(fileName); + } + + @TestMetadata("inOptimizableIntRange.kt") + public void testInOptimizableIntRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableIntRange.kt"); + doTest(fileName); + } + + @TestMetadata("inOptimizableLongRange.kt") + public void testInOptimizableLongRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableLongRange.kt"); + doTest(fileName); + } + + @TestMetadata("inRangeWithCustomContains.kt") + public void testInRangeWithCustomContains() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt"); + doTest(fileName); + } + + @TestMetadata("inRangeWithImplicitReceiver.kt") + public void testInRangeWithImplicitReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithImplicitReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("inRangeWithNonmatchingArguments.kt") + public void testInRangeWithNonmatchingArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithNonmatchingArguments.kt"); + doTest(fileName); + } + + @TestMetadata("rangeContainsString.kt") + public void testRangeContainsString() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)