/*
* Copyright 2014 Goldman Sachs.
*
* 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.gs.collections.impl.collection.mutable;
import java.util.Collection;
import java.util.Collections;
import com.gs.collections.api.RichIterable;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.function.Function2;
import com.gs.collections.api.block.function.Function3;
import com.gs.collections.api.collection.MutableCollection;
import com.gs.collections.api.collection.primitive.MutableBooleanCollection;
import com.gs.collections.api.collection.primitive.MutableByteCollection;
import com.gs.collections.api.collection.primitive.MutableCharCollection;
import com.gs.collections.api.collection.primitive.MutableDoubleCollection;
import com.gs.collections.api.collection.primitive.MutableFloatCollection;
import com.gs.collections.api.collection.primitive.MutableIntCollection;
import com.gs.collections.api.collection.primitive.MutableLongCollection;
import com.gs.collections.api.collection.primitive.MutableShortCollection;
import com.gs.collections.api.list.MutableList;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.api.multimap.Multimap;
import com.gs.collections.api.set.sorted.MutableSortedSet;
import com.gs.collections.api.tuple.Twin;
import com.gs.collections.impl.Counter;
import com.gs.collections.impl.block.factory.Functions;
import com.gs.collections.impl.block.factory.IntegerPredicates;
import com.gs.collections.impl.block.factory.Predicates;
import com.gs.collections.impl.block.factory.PrimitiveFunctions;
import com.gs.collections.impl.block.factory.Procedures;
import com.gs.collections.impl.block.factory.StringPredicates;
import com.gs.collections.impl.block.function.PassThruFunction0;
import com.gs.collections.impl.factory.Lists;
import com.gs.collections.impl.list.Interval;
import com.gs.collections.impl.list.mutable.FastList;
import com.gs.collections.impl.list.mutable.primitive.BooleanArrayList;
import com.gs.collections.impl.list.mutable.primitive.ByteArrayList;
import com.gs.collections.impl.list.mutable.primitive.CharArrayList;
import com.gs.collections.impl.list.mutable.primitive.DoubleArrayList;
import com.gs.collections.impl.list.mutable.primitive.FloatArrayList;
import com.gs.collections.impl.list.mutable.primitive.IntArrayList;
import com.gs.collections.impl.list.mutable.primitive.LongArrayList;
import com.gs.collections.impl.list.mutable.primitive.ShortArrayList;
import com.gs.collections.impl.map.mutable.UnifiedMap;
import com.gs.collections.impl.multimap.list.FastListMultimap;
import com.gs.collections.impl.set.sorted.mutable.TreeSortedSet;
import com.gs.collections.impl.test.Verify;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static com.gs.collections.impl.factory.Iterables.*;
/**
* JUnit test for {@link UnmodifiableMutableCollection}.
*/
public class UnmodifiableMutableCollectionTest
{
private static final String METALLICA = "Metallica";
private MutableCollection<String> mutableCollection;
private MutableCollection<String> unmodifiableCollection;
@Before
public void setUp()
{
this.mutableCollection = FastList.<String>newList().with(METALLICA, "Bon Jovi", "Europe", "Scorpions");
this.unmodifiableCollection = new UnmodifiableMutableCollection<>(this.mutableCollection);
}
@Test
public void delegatingMethods()
{
Assert.assertEquals(this.mutableCollection.notEmpty(), this.unmodifiableCollection.notEmpty());
Assert.assertEquals(this.mutableCollection.isEmpty(), this.unmodifiableCollection.isEmpty());
Assert.assertEquals(this.mutableCollection.size(), this.unmodifiableCollection.size());
Assert.assertEquals(this.mutableCollection.getFirst(), this.unmodifiableCollection.getFirst());
Assert.assertEquals(this.mutableCollection.getLast(), this.unmodifiableCollection.getLast());
Assert.assertEquals(this.mutableCollection.count(ignored6 -> true),
this.unmodifiableCollection.count(ignored5 -> true));
Verify.assertSize(4, this.unmodifiableCollection.select(ignored4 -> true));
Verify.assertSize(4, this.unmodifiableCollection.select(ignored3 -> true, FastList.<String>newList()));
Verify.assertSize(1, this.unmodifiableCollection.selectWith(Object::equals, METALLICA));
Verify.assertSize(
1,
this.unmodifiableCollection.selectWith(
Object::equals,
METALLICA,
FastList.<String>newList()));
Verify.assertSize(2, this.unmodifiableCollection.reject(StringPredicates.contains("p")));
Verify.assertSize(
2,
this.unmodifiableCollection.reject(StringPredicates.contains("p"), FastList.<String>newList()));
Verify.assertSize(3, this.unmodifiableCollection.rejectWith(Object::equals, METALLICA));
Verify.assertSize(
3,
this.unmodifiableCollection.rejectWith(
Object::equals,
METALLICA,
FastList.<String>newList()));
Verify.assertSize(4, this.unmodifiableCollection.collect(Functions.getStringPassThru()));
Verify.assertSize(
4,
this.unmodifiableCollection.collect(Functions.getStringPassThru(),
FastList.<String>newList()));
Function<String, Collection<String>> flattenFunction = object -> FastList.newListWith(object, object);
Verify.assertSize(8, this.unmodifiableCollection.flatCollect(flattenFunction));
Verify.assertSize(8, this.unmodifiableCollection.flatCollect(flattenFunction, FastList.<String>newList()));
Verify.assertSize(4, this.unmodifiableCollection.collectIf(ignored2 -> true, Functions.getStringPassThru()));
Verify.assertSize(
4,
this.unmodifiableCollection.collectIf(ignored1 -> true,
Functions.getStringPassThru(),
FastList.<String>newList()));
Assert.assertEquals(METALLICA, this.unmodifiableCollection.detect(StringPredicates.contains("allic")));
Assert.assertEquals("Not found", this.unmodifiableCollection.detectIfNone(StringPredicates.contains("donna"),
new PassThruFunction0<>("Not found")));
Assert.assertEquals(METALLICA, this.unmodifiableCollection.detectWith(Object::equals, METALLICA));
Assert.assertEquals("Not found", this.unmodifiableCollection.detectWithIfNone(Object::equals, "Madonna",
new PassThruFunction0<>("Not found")));
Assert.assertEquals(4, this.unmodifiableCollection.count(ignored -> true));
Assert.assertEquals(1, this.unmodifiableCollection.countWith(Object::equals, METALLICA));
Assert.assertTrue(this.unmodifiableCollection.anySatisfy(StringPredicates.contains("allic")));
Assert.assertTrue(this.unmodifiableCollection.anySatisfyWith(Object::equals, METALLICA));
Assert.assertTrue(this.unmodifiableCollection.allSatisfy(Predicates.notNull()));
Assert.assertTrue(this.unmodifiableCollection.allSatisfyWith((ignored1, ignored2) -> true, ""));
Assert.assertEquals(this.mutableCollection, this.unmodifiableCollection.toList());
Verify.assertListsEqual(Lists.mutable.of("Bon Jovi", "Europe", METALLICA, "Scorpions"),
this.unmodifiableCollection.toSortedList());
Verify.assertListsEqual(Lists.mutable.of("Scorpions", METALLICA, "Europe", "Bon Jovi"),
this.unmodifiableCollection.toSortedList(Collections.reverseOrder()));
Verify.assertSize(4, this.unmodifiableCollection.toSet());
Verify.assertSize(4, this.unmodifiableCollection.toMap(Functions.getStringPassThru(), Functions.getStringPassThru()));
}
@Test
public void delegatingCollectPrimitiveMethods()
{
MutableCollection<Integer> mutable = Interval.oneTo(4).toList();
MutableCollection<Integer> unmodifiable = new UnmodifiableMutableCollection<>(mutable);
MutableBooleanCollection expectedBooleans = mutable.collectBoolean(PrimitiveFunctions.integerIsPositive());
Assert.assertEquals(expectedBooleans, unmodifiable.collectBoolean(PrimitiveFunctions.integerIsPositive()));
Assert.assertEquals(BooleanArrayList.newListWith(true, true, true, true), expectedBooleans);
MutableByteCollection expectedBytes = mutable.collectByte(PrimitiveFunctions.unboxIntegerToByte());
Assert.assertEquals(expectedBytes, unmodifiable.collectByte(PrimitiveFunctions.unboxIntegerToByte()));
Assert.assertEquals(ByteArrayList.newListWith((byte) 1, (byte) 2, (byte) 3, (byte) 4), expectedBytes);
MutableCharCollection expectedChars = mutable.collectChar(PrimitiveFunctions.unboxIntegerToChar());
Assert.assertEquals(expectedChars, unmodifiable.collectChar(PrimitiveFunctions.unboxIntegerToChar()));
Assert.assertEquals(CharArrayList.newListWith((char) 1, (char) 2, (char) 3, (char) 4), expectedChars);
MutableDoubleCollection expectedDoubles = mutable.collectDouble(PrimitiveFunctions.unboxIntegerToDouble());
Assert.assertEquals(expectedDoubles, unmodifiable.collectDouble(PrimitiveFunctions.unboxIntegerToDouble()));
Assert.assertEquals(DoubleArrayList.newListWith(1.0d, 2.0d, 3.0d, 4.0d), expectedDoubles);
MutableFloatCollection expectedFloats = mutable.collectFloat(PrimitiveFunctions.unboxIntegerToFloat());
Assert.assertEquals(expectedFloats, unmodifiable.collectFloat(PrimitiveFunctions.unboxIntegerToFloat()));
Assert.assertEquals(FloatArrayList.newListWith(1.0f, 2.0f, 3.0f, 4.0f), expectedFloats);
MutableIntCollection expectedInts = mutable.collectInt(PrimitiveFunctions.unboxIntegerToInt());
Assert.assertEquals(expectedInts, unmodifiable.collectInt(PrimitiveFunctions.unboxIntegerToInt()));
Assert.assertEquals(IntArrayList.newListWith(1, 2, 3, 4), expectedInts);
MutableLongCollection expectedLongs = mutable.collectLong(PrimitiveFunctions.unboxIntegerToLong());
Assert.assertEquals(expectedLongs, unmodifiable.collectLong(PrimitiveFunctions.unboxIntegerToLong()));
Assert.assertEquals(LongArrayList.newListWith(1L, 2L, 3L, 4L), expectedLongs);
MutableShortCollection expectedShorts = mutable.collectShort(PrimitiveFunctions.unboxIntegerToShort());
Assert.assertEquals(expectedShorts, unmodifiable.collectShort(PrimitiveFunctions.unboxIntegerToShort()));
Assert.assertEquals(ShortArrayList.newListWith((short) 1, (short) 2, (short) 3, (short) 4), expectedShorts);
}
@Test
public void nullCollection()
{
Verify.assertThrows(NullPointerException.class, () -> new UnmodifiableMutableCollection<>(null));
}
@Test
public void add()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.add("Madonna"));
}
@Test
public void remove()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.remove(METALLICA));
}
@Test
public void addAll()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.addAll(FastList.<String>newList().with("Madonna")));
}
@Test
public void removeAll()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.removeAll(FastList.<String>newList().with(METALLICA)));
}
@Test
public void retainAll()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.retainAll(FastList.<String>newList().with(METALLICA)));
}
@Test
public void clear()
{
Verify.assertThrows(UnsupportedOperationException.class, this.unmodifiableCollection::clear);
}
@Test
public void transparencyOfMutableChanges()
{
this.mutableCollection.remove(METALLICA);
Verify.assertSize(this.mutableCollection.size(), this.unmodifiableCollection);
}
@Test
public void collectWith()
{
Function2<String, String, String> function = (band, parameter) -> parameter + band.charAt(0);
Assert.assertEquals(
FastList.newListWith(">M", ">B", ">E", ">S"),
this.unmodifiableCollection.collectWith(function, ">"));
Assert.assertEquals(FastList.newListWith("*M", "*B", "*E", "*S"), this.unmodifiableCollection.collectWith(function, "*", FastList.<String>newList()));
}
@Test
public void injectInto()
{
Function2<String, String, String> function = (injectValue, band) -> injectValue + band.charAt(0);
Assert.assertEquals(">MBES", this.unmodifiableCollection.injectInto(">", function));
}
@Test
public void injectIntoWith()
{
Function3<String, String, String, String> function =
(injectValue, band, parameter) -> injectValue + band.charAt(0) + parameter;
Assert.assertEquals(">M*B*E*S*", this.unmodifiableCollection.injectIntoWith(">", function, "*"));
}
@Test
public void removeIf()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.removeIf(Predicates.notNull()));
}
@Test
public void removeIfWith()
{
Verify.assertThrows(UnsupportedOperationException.class, () -> this.unmodifiableCollection.removeIfWith((ignored1, ignored2) -> true, METALLICA));
}
@Test(expected = UnsupportedOperationException.class)
public void with()
{
this.unmodifiableCollection.with(METALLICA);
}
@Test(expected = UnsupportedOperationException.class)
public void withAll()
{
this.unmodifiableCollection.withAll(this.mutableCollection);
}
@Test(expected = UnsupportedOperationException.class)
public void without()
{
this.unmodifiableCollection.without(METALLICA);
}
@Test(expected = UnsupportedOperationException.class)
public void withoutAll()
{
this.unmodifiableCollection.withoutAll(this.mutableCollection);
}
@Test
public void iterator()
{
Counter counter = new Counter();
for (Object each : this.unmodifiableCollection)
{
counter.increment();
}
Assert.assertEquals(4, counter.getCount());
}
@Test
public void forEach()
{
Counter counter = new Counter();
this.unmodifiableCollection.forEach(Procedures.cast(band -> counter.increment()));
Assert.assertEquals(4, counter.getCount());
}
@Test
public void forEachWith()
{
StringBuilder buf = new StringBuilder();
this.unmodifiableCollection.forEachWith((band, param) -> buf.append(param).append('<').append(band).append('>'), "GreatBand");
Assert.assertEquals("GreatBand<Metallica>GreatBand<Bon Jovi>GreatBand<Europe>GreatBand<Scorpions>", buf.toString());
}
@Test
public void forEachWithIndex()
{
Counter counter = new Counter();
this.unmodifiableCollection.forEachWithIndex((band, index) -> counter.add(index));
Assert.assertEquals(6, counter.getCount());
}
@Test
public void selectAndRejectWith()
{
Twin<MutableList<String>> twin =
this.unmodifiableCollection.selectAndRejectWith(Object::equals, METALLICA);
Verify.assertSize(1, twin.getOne());
Verify.assertSize(3, twin.getTwo());
}
@Test
public void groupBy()
{
RichIterable<Integer> list = this.newWith(1, 2, 3, 4, 5, 6, 7);
Function<Integer, Boolean> isOddFunction = object -> IntegerPredicates.isOdd().accept(object);
MutableMap<Boolean, RichIterable<Integer>> expected =
UnifiedMap.<Boolean, RichIterable<Integer>>newWithKeysValues(
Boolean.TRUE, FastList.newListWith(1, 3, 5, 7),
Boolean.FALSE, FastList.newListWith(2, 4, 6));
Multimap<Boolean, Integer> multimap = list.groupBy(isOddFunction);
Assert.assertEquals(expected, multimap.toMap());
Multimap<Boolean, Integer> multimap2 = list.groupBy(isOddFunction, FastListMultimap.<Boolean, Integer>newMultimap());
Assert.assertEquals(expected, multimap2.toMap());
}
private <T> UnmodifiableMutableCollection<T> newWith(T... elements)
{
return new UnmodifiableMutableCollection<>(FastList.newListWith(elements));
}
@Test
public void toSortedSet()
{
this.unmodifiableCollection = this.newWith("2", "4", "1", "3");
MutableSortedSet<String> set = this.unmodifiableCollection.toSortedSet();
Verify.assertSortedSetsEqual(TreeSortedSet.newSetWith("1", "2", "3", "4"), set);
}
@Test
public void toSortedSet_with_comparator()
{
this.unmodifiableCollection = this.newWith("2", "4", "4", "2", "1", "4", "1", "3");
MutableSortedSet<String> set = this.unmodifiableCollection.toSortedSet(Collections.<String>reverseOrder());
Verify.assertSortedSetsEqual(TreeSortedSet.newSetWith(Collections.<String>reverseOrder(), "1", "2", "3", "4"), set);
}
@Test
public void toSortedSetBy()
{
this.unmodifiableCollection = this.newWith("2", "4", "1", "3");
MutableSortedSet<String> set = this.unmodifiableCollection.toSortedSetBy(Functions.getStringToInteger());
Verify.assertSortedSetsEqual(TreeSortedSet.newSetWith("1", "2", "3", "4"), set);
}
@Test
public void selectInstancesOf()
{
MutableCollection<Number> numbers = UnmodifiableMutableCollection.of(FastList.<Number>newListWith(1, 2.0, 3, 4.0, 5));
Assert.assertEquals(iList(1, 3, 5), numbers.selectInstancesOf(Integer.class));
Assert.assertEquals(iList(1, 2.0, 3, 4.0, 5), numbers.selectInstancesOf(Number.class));
}
}