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:
      * 
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
-     * 
+ * }
* * @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: *
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 }