org.mule.util.CopyOnWriteCaseInsensitiveMapTestCase.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.util.CopyOnWriteCaseInsensitiveMapTestCase.java

Source

/*
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package org.mule.util;

import static junit.framework.Assert.fail;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.mule.tck.junit4.AbstractMuleTestCase;
import org.mule.tck.size.SmallTest;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.apache.commons.lang.SerializationUtils;
import org.junit.Test;

@SuppressWarnings("unchecked")
@SmallTest
public class CopyOnWriteCaseInsensitiveMapTestCase extends AbstractMuleTestCase {

    private static final String KEY1 = "FOO";
    private static final String KEY2 = "doo";

    @Test
    public void caseInsensitive() throws Exception {
        assertMapContents(createTestMap());
    }

    @Test
    public void keysCaseSensitive() throws Exception {
        Map<String, Object> map = createTestMap();

        assertEquals(2, map.keySet().size());
        assertTrue(map.keySet().toArray()[0].equals("FOO") || map.keySet().toArray()[0].equals("doo"));
        assertTrue(map.keySet().toArray()[1].equals("FOO") || map.keySet().toArray()[1].equals("doo"));
    }

    @Test
    public void caseInsensitiveDelegate() throws Exception {
        assertMapContents(createTestMap().clone());
    }

    @Test
    public void caseInsensitiveCopiedDelegate() throws Exception {
        Map<String, Object> map = createTestMap().clone();
        map.put("new", "val");
        assertMapContents(map);
    }

    @Test
    public void serialize() throws Exception {
        assertMapContents(serializeAndDeserialize(createTestMap()));
    }

    @Test
    public void serializeDelegate() throws Exception {
        assertMapContents(serializeAndDeserialize(createTestMap().clone()));
    }

    @Test
    public void serializeCopiedDelegate() throws Exception {
        Map<String, Object> map = createTestMap().clone();
        map.put("new", "val");
        assertMapContents(serializeAndDeserialize(map));
    }

    protected Map<String, Object> serializeAndDeserialize(Map<String, Object> map) {
        byte[] bytes = SerializationUtils.serialize((Serializable) map);
        return (Map) SerializationUtils.deserialize(bytes);
    }

    /*
     * Assert that Map created with createTestMap() has both of the original properties (FOO and DOO) and that
     * these can be accessed using case-insensitive keys
     */
    protected void assertMapContents(Map<String, Object> map) {
        assertEquals("BAR", map.get("FOO"));
        assertEquals("BAR", map.get("foo"));
        assertEquals("BAR", map.get("Foo"));

        assertEquals(Integer.valueOf(3), map.get("DOO"));
        assertEquals(Integer.valueOf(3), map.get("doo"));
        assertEquals(Integer.valueOf(3), map.get("Doo"));
    }

    /*
     * Create a CopyOnWriteCaseInsensitiveMap with two properties: F00=BAR (String) and DOO=3 (int).
     */
    protected CopyOnWriteCaseInsensitiveMap<String, Object> createTestMap() {
        CopyOnWriteCaseInsensitiveMap<String, Object> map = new CopyOnWriteCaseInsensitiveMap<String, Object>();
        map.put(KEY1, "BAR");
        map.put(KEY2, Integer.valueOf(3));
        return map;
    }

    @Test
    public void entrySet() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        assertEquals(2, original.size());
        original.keySet().remove("FOO");
        assertEquals(1, original.size());
        original.keySet().clear();
        assertEquals(0, original.size());
    }

    @Test
    public void entrySetCloneMutateOriginal() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        assertEquals(2, original.size());
        assertEquals(2, copyOnWriteMap.size());

        original.keySet().remove("FOO");
        assertEquals(1, original.size());
        assertEquals(2, copyOnWriteMap.size());

        original.keySet().clear();
        assertEquals(0, original.size());
        assertEquals(2, copyOnWriteMap.size());
    }

    @Test
    public void entrySetCloneMutateClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        assertEquals(2, original.size());
        assertEquals(2, copyOnWriteMap.size());

        copyOnWriteMap.keySet().remove("FOO");
        assertEquals(2, original.size());
        assertEquals(1, copyOnWriteMap.size());

        copyOnWriteMap.keySet().clear();
        assertEquals(2, original.size());
        assertEquals(0, copyOnWriteMap.size());
    }

    @Test
    public void putClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        original.put("newOriginal", "val");
        copyOnWriteMap.put("newCopy", "val");

        // Assert state of original map
        assertMapContents(original);
        assertEquals(3, original.size());
        assertFalse(original.containsKey("newCopy"));
        assertTrue(original.containsKey("newOriginal"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(3, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("newCopy"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal"));
    }

    @Test
    public void putAllClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        Map<String, String> newOriginalEntriesMap = new HashMap<String, String>();
        newOriginalEntriesMap.put("newOriginal1", "val");
        newOriginalEntriesMap.put("newOriginal2", "val");
        newOriginalEntriesMap.put("newOriginal3", "val");
        original.putAll(newOriginalEntriesMap);

        Map<String, String> newCopyEntriesMap = new HashMap<String, String>();
        newCopyEntriesMap.put("newCopy1", "val");
        newCopyEntriesMap.put("newCopy2", "val");
        newCopyEntriesMap.put("newCopy3", "val");
        copyOnWriteMap.putAll(newCopyEntriesMap);

        // Assert state of original map
        assertMapContents(original);
        assertEquals(5, original.size());
        assertTrue(original.containsKey("newOriginal1"));
        assertTrue(original.containsKey("newOriginal2"));
        assertTrue(original.containsKey("newOriginal3"));
        assertFalse(original.containsKey("newCopy1"));
        assertFalse(original.containsKey("newCopy2"));
        assertFalse(original.containsKey("newCopy3"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(5, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("newCopy1"));
        assertTrue(copyOnWriteMap.containsKey("newCopy2"));
        assertTrue(copyOnWriteMap.containsKey("newCopy3"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal1"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal2"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal3"));
    }

    @Test
    public void removeClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        original.put("extra", "value");
        original.put("extra2", "value");
        Map<String, Object> copyOnWriteMap = original.clone();

        original.remove("extra");
        copyOnWriteMap.remove("extra2");

        // Assert state of original map
        assertMapContents(original);
        assertEquals(3, original.size());
        assertFalse(original.containsKey("extra"));
        assertTrue(original.containsKey("extra2"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(3, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("extra"));
        assertFalse(copyOnWriteMap.containsKey("extra2"));
    }

    @Test
    public void clearOrignalClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        original.clear();
        assertEquals(0, original.size());
        assertEquals(0, original.entrySet().size());
        assertEquals(2, copyOnWriteMap.size());
        assertEquals(2, copyOnWriteMap.entrySet().size());
    }

    @Test
    public void clearCopyClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = original.clone();

        copyOnWriteMap.clear();
        assertEquals(2, original.size());
        assertEquals(2, original.entrySet().size());
        assertEquals(0, copyOnWriteMap.size());
        assertEquals(0, copyOnWriteMap.entrySet().size());
    }

    @Test
    public void entrySetDeserializedMutateOriginal() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        assertEquals(2, original.size());
        assertEquals(2, copyOnWriteMap.size());

        original.keySet().remove("FOO");
        assertEquals(1, original.size());
        assertEquals(2, copyOnWriteMap.size());

        original.keySet().clear();
        assertEquals(0, original.size());
        assertEquals(2, copyOnWriteMap.size());
    }

    @Test
    public void entrySetDeserializedMutateClone() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        assertEquals(2, original.size());
        assertEquals(2, copyOnWriteMap.size());

        copyOnWriteMap.keySet().remove("FOO");
        assertEquals(2, original.size());
        assertEquals(1, copyOnWriteMap.size());

        copyOnWriteMap.keySet().clear();
        assertEquals(2, original.size());
        assertEquals(0, copyOnWriteMap.size());
    }

    @Test
    public void putDeserialized() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        original.put("newOriginal", "val");
        copyOnWriteMap.put("newCopy", "val");

        // Assert state of original map
        assertMapContents(original);
        assertEquals(3, original.size());
        assertFalse(original.containsKey("newCopy"));
        assertTrue(original.containsKey("newOriginal"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(3, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("newCopy"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal"));
    }

    @Test
    public void putAllDeserialized() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        Map<String, String> newOriginalEntriesMap = new HashMap<String, String>();
        newOriginalEntriesMap.put("newOriginal1", "val");
        newOriginalEntriesMap.put("newOriginal2", "val");
        newOriginalEntriesMap.put("newOriginal3", "val");
        original.putAll(newOriginalEntriesMap);

        Map<String, String> newCopyEntriesMap = new HashMap<String, String>();
        newCopyEntriesMap.put("newCopy1", "val");
        newCopyEntriesMap.put("newCopy2", "val");
        newCopyEntriesMap.put("newCopy3", "val");
        copyOnWriteMap.putAll(newCopyEntriesMap);

        // Assert state of original map
        assertMapContents(original);
        assertEquals(5, original.size());
        assertTrue(original.containsKey("newOriginal1"));
        assertTrue(original.containsKey("newOriginal2"));
        assertTrue(original.containsKey("newOriginal3"));
        assertFalse(original.containsKey("newCopy1"));
        assertFalse(original.containsKey("newCopy2"));
        assertFalse(original.containsKey("newCopy3"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(5, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("newCopy1"));
        assertTrue(copyOnWriteMap.containsKey("newCopy2"));
        assertTrue(copyOnWriteMap.containsKey("newCopy3"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal1"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal2"));
        assertFalse(copyOnWriteMap.containsKey("newOriginal3"));
    }

    @Test
    public void removeDeserialized() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        original.put("extra", "value");
        original.put("extra2", "value");
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        original.remove("extra");
        copyOnWriteMap.remove("extra2");

        // Assert state of original map
        assertMapContents(original);
        assertEquals(3, original.size());
        assertFalse(original.containsKey("extra"));
        assertTrue(original.containsKey("extra2"));

        // Assert state of copy on write map
        assertMapContents(copyOnWriteMap);
        assertEquals(3, copyOnWriteMap.size());
        assertTrue(copyOnWriteMap.containsKey("extra"));
        assertFalse(copyOnWriteMap.containsKey("extra2"));
    }

    @Test
    public void clearOrignalDeserialized() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        original.clear();
        assertEquals(0, original.size());
        assertEquals(0, original.entrySet().size());
        assertEquals(2, copyOnWriteMap.size());
        assertEquals(2, copyOnWriteMap.entrySet().size());
    }

    @Test
    public void clearCopyDeserialized() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> original = createTestMap();
        Map<String, Object> copyOnWriteMap = serializeAndDeserialize(original);

        copyOnWriteMap.clear();
        assertEquals(2, original.size());
        assertEquals(2, original.entrySet().size());
        assertEquals(0, copyOnWriteMap.size());
        assertEquals(0, copyOnWriteMap.entrySet().size());
    }

    @Test
    public void keySetGivesAllKeys() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> map = createTestMap();
        Set<String> foundKeys = new HashSet<String>();
        for (String key : map.keySet()) {
            assertTrue(KEY1.equals(key) || KEY2.equals(key));
            assertFalse(foundKeys.contains(key));
            foundKeys.add(key);
        }
    }

    @Test
    public void removeKeySetItem() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> map = createTestMap();
        Iterator<String> it = map.keySet().iterator();

        assertTrue(it.hasNext());
        String key = it.next();
        it.remove();

        assertFalse(map.keySet().contains(key));
        it = map.keySet().iterator();
        assertTrue(it.hasNext());
        String key2 = it.next();
        assertFalse(key.equals(key2));
        assertFalse(it.hasNext());
        it.remove();
        assertFalse(it.hasNext());

        assertTrue(map.keySet().isEmpty());
        it = map.keySet().iterator();
        assertFalse(it.hasNext());

        try {
            it.next();
            fail("Was expecting NoSuchElementException");
        } catch (NoSuchElementException e) {
            // happyness
        }
    }

    @Test(expected = NoSuchElementException.class)
    public void emptyMapKeySetIterator() throws Exception {
        Map<String, String> map = new CopyOnWriteCaseInsensitiveMap<String, String>();
        assertTrue(map.keySet().isEmpty());
        Iterator<String> iterator = map.keySet().iterator();
        assertFalse(iterator.hasNext());
        iterator.next();
    }

    @Test(expected = IllegalStateException.class)
    public void removeInKeySetIteratorBeforeAnyNext() throws Exception {
        createTestMap().keySet().iterator().remove();
    }

    @Test(expected = IllegalStateException.class)
    public void keySetIteratorWithTwoRemovesInTheSameNext() throws Exception {
        Iterator<String> iterator = createTestMap().keySet().iterator();
        iterator.next();
        iterator.remove();
        iterator.remove();
    }

    @Test
    public void removeShouldNotMoveForward() throws Exception {
        CopyOnWriteCaseInsensitiveMap<String, Object> map = createTestMap();

        //add a third element to spice things up
        final String EXTRA_KEY = "THIRD";
        map.put(EXTRA_KEY, new Object());

        // store iteration order
        List<String> keys = new ArrayList<String>();
        for (String key : map.keySet()) {
            keys.add(key);
        }

        //now remove second element and make sure that the next element is the third
        Iterator<String> iterator = map.keySet().iterator();
        iterator.next();
        iterator.next();
        iterator.remove();
        String key = iterator.next();
        assertEquals(keys.get(2), key);
        assertFalse(iterator.hasNext());
    }

    @Test
    public void asHashMap() {
        CopyOnWriteCaseInsensitiveMap<String, Object> map = createTestMap();
        Map<String, Object> regularMap = map.asHashMap();
        assertThat(regularMap, is(instanceOf(HashMap.class)));
        assertThat(regularMap.size(), is(map.size()));
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            assertThat(map.get(entry.getKey()), is(regularMap.get(entry.getKey())));
        }
    }
}