From 5b793a70bad26fcfbc21ad2e22886fa622f173b6 Mon Sep 17 00:00:00 2001 From: Divyansh <2023csb1119@iitrpr.ac.in> Date: Sun, 30 Aug 2026 13:00:02 +0530 Subject: [PATCH 1/2] Use `SUPPORTS_REMOVE` for `CollectionRemoveIfTester` feature requirements. Fixes https://github.com/google/guava/issues/6076 RELNOTES=`testing`: Fixed `CollectionRemoveIfTester` so that `removeIf` tests run for collections with `SUPPORTS_REMOVE` even when `SUPPORTS_ITERATOR_REMOVE` is absent. Co-authored-by: Cursor --- .../testers/CollectionRemoveIfTester.java | 9 +- .../CollectionRemoveIfFeatureTest.java | 127 ++++++++++++++++++ 2 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 guava-testlib/test/com/google/common/collect/testing/CollectionRemoveIfFeatureTest.java diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveIfTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveIfTester.java index 83d562227767..f280c1f29305 100644 --- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveIfTester.java +++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveIfTester.java @@ -17,7 +17,6 @@ package com.google.common.collect.testing.testers; import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION; -import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ITERATOR_REMOVE; import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; import static com.google.common.collect.testing.features.CollectionSize.ZERO; @@ -40,13 +39,13 @@ */ @GwtCompatible public class CollectionRemoveIfTester extends AbstractCollectionTester { - @CollectionFeature.Require(SUPPORTS_ITERATOR_REMOVE) + @CollectionFeature.Require(SUPPORTS_REMOVE) public void testRemoveIf_alwaysFalse() { assertFalse("removeIf(x -> false) should return false", collection.removeIf(x -> false)); expectUnchanged(); } - @CollectionFeature.Require(SUPPORTS_ITERATOR_REMOVE) + @CollectionFeature.Require(SUPPORTS_REMOVE) @CollectionSize.Require(absent = ZERO) public void testRemoveIf_sometimesTrue() { assertTrue( @@ -55,14 +54,14 @@ public void testRemoveIf_sometimesTrue() { expectMissing(samples.e0()); } - @CollectionFeature.Require(SUPPORTS_ITERATOR_REMOVE) + @CollectionFeature.Require(SUPPORTS_REMOVE) @CollectionSize.Require(absent = ZERO) public void testRemoveIf_allPresent() { assertTrue("removeIf(x -> true) should return true", collection.removeIf(x -> true)); expectContents(); } - @CollectionFeature.Require({SUPPORTS_ITERATOR_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) + @CollectionFeature.Require({SUPPORTS_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) @CollectionSize.Require(SEVERAL) public void testRemoveIfSomeMatchesConcurrentWithIteration() { Iterator iterator = collection.iterator(); diff --git a/guava-testlib/test/com/google/common/collect/testing/CollectionRemoveIfFeatureTest.java b/guava-testlib/test/com/google/common/collect/testing/CollectionRemoveIfFeatureTest.java new file mode 100644 index 000000000000..a198ed98c4b4 --- /dev/null +++ b/guava-testlib/test/com/google/common/collect/testing/CollectionRemoveIfFeatureTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2026 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect.testing; + +import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER; +import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; +import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; + +import com.google.common.collect.Lists; +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Regression test for {@link testers.CollectionRemoveIfTester} feature requirements. + */ +@AndroidIncompatible // test-suite builders +public class CollectionRemoveIfFeatureTest extends TestCase { + + /** + * A collection that supports {@link Collection#removeIf} and {@link Collection#remove} but whose + * iterator does not support {@link Iterator#remove()}. + */ + private static final class RemoveIfOnlyList extends AbstractList { + private final List elements = Lists.newArrayList("a", "b", "c"); + + void resetTo(String[] newElements) { + elements.clear(); + elements.addAll(Lists.newArrayList(newElements)); + } + + @Override + public String get(int index) { + return elements.get(index); + } + + @Override + public int size() { + return elements.size(); + } + + @Override + public boolean remove(Object o) { + return elements.remove(o); + } + + @Override + public boolean removeIf(Predicate filter) { + return elements.removeIf(filter); + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int index; + + @Override + public boolean hasNext() { + return index < size(); + } + + @Override + public String next() { + return get(index++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + } + + public void testRemoveIfTestsRunWhenOnlySupportsRemove() { + TestSuite suite = + CollectionTestSuiteBuilder.using( + new TestStringCollectionGenerator() { + @Override + protected Collection create(String[] elements) { + RemoveIfOnlyList list = new RemoveIfOnlyList(); + list.resetTo(elements); + return list; + } + }) + .named("RemoveIfOnlyList") + .withFeatures(SUPPORTS_REMOVE, KNOWN_ORDER, SEVERAL) + .createTestSuite(); + + int removeIfTestCount = countTestsWithNameContaining(suite, "testRemoveIf"); + assertTrue( + "removeIf tests should run for collections with SUPPORTS_REMOVE, even without" + + " SUPPORTS_ITERATOR_REMOVE", + removeIfTestCount > 0); + } + + private static int countTestsWithNameContaining(Test test, String substring) { + if (test instanceof TestSuite) { + TestSuite testSuite = (TestSuite) test; + int count = 0; + for (int i = 0; i < testSuite.testCount(); i++) { + count += countTestsWithNameContaining(testSuite.testAt(i), substring); + } + return count; + } + return test.toString().contains(substring) ? 1 : 0; + } +} From 2ec0b919181f8ead253cd56768f5ac7b03d08a70 Mon Sep 17 00:00:00 2001 From: Divyansh <2023csb1119@iitrpr.ac.in> Date: Sun, 30 Aug 2026 13:32:17 +0530 Subject: [PATCH 2/2] Trigger CLA re-check. Co-authored-by: Cursor