| package ioc.specs |
| |
| import org.apache.tapestry5.ioc.util.CaseInsensitiveMap |
| import spock.lang.Specification |
| |
| class CaseInsensitiveMapSpec extends Specification { |
| |
| CaseInsensitiveMap map = new CaseInsensitiveMap([fred: "flintstone", barney: "rubble", wilma: "flinstone", betty: "rubble"]) |
| |
| def "get() is case insensitive"() { |
| def map = new CaseInsensitiveMap() |
| |
| def value = "flintstone" |
| |
| when: |
| |
| map.put("fred", value) |
| |
| then: |
| |
| map.get("fred").is(value) |
| map.get("Fred").is(value) |
| } |
| |
| def "containsKey() is case insensitive"() { |
| |
| expect: |
| |
| map.containsKey("fred") |
| map.containsKey("Fred") |
| map.containsKey("barney") |
| map.containsKey("wilma") |
| !map.containsKey("dino") |
| } |
| |
| def "remove() is case insensitive"() { |
| expect: |
| |
| map.containsKey("fred") |
| !map.isEmpty() |
| |
| when: |
| |
| map.remove("FrED") |
| |
| then: |
| |
| map.keySet() == ["barney", "wilma", "betty"] as Set |
| } |
| |
| def "copying Map constructor"() { |
| def standard = [fred: "flintstone", barney: "rubble", wilma: "flintstone"] |
| |
| when: |
| |
| def original = new CaseInsensitiveMap(standard) |
| |
| then: |
| |
| original == standard |
| |
| when: |
| |
| def copy = new CaseInsensitiveMap(original) |
| |
| then: |
| |
| copy == original |
| } |
| |
| def "comparison of two CaseInsensitiveMaps ignores case"() { |
| def lower = new CaseInsensitiveMap([fred: "flintstone", barney: "rubble"]) |
| def upper = new CaseInsensitiveMap([Fred: "flintstone", Barney: "rubble"]) |
| |
| expect: |
| |
| upper == lower |
| } |
| |
| def "put with different case replaces the old key"() { |
| |
| expect: |
| |
| map.keySet() == ["fred", "barney", "betty", "wilma"] as Set |
| |
| |
| when: |
| |
| map.put("FRED", "flintstone") |
| |
| then: |
| |
| map.keySet() == ["FRED", "barney", "betty", "wilma"] as Set |
| } |
| |
| def "get with missing key is null"() { |
| expect: |
| |
| map.notFound == null |
| } |
| |
| def "get with non-string key is null"() { |
| expect: |
| |
| map.get(this) == null |
| } |
| |
| def "expansion of the internal entry array"() { |
| |
| def count = 2000 |
| |
| def map = new CaseInsensitiveMap() |
| |
| count.times { it -> |
| assert map.put("key_$it" as String, it) == null |
| } |
| |
| when: |
| |
| count.times { it -> |
| assert map.get("key_$it" as String) == it |
| } |
| |
| then: |
| |
| map.size() == count |
| map.entrySet().size() == count |
| |
| when: |
| |
| map.clear() |
| |
| then: |
| |
| map.size() == 0 |
| |
| } |
| |
| def "change value via entrySet()"() { |
| def map = new CaseInsensitiveMap() |
| |
| map.put("fred", "flintstone") |
| |
| when: |
| |
| map.entrySet().each { entry -> entry.value = "murray" } |
| |
| then: |
| |
| map.get("fred") == "murray" |
| } |
| |
| def "entrySet iterator fails fast after remove"() { |
| |
| def i = map.entrySet().iterator() |
| |
| i.next() |
| map.remove("betty") |
| |
| when: |
| |
| i.next() |
| |
| then: |
| |
| thrown(ConcurrentModificationException) |
| } |
| |
| def "entrySet iterator fails fast after put"() { |
| |
| def i = map.entrySet().iterator() |
| |
| i.next() |
| map.put("zaphod", "breeblebrox") |
| |
| when: |
| |
| i.next() |
| |
| then: |
| |
| thrown(ConcurrentModificationException) |
| } |
| |
| def "iterator may remove without concurrent exception"() { |
| |
| def i = map.entrySet().iterator() |
| |
| while (i.hasNext()) { |
| if (i.next().key == "wilma") { i.remove() } |
| } |
| |
| expect: |
| |
| map.keySet() == ["barney", "betty", "fred"] as Set |
| } |
| |
| def "contains via entrySet"() { |
| |
| def set = map.entrySet() |
| |
| expect: |
| |
| set.contains(newMapEntry("fred", "flintstone")) |
| set.contains(newMapEntry("Fred", "flintstone")) |
| |
| !set.contains(newMapEntry("Zaphod", "Breeblebox")) |
| !set.contains(newMapEntry("fred", "murray")) |
| } |
| |
| def "remove via entrySet"() { |
| |
| def set = map.entrySet() |
| |
| when: |
| |
| assert set.remove(newMapEntry("Zaphod", "Breeblrox")) == false |
| assert set.remove(newMapEntry("fred", "murray")) == false |
| |
| assert set.remove(newMapEntry("fred", "flintstone")) == true |
| |
| then: |
| |
| map.keySet() == ["barney", "wilma", "betty"] as Set |
| } |
| |
| def newMapEntry(key, value) { |
| return new Map.Entry() { |
| |
| @Override |
| Object getKey() { |
| return key |
| } |
| |
| @Override |
| Object getValue() { |
| return value; |
| } |
| |
| @Override |
| Object setValue(Object newValue) { |
| value = newValue |
| } |
| } |
| } |
| |
| def "null is a valid key"() { |
| when: |
| |
| map.put(null, "NULL") |
| |
| then: |
| |
| map.get(null) == "NULL" |
| } |
| |
| def "clearing the entrySet clears the map"() { |
| expect: |
| |
| !map.isEmpty() |
| !map.entrySet().isEmpty() |
| |
| when: |
| |
| map.entrySet().clear() |
| |
| then: |
| |
| map.isEmpty() |
| } |
| |
| def "next() after last entry in entrySet is a failure"() { |
| Iterator i = map.entrySet().iterator() |
| |
| while (i.hasNext()) { i.next() } |
| |
| when: |
| |
| i.next() |
| |
| then: |
| |
| thrown(NoSuchElementException) |
| } |
| |
| def "serialize/deserialize copies all data"() { |
| |
| def baos = new ByteArrayOutputStream() |
| def oos = new ObjectOutputStream(baos) |
| |
| oos.writeObject(map) |
| oos.close() |
| |
| def bais = new ByteArrayInputStream(baos.toByteArray()) |
| ObjectInputStream ois = new ObjectInputStream(bais) |
| |
| def copy = ois.readObject() |
| |
| expect: |
| |
| copy == map |
| } |
| } |