package com.cedarsoftware.util;
import org.junit.Test;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author John DeRegnaucourt (john@cedarsoftware.com)
* <br>
* Copyright (c) Cedar Software LLC
* <br><br>
* 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
* <br><br>
* http://www.apache.org/licenses/LICENSE-2.0
* <br><br>
* 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.
*/
public class TestCaseInsensitiveMap
{
@Test
public void testMapStraightUp()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
assertTrue(stringMap.get("one").equals("Two"));
assertTrue(stringMap.get("One").equals("Two"));
assertTrue(stringMap.get("oNe").equals("Two"));
assertTrue(stringMap.get("onE").equals("Two"));
assertTrue(stringMap.get("ONe").equals("Two"));
assertTrue(stringMap.get("oNE").equals("Two"));
assertTrue(stringMap.get("ONE").equals("Two"));
assertFalse(stringMap.get("one").equals("two"));
assertTrue(stringMap.get("three").equals("Four"));
assertTrue(stringMap.get("fIvE").equals("Six"));
}
@Test
public void testWithNonStringKeys()
{
CaseInsensitiveMap stringMap = new CaseInsensitiveMap();
stringMap.put(97, "eight");
stringMap.put(19, "nineteen");
stringMap.put("a", "two");
stringMap.put("three", "four");
stringMap.put(null, "null");
assertEquals("two", stringMap.get("a"));
assertEquals("four", stringMap.get("three"));
assertNull(stringMap.get(8L));
assertEquals("nineteen", stringMap.get(19));
assertEquals("null", stringMap.get(null));
}
@Test
public void testOverwrite()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
assertTrue(stringMap.get("three").equals("Four"));
stringMap.put("thRee", "Thirty");
assertFalse(stringMap.get("three").equals("Four"));
assertTrue(stringMap.get("three").equals("Thirty"));
assertTrue(stringMap.get("THREE").equals("Thirty"));
}
@Test
public void testKeySetWithOverwriteAttempt()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
stringMap.put("thREe", "Four");
Set<String> keySet = stringMap.keySet();
assertNotNull(keySet);
assertTrue(!keySet.isEmpty());
assertTrue(keySet.size() == 3);
boolean foundOne = false, foundThree = false, foundFive = false;
for (String key : keySet)
{
if (key.equals("One"))
{
foundOne = true;
}
if (key.equals("Three"))
{
foundThree = true;
}
if (key.equals("Five"))
{
foundFive = true;
}
}
assertTrue(foundOne);
assertTrue(foundThree);
assertTrue(foundFive);
}
@Test
public void testEntrySetWithOverwriteAttempt()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
stringMap.put("thREe", "four");
Set<Map.Entry<String, Object>> entrySet = stringMap.entrySet();
assertNotNull(entrySet);
assertTrue(entrySet.size() == 3);
boolean foundOne = false, foundThree = false, foundFive = false;
for (Map.Entry<String, Object> entry : entrySet)
{
String key = entry.getKey();
Object value = entry.getValue();
if (key.equals("One") && value.equals("Two"))
{
foundOne = true;
}
if (key.equals("Three") && value.equals("four"))
{
foundThree = true;
}
if (key.equals("Five") && value.equals("Six"))
{
foundFive = true;
}
}
assertTrue(foundOne);
assertTrue(foundThree);
assertTrue(foundFive);
}
@Test
public void testPutAll()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
CaseInsensitiveMap<String, Object> newMap = new CaseInsensitiveMap<String, Object>(2);
newMap.put("thREe", "four");
newMap.put("Seven", "Eight");
stringMap.putAll(newMap);
assertTrue(stringMap.size() == 4);
assertFalse(stringMap.get("one").equals("two"));
assertTrue(stringMap.get("fIvE").equals("Six"));
assertTrue(stringMap.get("three").equals("four"));
assertTrue(stringMap.get("seven").equals("Eight"));
Map a = createSimpleMap();
a.putAll(null); // Ensure NPE not happening
}
@Test
public void testContainsKey()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
assertTrue(stringMap.containsKey("one"));
assertTrue(stringMap.containsKey("One"));
assertTrue(stringMap.containsKey("oNe"));
assertTrue(stringMap.containsKey("onE"));
assertTrue(stringMap.containsKey("ONe"));
assertTrue(stringMap.containsKey("oNE"));
assertTrue(stringMap.containsKey("ONE"));
}
@Test
public void testRemove()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
assertTrue(stringMap.remove("one").equals("Two"));
assertNull(stringMap.get("one"));
}
@Test
public void testNulls()
{
CaseInsensitiveMap<String, Object> stringMap = createSimpleMap();
stringMap.put(null, "Something");
assertTrue("Something".equals(stringMap.get(null)));
}
@Test
public void testRemoveIterator()
{
Map map = new CaseInsensitiveMap();
map.put("One", null);
map.put("Two", null);
map.put("Three", null);
int count = 0;
Iterator i = map.keySet().iterator();
while (i.hasNext())
{
i.next();
count++;
}
assertEquals(3, count);
i = map.keySet().iterator();
while (i.hasNext())
{
Object elem = i.next();
if (elem.equals("One"))
{
i.remove();
}
}
assertEquals(2, map.size());
assertFalse(map.containsKey("one"));
assertTrue(map.containsKey("two"));
assertTrue(map.containsKey("three"));
}
@Test
public void testEquals()
{
Map a = createSimpleMap();
Map b = createSimpleMap();
assertTrue(a.equals(b));
Map c = new HashMap();
assertFalse(a.equals(c));
Map other = new LinkedHashMap();
other.put("one", "Two");
other.put("THREe", "Four");
other.put("five", "Six");
assertTrue(a.equals(other));
assertTrue(other.equals(a));
other.clear();
other.put("one", "Two");
other.put("Three-x", "Four");
other.put("five", "Six");
assertFalse(a.equals(other));
other.clear();
other.put("One", "Two");
other.put("Three", "Four");
other.put("Five", "six"); // lowercase six
assertFalse(a.equals(other));
assertFalse(a.equals("Foo"));
other.put("FIVE", null);
assertFalse(a.equals(other));
a = createSimpleMap();
b = createSimpleMap();
a.put("Five", null);
assertNotEquals(a, b);
}
@Test
public void testHashCode()
{
Map a = createSimpleMap();
Map b = new CaseInsensitiveMap(a);
assertTrue(a.hashCode() == b.hashCode());
b = new CaseInsensitiveMap();
b.put("ONE", "Two");
b.put("THREE", "Four");
b.put("FIVE", "Six");
assertEquals(a.hashCode(), b.hashCode());
b = new CaseInsensitiveMap();
b.put("One", "Two");
b.put("THREE", "FOUR");
b.put("Five", "Six");
assertFalse(a.hashCode() == b.hashCode()); // value FOUR is different than Four
}
@Test
public void testToString()
{
assertNotNull(createSimpleMap().toString());
}
@Test
public void testClear()
{
Map a = createSimpleMap();
a.clear();
assertEquals(0, a.size());
}
@Test
public void testContainsValue()
{
Map a = createSimpleMap();
assertTrue(a.containsValue("Two"));
assertFalse(a.containsValue("TWO"));
}
@Test
public void testValues()
{
Map a = createSimpleMap();
Collection col = a.values();
assertEquals(3, col.size());
assertTrue(col.contains("Two"));
assertTrue(col.contains("Four"));
assertTrue(col.contains("Six"));
assertFalse(col.contains("TWO"));
}
@Test
public void testNullKey()
{
Map a = createSimpleMap();
a.put(null, "foo");
String b = (String) a.get(null);
int x = b.hashCode();
assertEquals("foo", b);
}
@Test
public void testConstructors()
{
Map<String, Object> map = new CaseInsensitiveMap<String, Object>();
map.put("BTC", "Bitcoin");
map.put("LTC", "Litecoin");
assertTrue(map.size() == 2);
assertEquals("Bitcoin", map.get("btc"));
assertEquals("Litecoin", map.get("ltc"));
map = new CaseInsensitiveMap<String, Object>(20);
map.put("BTC", "Bitcoin");
map.put("LTC", "Litecoin");
assertTrue(map.size() == 2);
assertEquals("Bitcoin", map.get("btc"));
assertEquals("Litecoin", map.get("ltc"));
map = new CaseInsensitiveMap<String, Object>(20, 0.85f);
map.put("BTC", "Bitcoin");
map.put("LTC", "Litecoin");
assertTrue(map.size() == 2);
assertEquals("Bitcoin", map.get("btc"));
assertEquals("Litecoin", map.get("ltc"));
Map map1 = new HashMap<String, Object>();
map1.put("BTC", "Bitcoin");
map1.put("LTC", "Litecoin");
map = new CaseInsensitiveMap<String, Object>(map1);
assertTrue(map.size() == 2);
assertEquals("Bitcoin", map.get("btc"));
assertEquals("Litecoin", map.get("ltc"));
}
@Test
public void testEqualsAndHashCode()
{
Map map1 = new HashMap();
map1.put("BTC", "Bitcoin");
map1.put("LTC", "Litecoin");
map1.put(16, 16);
map1.put(null, null);
Map map2 = new CaseInsensitiveMap();
map2.put("BTC", "Bitcoin");
map2.put("LTC", "Litecoin");
map2.put(16, 16);
map2.put(null, null);
Map map3 = new CaseInsensitiveMap();
map3.put("btc", "Bitcoin");
map3.put("ltc", "Litecoin");
map3.put(16, 16);
map3.put(null, null);
assertTrue(map1.hashCode() != map2.hashCode()); // By design: case sensitive maps will [rightly] compute hash of ABC and abc differently
assertTrue(map1.hashCode() != map3.hashCode()); // By design: case sensitive maps will [rightly] compute hash of ABC and abc differently
assertTrue(map2.hashCode() == map3.hashCode());
assertTrue(map1.equals(map2));
assertTrue(map1.equals(map3));
assertTrue(map3.equals(map1));
assertTrue(map2.equals(map3));
}
// --------- Test returned keySet() operations ---------
@Test
public void testKeySetContains()
{
Map m = createSimpleMap();
Set s = m.keySet();
assertTrue(s.contains("oNe"));
assertTrue(s.contains("thRee"));
assertTrue(s.contains("fiVe"));
assertFalse(s.contains("dog"));
}
@Test
public void testKeySetContainsAll()
{
Map m = createSimpleMap();
Set s = m.keySet();
Set items = new HashSet();
items.add("one");
items.add("five");
assertTrue(s.containsAll(items));
items.add("dog");
assertFalse(s.containsAll(items));
}
@Test
public void testKeySetRemove()
{
Map m = createSimpleMap();
Set s = m.keySet();
s.remove("Dog");
assertEquals(3, m.size());
assertEquals(3, s.size());
assertTrue(s.remove("oNe"));
assertTrue(s.remove("thRee"));
assertTrue(s.remove("fiVe"));
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testKeySetRemoveAll()
{
Map m = createSimpleMap();
Set s = m.keySet();
Set items = new HashSet();
items.add("one");
items.add("five");
assertTrue(s.removeAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains("three"));
assertTrue(m.containsKey("three"));
items.clear();
items.add("dog");
s.removeAll(items);
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains("three"));
assertTrue(m.containsKey("three"));
}
@Test
public void testKeySetRetainAll()
{
Map m = createSimpleMap();
Set s = m.keySet();
Set items = new HashSet();
items.add("three");
assertTrue(s.retainAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains("three"));
assertTrue(m.containsKey("three"));
m = createSimpleMap();
s = m.keySet();
items.clear();
items.add("dog");
items.add("one");
assertTrue(s.retainAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains("one"));
assertTrue(m.containsKey("one"));
}
@Test
public void testKeySetToObjectArray()
{
Map m = createSimpleMap();
Set s = m.keySet();
Object[] array = s.toArray();
assertEquals(array[0], "One");
assertEquals(array[1], "Three");
assertEquals(array[2], "Five");
}
@Test
public void testKeySetToTypedArray()
{
Map m = createSimpleMap();
Set s = m.keySet();
String[] array = (String[]) s.toArray(new String[]{});
assertEquals(array[0], "One");
assertEquals(array[1], "Three");
assertEquals(array[2], "Five");
array = (String[]) s.toArray(new String[4]);
assertEquals(array[0], "One");
assertEquals(array[1], "Three");
assertEquals(array[2], "Five");
assertEquals(array[3], null);
assertEquals(4, array.length);
array = (String[]) s.toArray(new String[]{"","",""});
assertEquals(array[0], "One");
assertEquals(array[1], "Three");
assertEquals(array[2], "Five");
assertEquals(3, array.length);
}
@Test
public void testKeySetClear()
{
Map m = createSimpleMap();
Set s = m.keySet();
s.clear();
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testKeySetHashCode()
{
Map m = createSimpleMap();
Set s = m.keySet();
int h = s.hashCode();
Set s2 = new HashSet();
s2.add("One");
s2.add("Three");
s2.add("Five");
assertNotEquals(h, s2.hashCode());
s2 = new CaseInsensitiveSet();
s2.add("One");
s2.add("Three");
s2.add("Five");
assertEquals(h, s2.hashCode());
}
@Test
public void testKeySetIteratorActions()
{
Map m = createSimpleMap();
Set s = m.keySet();
Iterator i = s.iterator();
Object o = i.next();
assertTrue(o instanceof String);
i.remove();
assertEquals(2, m.size());
assertEquals(2, s.size());
o = i.next();
assertTrue(o instanceof String);
i.remove();
assertEquals(1, m.size());
assertEquals(1, s.size());
o = i.next();
assertTrue(o instanceof String);
i.remove();
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testKeySetEquals()
{
Map m = createSimpleMap();
Set s = m.keySet();
Set s2 = new HashSet();
s2.add("One");
s2.add("Three");
s2.add("Five");
assertTrue(s2.equals(s));
assertTrue(s.equals(s2));
Set s3 = new HashSet();
s3.add("one");
s3.add("three");
s3.add("five");
assertFalse(s3.equals(s));
assertTrue(s.equals(s3));
Set s4 = new CaseInsensitiveSet();
s4.add("one");
s4.add("three");
s4.add("five");
assertTrue(s4.equals(s));
assertTrue(s.equals(s4));
}
@Test
public void testKeySetAddNotSupported()
{
Map m = createSimpleMap();
Set s = m.keySet();
try
{
s.add("Bitcoin");
fail("should not make it here");
}
catch (UnsupportedOperationException e)
{ }
Set items = new HashSet();
items.add("Food");
items.add("Water");
try
{
s.addAll(items);
fail("should not make it here");
}
catch (UnsupportedOperationException e)
{ }
}
// ---------------- returned Entry Set tests ---------
@Test
public void testEntrySetContains()
{
Map m = createSimpleMap();
Set s = m.entrySet();
assertTrue(s.contains(getEntry("one", "Two")));
assertTrue(s.contains(getEntry("tHree", "Four")));
assertFalse(s.contains(getEntry("one", "two"))); // Value side is case-sensitive (needs 'Two' not 'two')
assertFalse(s.contains("Not an entry"));
}
@Test
public void testEntrySetContainsAll()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Set items = new HashSet();
items.add(getEntry("one", "Two"));
items.add(getEntry("thRee", "Four"));
assertTrue(s.containsAll(items));
items = new HashSet();
items.add(getEntry("one", "two"));
items.add(getEntry("thRee", "Four"));
assertFalse(s.containsAll(items));
}
@Test
public void testEntrySetRemove()
{
Map m = createSimpleMap();
Set s = m.entrySet();
assertFalse(s.remove(getEntry("Cat", "Six")));
assertEquals(3, m.size());
assertEquals(3, s.size());
assertTrue(s.remove(getEntry("oNe", "Two")));
assertTrue(s.remove(getEntry("thRee", "Four")));
assertFalse(s.remove(getEntry("Dog", "Two")));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.remove(getEntry("fiVe", "Six")));
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetRemoveAll()
{
// Pure JDK test that fails
// LinkedHashMap<String, Object> mm = new LinkedHashMap<String, Object>();
// mm.put("One", "Two");
// mm.put("Three", "Four");
// mm.put("Five", "Six");
// Set ss = mm.entrySet();
// Set itemz = new HashSet();
// itemz.add(getEntry("One", "Two"));
// itemz.add(getEntry("Five", "Six"));
// ss.removeAll(itemz);
//
// itemz.clear();
// itemz.add(getEntry("dog", "Two"));
// assertFalse(ss.removeAll(itemz));
// assertEquals(1, mm.size());
// assertEquals(1, ss.size());
// assertTrue(ss.contains(getEntry("Three", "Four")));
// assertTrue(mm.containsKey("Three"));
//
// itemz.clear();
// itemz.add(getEntry("Three", "Four"));
// assertTrue(ss.removeAll(itemz)); // fails - bug in JDK (Watching to see if this gets fixed)
// assertEquals(0, mm.size());
// assertEquals(0, ss.size());
// Cedar Software code handles removeAll from entrySet perfectly
Map m = createSimpleMap();
Set s = m.entrySet();
Set items = new HashSet();
items.add(getEntry("one", "Two"));
items.add(getEntry("five", "Six"));
assertTrue(s.removeAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains(getEntry("three", "Four")));
assertTrue(m.containsKey("three"));
items.clear();
items.add(getEntry("dog", "Two"));
assertFalse(s.removeAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains(getEntry("three", "Four")));
assertTrue(m.containsKey("three"));
items.clear();
items.add(getEntry("three", "Four"));
assertTrue(s.removeAll(items));
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetRetainAll()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Set items = new HashSet();
items.add(getEntry("three", "Four"));
assertTrue(s.retainAll(items));
assertEquals(1, m.size());
assertEquals(1, s.size());
assertTrue(s.contains(getEntry("three", "Four")));
assertTrue(m.containsKey("three"));
items.clear();
items.add("dog");
assertTrue(s.retainAll(items));
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetRetainAll2()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Set items = new HashSet();
items.add(getEntry("three", null));
assertTrue(s.retainAll(items));
assertEquals(0, m.size());
assertEquals(0, s.size());
m = createSimpleMap();
s = m.entrySet();
items.clear();
items.add(getEntry("three", 16));
assertTrue(s.retainAll(items));
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetToObjectArray()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Object[] array = s.toArray();
assertEquals(3, array.length);
Map.Entry entry = (Map.Entry) array[0];
assertEquals("One", entry.getKey());
assertEquals("Two", entry.getValue());
entry = (Map.Entry) array[1];
assertEquals("Three", entry.getKey());
assertEquals("Four", entry.getValue());
entry = (Map.Entry) array[2];
assertEquals("Five", entry.getKey());
assertEquals("Six", entry.getValue());
}
@Test
public void testEntrySetToTypedArray()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Map.Entry[] array = (Map.Entry[]) s.toArray(new Map.Entry[]{});
assertEquals(array[0], getEntry("One", "Two"));
assertEquals(array[1], getEntry("Three", "Four"));
assertEquals(array[2], getEntry("Five", "Six"));
s = m.entrySet(); // Should not need to do this (JDK has same issue)
array = (Map.Entry[]) s.toArray(new Map.Entry[4]);
assertEquals(array[0], getEntry("One", "Two"));
assertEquals(array[1], getEntry("Three", "Four"));
assertEquals(array[2], getEntry("Five", "Six"));
assertEquals(array[3], null);
assertEquals(4, array.length);
s = m.entrySet();
array = (Map.Entry[]) s.toArray(new Map.Entry[]{getEntry(1, 1), getEntry(2, 2), getEntry(3, 3)});
assertEquals(array[0], getEntry("One", "Two"));
assertEquals(array[1], getEntry("Three", "Four"));
assertEquals(array[2], getEntry("Five", "Six"));
assertEquals(3, array.length);
}
@Test
public void testEntrySetClear()
{
Map m = createSimpleMap();
Set s = m.entrySet();
s.clear();
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetHashCode()
{
Map m = createSimpleMap();
Map m2 = new CaseInsensitiveMap();
m2.put("one", "Two");
m2.put("three", "Four");
m2.put("five", "Six");
assertEquals(m.hashCode(), m2.hashCode());
Map m3 = new LinkedHashMap();
m3.put("One", "Two");
m3.put("Three", "Four");
m3.put("Five", "Six");
assertNotEquals(m.hashCode(), m3.hashCode());
}
@Test
public void testEntrySetIteratorActions()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Iterator i = s.iterator();
Object o = i.next();
assertTrue(o instanceof Map.Entry);
i.remove();
assertEquals(2, m.size());
assertEquals(2, s.size());
o = i.next();
assertTrue(o instanceof Map.Entry);
i.remove();
assertEquals(1, m.size());
assertEquals(1, s.size());
o = i.next();
assertTrue(o instanceof Map.Entry);
i.remove();
assertEquals(0, m.size());
assertEquals(0, s.size());
}
@Test
public void testEntrySetEquals()
{
Map m = createSimpleMap();
Set s = m.entrySet();
Set s2 = new HashSet();
s2.add(getEntry("One", "Two"));
s2.add(getEntry("Three", "Four"));
s2.add(getEntry("Five", "Six"));
assertTrue(s.equals(s2));
s2.clear();
s2.add(getEntry("One", "Two"));
s2.add(getEntry("Three", "Four"));
s2.add(getEntry("Five", "six")); // lowercase six
assertFalse(s.equals(s2));
s2.clear();
s2.add(getEntry("One", "Two"));
s2.add(getEntry("Thre", "Four")); // missing 'e' on three
s2.add(getEntry("Five", "Six"));
assertFalse(s.equals(s2));
Set s3 = new HashSet();
s3.add(getEntry("one", "Two"));
s3.add(getEntry("three", "Four"));
s3.add(getEntry("five","Six"));
assertTrue(s.equals(s3));
Set s4 = new CaseInsensitiveSet();
s4.add(getEntry("one", "Two"));
s4.add(getEntry("three", "Four"));
s4.add(getEntry("five","Six"));
assertTrue(s.equals(s4));
CaseInsensitiveMap<String, Object> secondStringMap = createSimpleMap();
assertFalse(s.equals("one"));
assertTrue(s.equals(secondStringMap.entrySet()));
// case-insensitive
secondStringMap.put("five", "Six");
assertTrue(s.equals(secondStringMap.entrySet()));
secondStringMap.put("six", "sixty");
assertFalse(s.equals(secondStringMap.entrySet()));
secondStringMap.remove("five");
assertFalse(s.equals(secondStringMap.entrySet()));
secondStringMap.put("five", null);
secondStringMap.remove("six");
assertFalse(s.equals(secondStringMap.entrySet()));
m.put("five", null);
assertTrue(m.entrySet().equals(secondStringMap.entrySet()));
}
@Test
public void testEntrySetAddNotSupport()
{
Map m = createSimpleMap();
Set s = m.entrySet();
try
{
s.add(10);
fail("should not make it here");
}
catch (UnsupportedOperationException e)
{ }
Set s2 = new HashSet();
s2.add("food");
s2.add("water");
try
{
s.addAll(s2);
fail("should not make it here");
}
catch (UnsupportedOperationException e)
{ }
}
@Test
public void testEntrySetKeyInsensitive()
{
Map<String, Object> m = createSimpleMap();
int one = 0;
int three = 0;
int five = 0;
for (Map.Entry<String, Object> entry : m.entrySet())
{
if (entry.equals(new AbstractMap.SimpleEntry("one", "Two")))
{
one++;
}
if (entry.equals(new AbstractMap.SimpleEntry("thrEe", "Four")))
{
three++;
}
if (entry.equals(new AbstractMap.SimpleEntry("FIVE", "Six")))
{
five++;
}
}
assertEquals(1, one);
assertEquals(1, three);
assertEquals(1, five);
}
@Test
public void testRetainAll2()
{
Map<String, String> oldMap = new CaseInsensitiveMap<>();
Map<String, String> newMap = new CaseInsensitiveMap<>();
oldMap.put("foo", null);
oldMap.put("bar", null);
newMap.put("foo", null);
newMap.put("bar", null);
newMap.put("qux", null);
Set<String> oldKeys = oldMap.keySet();
Set<String> newKeys = newMap.keySet();
assertTrue(newKeys.retainAll(oldKeys));
}
@Test
public void testRemoveAll2()
{
Map<String, String> oldMap = new CaseInsensitiveMap<>();
Map<String, String> newMap = new CaseInsensitiveMap<>();
oldMap.put("bart", null);
oldMap.put("qux", null);
newMap.put("foo", null);
newMap.put("bar", null);
newMap.put("qux", null);
Set<String> oldKeys = oldMap.keySet();
Set<String> newKeys = newMap.keySet();
boolean ret = newKeys.removeAll(oldKeys);
assertTrue(ret);
}
@Test
public void testAgainstUnmodifiableMap()
{
Map<String, String> oldMeta = new CaseInsensitiveMap<>();
oldMeta.put("foo", "baz");
oldMeta = Collections.unmodifiableMap(oldMeta);
oldMeta.keySet();
Map<String, String> newMeta = new CaseInsensitiveMap<>();
newMeta.put("foo", "baz");
newMeta.put("bar", "qux");
newMeta = Collections.unmodifiableMap(newMeta);
Set<String> oldKeys = new CaseInsensitiveSet<>(oldMeta.keySet());
Set<String> sameKeys = new CaseInsensitiveSet<>(newMeta.keySet());
sameKeys.retainAll(oldKeys);
}
@Test
public void testSetValueApiOnEntrySet()
{
Map<String, String> map = new CaseInsensitiveMap();
map.put("One", "Two");
map.put("Three", "Four");
map.put("Five", "Six");
for (Map.Entry<String, String> entry : map.entrySet())
{
if ("Three".equals(entry.getKey()))
{ // Make sure this 'writes thru' to the underlying map's value.
entry.setValue("~3");
}
}
assertEquals("~3", map.get("Three"));
}
@Test
public void testWrappedTreeMap()
{
Map map = new CaseInsensitiveMap(new TreeMap());
map.put("z", "zulu");
map.put("J", "juliet");
map.put("a", "alpha");
assert map.size() == 3;
Iterator i = map.keySet().iterator();
assert "a" == i.next();
assert "J" == i.next();
assert "z" == i.next();
assert map.containsKey("A");
assert map.containsKey("j");
assert map.containsKey("Z");
assert ((CaseInsensitiveMap)map).getWrappedMap() instanceof TreeMap;
}
@Test
public void testWrappedTreeMapNotAllowsNull()
{
try
{
Map map = new CaseInsensitiveMap(new TreeMap());
map.put(null, "not allowed");
fail();
}
catch (NullPointerException ignored)
{ }
}
@Test
public void testWrappedConcurrentHashMap()
{
Map map = new CaseInsensitiveMap(new ConcurrentHashMap());
map.put("z", "zulu");
map.put("J", "juliet");
map.put("a", "alpha");
assert map.size() == 3;
assert map.containsKey("A");
assert map.containsKey("j");
assert map.containsKey("Z");
assert ((CaseInsensitiveMap)map).getWrappedMap() instanceof ConcurrentHashMap;
}
@Test
public void testWrappedConcurrentMapNotAllowsNull()
{
try
{
Map map = new CaseInsensitiveMap(new ConcurrentHashMap());
map.put(null, "not allowed");
fail();
}
catch (NullPointerException ignored)
{ }
}
@Test
public void testUnmodifiableMap()
{
Map junkMap = new ConcurrentHashMap();
junkMap.put("z", "zulu");
junkMap.put("J", "juliet");
junkMap.put("a", "alpha");
Map map = new CaseInsensitiveMap(Collections.unmodifiableMap(junkMap));
assert map.size() == 3;
assert map.containsKey("A");
assert map.containsKey("j");
assert map.containsKey("Z");
map.put("h", "hotel"); // modifiable allowed on the CaseInsensitiveMap
}
@Test
public void testWeakHashMap()
{
Map map = new CaseInsensitiveMap(new WeakHashMap());
map.put("z", "zulu");
map.put("J", "juliet");
map.put("a", "alpha");
assert map.size() == 3;
assert map.containsKey("A");
assert map.containsKey("j");
assert map.containsKey("Z");
assert ((CaseInsensitiveMap)map).getWrappedMap() instanceof WeakHashMap;
}
@Test
public void testWrasppedMap()
{
Map linked = new LinkedHashMap();
linked.put("key1", 1);
linked.put("key2", 2);
linked.put("key3", 3);
CaseInsensitiveMap caseInsensitive = new CaseInsensitiveMap(linked);
Set<String> newKeys = new LinkedHashSet();
newKeys.add("key4");
newKeys.add("key5");
int newValue = 4;
for (String key : newKeys)
{
caseInsensitive.put(key, newValue++);
}
Iterator i = caseInsensitive.keySet().iterator();
assertEquals(i.next(), "key1");
assertEquals(i.next(), "key2");
assertEquals(i.next(), "key3");
assertEquals(i.next(), "key4");
assertEquals(i.next(), "key5");
}
// Used only during development right now
// @Test
// public void testPerformance()
// {
// Map<String, String> map = new CaseInsensitiveMap();
// Map<String, String> copy = new LinkedHashMap();
// Random random = new Random();
//
// long start = System.nanoTime();
//
// for (int i=0; i < 1000000; i++)
// {
// String key = StringUtilities.getRandomString(random, 1, 10);
// String value = StringUtilities.getRandomString(random, 1, 10);
// map.put(key, value);
// copy.put(key.toLowerCase(), value);
// }
//
// long stop = System.nanoTime();
// System.out.println((stop - start) / 1000000);
//
// start = System.nanoTime();
//
//// for (Map.Entry<String, String> entry : map.entrySet())
//// {
////
//// }
////
//// for (Object key : copy.keySet())
//// {
////
//// }
//
// for (Map.Entry<String, String> entry : map.entrySet())
// {
// String value = map.get(entry.getKey());
// }
//
// stop = System.nanoTime();
//
// System.out.println((stop - start) / 1000000);
// }
// ---------------------------------------------------
private CaseInsensitiveMap<String, Object> createSimpleMap()
{
CaseInsensitiveMap<String, Object> stringMap = new CaseInsensitiveMap<String, Object>();
stringMap.put("One", "Two");
stringMap.put("Three", "Four");
stringMap.put("Five", "Six");
return stringMap;
}
private Map.Entry getEntry(final Object key, final Object value)
{
return new Map.Entry()
{
Object myValue = value;
public Object getKey()
{
return key;
}
public Object getValue()
{
return value;
}
public Object setValue(Object value)
{
Object save = myValue;
myValue = value;
return save;
}
};
}
}