import "copyrightAndOthers.stg"
import "primitiveEquals.stg"
import "primitiveHashCode.stg"
import "primitiveLiteral.stg"

isTest() ::= "true"

hasTwoPrimitives() ::= "true"

skipBoolean() ::= "true"

targetPath() ::= "org/eclipse/collections/impl/map/mutable/primitive"

fileName(primitive1, primitive2, sameTwoPrimitives) ::= "Unmodifiable<primitive1.name><primitive2.name>MapTest"

class(primitive1, primitive2, sameTwoPrimitives) ::= <<
<body(primitive1.type, primitive2.type, primitive1.name, primitive2.name)>
>>

body(type1, type2, name1, name2) ::= <<
<copyrightAndOthers()>

package org.eclipse.collections.impl.map.mutable.primitive;

import org.eclipse.collections.api.block.function.primitive.<name2>Function;
import org.eclipse.collections.api.block.function.primitive.<name2>Function0;
import org.eclipse.collections.api.block.function.primitive.<name2>To<name2>Function;
<if(!sameTwoPrimitives)>import org.eclipse.collections.api.block.function.primitive.<name1>To<name2>Function;<endif>
import org.eclipse.collections.api.iterator.Mutable<name2>Iterator;
import org.eclipse.collections.impl.list.mutable.primitive.<name1>ArrayList;
import org.eclipse.collections.api.map.primitive.Mutable<name1><name2>Map;
import org.eclipse.collections.api.set.primitive.<name1>Set;
import org.eclipse.collections.impl.factory.Iterables;
import org.eclipse.collections.impl.set.mutable.primitive.<name1>HashSet;
import org.eclipse.collections.impl.test.Verify;
import org.eclipse.collections.impl.tuple.primitive.PrimitiveTuples;
import org.junit.Assert;
import org.junit.Test;

/**
 * JUnit test for {@link Unmodifiable<name1><name2>Map}.
 * This file was automatically generated from template file unmodifiablePrimitivePrimitiveMapTest.stg.
 */
public class Unmodifiable<name1><name2>MapTest extends AbstractMutable<name1><name2>MapTestCase
{
    private final Unmodifiable<name1><name2>Map map = this.classUnderTest();

    @Override
    protected Unmodifiable<name1><name2>Map classUnderTest()
    {
        return new Unmodifiable<name1><name2>Map(<name1><name2>HashMap.newWithKeysValues(<["0", "31", "32"]:keyValue(); separator=", ">));
    }

    @Override
    protected Unmodifiable<name1><name2>Map newWithKeysValues(<type1> key1, <type2> value1)
    {
        return new Unmodifiable<name1><name2>Map(new <name1><name2>HashMap(1).withKeyValue(key1, value1));
    }

    @Override
    protected Unmodifiable<name1><name2>Map newWithKeysValues(<type1> key1, <type2> value1, <type1> key2, <type2> value2)
    {
        return new Unmodifiable<name1><name2>Map(new <name1><name2>HashMap(2).withKeysValues(key1, value1, key2, value2));
    }

    @Override
    protected Unmodifiable<name1><name2>Map newWithKeysValues(<type1> key1, <type2> value1, <type1> key2, <type2> value2, <type1> key3, <type2> value3)
    {
        return new Unmodifiable<name1><name2>Map(new <name1><name2>HashMap(3).withKeysValues(key1, value1, key2, value2, key3, value3));
    }

    @Override
    protected Unmodifiable<name1><name2>Map newWithKeysValues(<type1> key1, <type2> value1, <type1> key2, <type2> value2, <type1> key3, <type2> value3, <type1> key4, <type2> value4)
    {
        return new Unmodifiable<name1><name2>Map(new <name1><name2>HashMap(4).withKeysValues(key1, value1, key2, value2, key3, value3, key4, value4));
    }

