diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java index 8605cff657f..1df8e3116b7 100644 --- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java +++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java @@ -1110,7 +1110,7 @@ public static boolean isCase(Object caseValue, Object switchValue) { } /** - * Special 'Case' implementation for Class, which allows testing + * Special 'case' implementation for Class, which allows testing * whether some switch value is assignable from the given case class. * * If the switch value is an object, {@code isCase} will return true if the @@ -1163,9 +1163,8 @@ public static boolean isCase(Class caseValue, Object switchValue) { } /** - * 'Case' implementation for collections which tests if the 'switch' - * operand is contained in any of the 'case' values. - * For example: + * Special 'case' implementation for collections which tests if the 'switch' + * operand is contained in any of the 'case' values. For example: *
switch( 3 ) { * case [1,3,5]: * assert true @@ -1185,9 +1184,8 @@ public static boolean isCase(Collection caseValue, Object switchValue) { } /** - * 'Case' implementation for iterable types which tests if the 'switch' - * operand is contained in any of the 'case' values. - * For example: + * Special 'case' implementation for iterables which tests if the 'switch' + * operand is contained in any of the 'case' values. For example: ** * @param caseValue the case value * @param switchValue the switch value @@ -1213,11 +1206,10 @@ public static boolean isCase(Iterable caseValue, Object switchValue) { } /** - * 'Case' implementation for maps which tests the groovy truth - * value obtained using the 'switch' operand as key. - * For example: + * Special 'case' implementation for maps which tests if the 'switch' operand + * exists in the key set. For example: *Iterable it = {[1,3,5].iterator()} * switch( 3 ) { * case it: @@ -1195,12 +1193,7 @@ public static boolean isCase(Collection caseValue, Object switchValue) { * break * default: * assert false - * } - * - * //GROOVY-7919 - * assert 1 in it - * assert 2 !in it - *+ * }
switch( 'foo' ) { - * case [foo:true, bar:false]: + * case [foo:true]: * assert true * break * default: @@ -1226,11 +1218,11 @@ public static boolean isCase(Iterable caseValue, Object switchValue) { * * @param caseValue the case value * @param switchValue the switch value - * @return the groovy truth value from caseValue corresponding to the switchValue key + * @return true if the key set of caseValue contains the switchValue * @since 1.7.6 */ - public static boolean isCase(Map caseValue, Object switchValue) { - return DefaultTypeTransformation.castToBoolean(caseValue.get(switchValue)); + public static boolean isCase(Map,?> caseValue, Object switchValue) { + return caseValue.containsKey(switchValue); } /** diff --git a/src/spec/test/OperatorsTest.groovy b/src/spec/test/OperatorsTest.groovy index a37b369fd97..3574cf176a5 100644 --- a/src/spec/test/OperatorsTest.groovy +++ b/src/spec/test/OperatorsTest.groovy @@ -230,9 +230,6 @@ class OperatorsTest extends CompilableTestSupport { // end::nullsafe[] } - OperatorsTest() { - } - void testDirectFieldAccess() { assertScript ''' // tag::direct_field_class[] @@ -704,6 +701,7 @@ assert (b1 + b2).size == 15 // <1> // end::operator_overload_op[] ''' } + void testOperatorOverloadingWithDifferentArgumentType() { assertScript ''' class Bucket { diff --git a/src/test/groovy/GroovyMethodsTest.groovy b/src/test/groovy/GroovyMethodsTest.groovy index 0592e73e949..d87ace3d4ea 100644 --- a/src/test/groovy/GroovyMethodsTest.groovy +++ b/src/test/groovy/GroovyMethodsTest.groovy @@ -19,11 +19,11 @@ package groovy import groovy.test.GroovyTestCase +import org.codehaus.groovy.util.StringUtil import java.awt.Dimension import java.nio.CharBuffer import java.util.concurrent.LinkedBlockingQueue -import org.codehaus.groovy.util.StringUtil /** * Tests various GDK methods @@ -445,12 +445,6 @@ class GroovyMethodsTest extends GroovyTestCase { assert map.size() == 2 } - void testInForLists() { - def list = ['a', 'b', 'c'] - assert 'b' in list - assert !('d' in list) - } - void testFirstLastHeadTailInitForLists() { def list = ['a', 'b', 'c'] assert 'a' == list.first() @@ -548,10 +542,71 @@ class GroovyMethodsTest extends GroovyTestCase { assert list.size() == 3 } + // GROOVY-9848 + void testInForMaps() { + assert 'foo' in [foo:true] + assert 'foo' in [foo:null] + assert 'bar' !in [foo:true] + assert 'bar' !in [:].withDefault{ true } + } + + void testInForSets() { + def set = ['a', 'b', 'c'] as Set + assert 'a' in set + assert 'b' in set + assert 'c' in set + assert 'd' !in set + assert !('d' in set) + assert !(null in set) + assert !(true in set) + } + + void testInForLists() { + def list = ['a', 'b', 'c'] + assert 'a' in list + assert 'b' in list + assert 'c' in list + assert 'd' !in list + assert !('d' in list) + assert !(null in list) + assert !(true in list) + } + void testInForArrays() { - String[] array = ['a', 'b', 'c'] + def array = new String[]{'a', 'b', 'c'} + assert 'a' in array assert 'b' in array + assert 'c' in array + assert 'd' !in array assert !('d' in array) + assert !(null in array) + assert !(true in array) + } + + // GROOVY-2456 + void testInForStrings() { + def string = 'abc' + shouldFail { assert 'a' in string } + shouldFail { assert 'b' in string } + shouldFail { assert 'c' in string } + shouldFail { assert 'ab' in string } + shouldFail { assert 'bc' in string } + assert 'abc' in string + assert !('d' in string) + assert !(null in string) + assert !(true in string) + } + + // GROOVY-7919 + void testInForIterables() { + Iterable iter = { -> ['a','b','c'].iterator() } + assert 'a' in iter + assert 'b' in iter + assert 'c' in iter + assert 'd' !in iter + assert !('d' in iter) + assert !(null in iter) + assert !(true in iter) } void testMaxForIterable() { diff --git a/src/test/groovy/MapTest.groovy b/src/test/groovy/MapTest.groovy index 98107302737..5b5a3296fc3 100644 --- a/src/test/groovy/MapTest.groovy +++ b/src/test/groovy/MapTest.groovy @@ -329,33 +329,39 @@ final class MapTest extends GroovyTestCase { assert result2 == 'c2 b3 a1 ' } - void testMapWithDefault() { - def m = [:].withDefault {k -> k * 2} - m[1] = 3 - assert m[1] == 3 - assert m[2] == 4 - assert [1: 3, 2: 4] == m - assert m == [1: 3, 2: 4] - } - void testMapIsCaseWithGrep() { - def predicate = [apple:true, banana:true, lemon:false, orange:false, pear:true] def fruitList = ['apple', 'apple', 'pear', 'orange', 'pear', 'lemon', 'banana'] - def expected = ['apple', 'apple', 'pear', 'pear', 'banana'] - assert fruitList.grep(predicate) == expected + def predicate = [apple:true, banana:true, lemon:false, orange:false, pear:true] + predicate.retainAll{ e -> e.value } // GROOVY-9848: retain truthy entrys + + def nonCitrus = fruitList.grep(predicate) + assert nonCitrus == ['apple', 'apple', 'pear', 'pear', 'banana'] } void testMapIsCaseWithSwitch() { - switch ('foo') { - case [foo: true, bar: false]: assert true; break - default: assert false + assert switch ('foo') { + case [foo: true, bar: false] -> true + default -> false + } + assert switch ('foo') { + case [foo: false, bar: true] -> true + default -> false } - switch ('bar') { - case [foo: true, bar: false]: assert false; break - default: assert true + assert switch ('bar') { + case [foo: true] -> false + default -> true } } + void testMapWithDefault() { + def m = [:].withDefault { k -> k * 2 } + m[1] = 3 + assert m[1] == 3 + assert m[2] == 4 + assert [1: 3, 2: 4] == m + assert m == [1: 3, 2: 4] + } + void testMapWithDefaultCanBeConfiguredToNotStoreDefaultValue() { def defaultValue = 0 def m = [:].withDefault(false, true) { defaultValue }