    @Override
    protected Unmodifiable<name1><name2>Map getEmptyMap()
    {
        return new Unmodifiable<name1><name2>Map(new <name1><name2>HashMap());
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void clear()
    {
        this.map.clear();
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void removeKey()
    {
        this.map.removeKey(<(literal.(type1))("5")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void remove()
    {
        this.map.remove(<(literal.(type1))("5")>);
    }

    @Override
    @Test
    public void removeKeyIfAbsent()
    {
        Assert.assertEquals(<(literal.(type2))("100")>, this.map.removeKeyIfAbsent(<(literal.(type1))("10")>, <(literal.(type2))("100")>)<(wideDelta.(type2))>);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void removeKeyIfAbsentThrowsException()
    {
        Assert.assertEquals(<(literal.(type2))("100")>, this.map.removeKeyIfAbsent(<(literal.(type1))("10")>, <(literal.(type2))("100")>)<(wideDelta.(type2))>);
        this.map.removeKeyIfAbsent(<(literal.(type1))("0")>, <(literal.(type2))("100")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void put()
    {
        this.map.put(<(literal.(type1))("0")>, <(literal.(type2))("1")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void getAndPut()
    {
        this.map.getAndPut(<(literal.(type1))("0")>, <(literal.(type2))("1")>, <(literal.(type2))("2")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void putPair()
    {
        this.map.putPair(PrimitiveTuples.pair(<(literal.(type1))("0")>, <(literal.(type2))("1")>));
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void updateValues()
    {
        this.map.updateValues((k, v) -> v);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void addToValue()
    {
        this.map.addToValue(<(literal.(type1))("0")>, <(literal.(type2))("1")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void withKeysValues()
    {
        this.map.withKeyValue(<(literal.(type1))("1")>, <(literal.(type2))("1")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void withoutKey()
    {
        this.map.withoutKey(<(literal.(type1))("32")>);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void withoutAllKeys()
    {
        this.map.withoutAllKeys(<name1>ArrayList.newListWith(<(literal.(type1))("0")>, <(literal.(type1))("32")>));
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void withAllKeyValues()
    {
        this.map.withAllKeyValues(Iterables.iList(PrimitiveTuples.pair(<(literal.(type1))("1")>, <(literal.(type2))("1")>)));
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void putDuplicateWithRemovedSlot()
    {
        <type1> collision1 = AbstractMutable<name1><name2>MapTestCase.generateCollisions().getFirst();

        Unmodifiable<name1><name2>Map hashMap = this.getEmptyMap();
        hashMap.put(collision1, <(literal.(type2))("1")>);
    }

    @Override
    @Test
    public void get()
    {
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.get(<(literal.(type1))("0")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("31")>, this.map.get(<(literal.(type1))("31")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("32")>, this.map.get(<(literal.(type1))("32")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.get(<(literal.(type1))("1")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.get(<(literal.(type1))("33")>)<(wideDelta.(type2))>);
    }

    @Override
    @Test
    public void getIfAbsent()
    {
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getIfAbsent(<(literal.(type1))("0")>, <(literal.(type2))("5")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("31")>, this.map.getIfAbsent(<(literal.(type1))("31")>, <(literal.(type2))("5")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("32")>, this.map.getIfAbsent(<(literal.(type1))("32")>, <(literal.(type2))("5")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("6")>, this.map.getIfAbsent(<(literal.(type1))("33")>, <(literal.(type2))("6")>)<(wideDelta.(type2))>);
    }

    @Override
    @Test
    public void getOrThrow()
    {
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getOrThrow(<(literal.(type1))("0")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("31")>, this.map.getOrThrow(<(literal.(type1))("31")>)<(wideDelta.(type2))>);
        Assert.assertEquals(<(wideLiteral.(type2))("32")>, this.map.getOrThrow(<(literal.(type1))("32")>)<(wideDelta.(type2))>);

        Assert.assertThrows(IllegalStateException.class, () -> this.map.getOrThrow(<(literal.(type1))("1")>));
        Assert.assertThrows(IllegalStateException.class, () -> this.map.getOrThrow(<(literal.(type1))("33")>));
    }

    @Override
    @Test
    public void getIfAbsentPut()
    {
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getIfAbsentPut(<(literal.(type1))("0")>, <(literal.(type2))("50")>)<(wideDelta.(type2))>);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void getIfAbsentPutThrowsException()
    {
        this.map.getIfAbsentPut(<(literal.(type1))("10")>, <(literal.(type2))("100")>);
    }

    @Override
    @Test
    public void getIfAbsentPut_Function()
    {
        <name2>Function0 factory = () -> <(literal.(type2))("100")>;

        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getIfAbsentPut(<(literal.(type1))("0")>, factory)<(wideDelta.(type2))>);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void getIfAbsentPut_FunctionThrowsException()
    {
        <name2>Function0 factory = () -> <(literal.(type2))("100")>;

        this.map.getIfAbsentPut(<(literal.(type1))("10")>, factory);
    }

    @Override
    @Test
    public void getIfAbsentPutWith()
    {
        <name2>Function\<String> functionLength = (String string) -> <(castFromInt.(type2))("string.length()")>;

        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getIfAbsentPutWith(<(literal.(type1))("0")>, functionLength, "123456789")<(wideDelta.(type2))>);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void getIfAbsentPutWithThrowsException()
    {
        <name2>Function\<String> functionLength = (String string) -> <(castFromInt.(type2))("string.length()")>;

        this.map.getIfAbsentPutWith(<(literal.(type1))("10")>, functionLength, "unused");
    }

    @Override
    @Test
    public void getIfAbsentPutWithKey()
    {
        <name1>To<name2>Function function = (<type1> <type1>Parameter) -> <castExactly(type2, {<type1>Parameter}, sameTwoPrimitives)>;
        Assert.assertEquals(<(wideLiteral.(type2))("0")>, this.map.getIfAbsentPutWithKey(<(literal.(type1))("0")>, function)<(wideDelta.(type2))>);
    }

    @Override
    @Test
    public void freeze()
    {
        Mutable<name1><name2>Map mutable<name1><name2>Map = this.classUnderTest();
        <name1>Set frozenSet = mutable<name1><name2>Map.keySet().freeze();
        <name1>Set frozenSetCopy = <name1>HashSet.newSetWith(mutable<name1><name2>Map.keySet().toArray());
        Assert.assertEquals(frozenSet, frozenSetCopy);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void getIfAbsentPutWithKeyThrowsException()
    {
        <name1>To<name2>Function function = (<type1> <type1>Parameter) -> <castExactly(type2, {<type1>Parameter}, sameTwoPrimitives)>;
        this.map.getIfAbsentPutWithKey(<(literal.(type1))("10")>, function);
    }

    @Test(expected = UnsupportedOperationException.class)
    public void putAllThrowsException()
    {
        Unmodifiable<name1><name2>Map copyMap = new Unmodifiable<name1><name2>Map(<name1><name2>HashMap.newWithKeysValues(<["0", "31", "32"]:keyValue(); separator=", ">));
        this.map.putAll(copyMap);
    }

    @Override
    @Test(expected = UnsupportedOperationException.class)
    public void updateValue()
    {
        <name2>To<name2>Function incrementFunction = (<type2> value) -> <(castIntToNarrowTypeWithParens.(type2))({value + <(literal.(type2))("1")>})>;
        this.map.updateValue(<keyValue("0")>, incrementFunction);
    }

    @Override
    @Test
    public void contains()
    {
        Assert.assertTrue(this.map.contains(<(literal.(type2))("0")>));
        Assert.assertTrue(this.map.contains(<(literal.(type2))("31")>));
        Assert.assertTrue(this.map.contains(<(literal.(type2))("32")>));
    }

    @Override
    @Test
    public void containsKey()
    {
        Assert.assertTrue(this.map.containsKey(<(literal.(type1))("0")>));
        Assert.assertTrue(this.map.containsKey(<(literal.(type1))("31")>));
        Assert.assertTrue(this.map.containsKey(<(literal.(type1))("32")>));
        Assert.assertFalse(this.map.containsKey(<(literal.(type1))("1")>));
        Assert.assertFalse(this.map.containsKey(<(literal.(type1))("5")>));
        Assert.assertFalse(this.map.containsKey(<(literal.(type1))("35")>));
    }

    @Override
    @Test
    public void containsValue()
    {
        Assert.assertTrue(this.map.containsValue(<(literal.(type2))("0")>));
        Assert.assertTrue(this.map.containsValue(<(literal.(type2))("31")>));
        Assert.assertTrue(this.map.containsValue(<(literal.(type2))("32")>));
    }

    @Override
    @Test
    public void size()
    {
        Assert.assertEquals(0, this.getEmptyMap().size());
        Assert.assertEquals(1, this.newWithKeysValues(<keyValue("0")>).size());
        Assert.assertEquals(1, this.newWithKeysValues(<(literal.(type1))("1")>, <(literal.(type2))("1")>).size());

        Assert.assertEquals(2, this.newWithKeysValues(<(literal.(type1))("1")>, <(literal.(type2))("1")>, <(literal.(type1))("5")>, <(literal.(type2))("5")>).size());
        Assert.assertEquals(2, this.newWithKeysValues(<keyValue("0")>, <(literal.(type1))("5")>, <(literal.(type2))("5")>).size());
        Assert.assertEquals(3, this.newWithKeysValues(<(literal.(type1))("1")>, <(literal.(type2))("1")>, <keyValue("0")>, <(literal.(type1))("5")>, <(literal.(type2))("5")>).size());
        Assert.assertEquals(2, this.newWithKeysValues(<(literal.(type1))("6")>, <(literal.(type2))("6")>, <(literal.(type1))("5")>, <(literal.(type2))("5")>).size());
        Verify.assertSize(3, this.map);
    }

    @Override
    @Test
    public void asUnmodifiable()
    {
        super.asUnmodifiable();
        Assert.assertSame(this.map, this.map.asUnmodifiable());
    }

    @Override
    @Test
    public void <type2>Iterator_with_remove()
    {
        Mutable<name2>Iterator iterator = this.map.<type2>Iterator();
        Assert.assertTrue(iterator.hasNext());
        iterator.next();
        Assert.assertThrows(UnsupportedOperationException.class, iterator::remove);
    }

    @Override
    @Test
    public void iterator_throws_on_invocation_of_remove_before_next()
    {
        Mutable<name2>Iterator iterator = this.map.<type2>Iterator();
        Assert.assertTrue(iterator.hasNext());
        Assert.assertThrows(UnsupportedOperationException.class, iterator::remove);
    }

    @Override
    @Test
    public void iterator_throws_on_consecutive_invocation_of_remove()
    {
        // Not applicable for Unmodifiable*
    }

    @Override
    @Test
    public void flipUniqueValues()
    {
        super.flipUniqueValues();

        Verify.assertInstanceOf(Unmodifiable<name2><name1>Map.class, this.classUnderTest().flipUniqueValues());
    }
}

>>

keyValue(value) ::= <<
<(literal.(type1))(value)>, <(literal.(type2))(value)>
>>
