1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.util.concurrent;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23
24 import org.junit.Test;
25
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.SortedMap;
31
32 public class CopyOnWriteSortedMapTest {
33
34 @Test public void comparator() {
35 final SortedMap<String, String> map = CopyOnWriteMaps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
36 assertNotNull(map.comparator());
37 assertEquals(String.CASE_INSENSITIVE_ORDER, map.comparator());
38 map.put("one", "two");
39 assertNotNull(map.comparator());
40 assertEquals(String.CASE_INSENSITIVE_ORDER, map.comparator());
41 }
42
43 @Test public void firstKey() {
44 final SortedMap<String, String> map = CopyOnWriteMaps.newTreeMap();
45 map.put("one", "value");
46 map.put("two", "value");
47 map.put("three", "value");
48 assertEquals("one", map.firstKey());
49 }
50
51 @Test public void lastKey() {
52 final SortedMap<String, String> map = CopyOnWriteMaps.newTreeMap();
53 map.put("one", "value");
54 map.put("two", "value");
55 map.put("three", "value");
56 assertEquals("two", map.lastKey());
57 }
58
59 @Test public void headMap() {
60 final SortedMap<String, String> map = CopyOnWriteMaps.newTreeMap();
61 map.put("1", "one");
62 map.put("2", "two");
63 map.put("3", "three");
64 final SortedMap<String, String> headMap = map.headMap("3");
65 assertEquals(2, headMap.size());
66 assertTrue(headMap.containsKey("1"));
67 assertTrue(headMap.containsKey("2"));
68 assertTrue(headMap.containsValue("one"));
69 assertTrue(headMap.containsValue("two"));
70
71 assertUnmodifiableMap(headMap, "3", "three");
72 }
73
74 @Test public void tailMap() {
75 final SortedMap<String, String> map = CopyOnWriteMaps.newTreeMap();
76 map.put("1", "one");
77 map.put("2", "two");
78 map.put("3", "three");
79 final SortedMap<String, String> tailMap = map.tailMap("2");
80 assertEquals(2, tailMap.size());
81 assertTrue(tailMap.containsKey("2"));
82 assertTrue(tailMap.containsKey("3"));
83 assertTrue(tailMap.containsValue("two"));
84 assertTrue(tailMap.containsValue("three"));
85
86 assertUnmodifiableMap(tailMap, "1", "one");
87 }
88
89 @Test public void subMap() {
90 final CopyOnWriteSortedMap<String, String> map = CopyOnWriteMaps.newTreeMap();
91 map.put("1", "one");
92 map.put("2", "two");
93 map.put("3", "three");
94 map.put("4", "four");
95 final SortedMap<String, String> subMap = map.subMap("2", "4");
96 assertEquals(2, subMap.size());
97 assertTrue(subMap.containsKey("2"));
98 assertTrue(subMap.containsKey("3"));
99 assertTrue(subMap.containsValue("two"));
100 assertTrue(subMap.containsValue("three"));
101
102 assertUnmodifiableMap(subMap, "1", "one");
103 }
104
105 static <K, V> void assertUnmodifiableMap(final Map<K, V> map, final K key, final V value) {
106 assertThrowsUnsupportedOp(new Runnable() {
107 public void run() {
108 map.put(key, value);
109 }
110 });
111 assertThrowsUnsupportedOp(new Runnable() {
112 public void run() {
113 map.remove(key);
114 }
115 });
116 assertThrowsUnsupportedOp(new Runnable() {
117 public void run() {
118 map.clear();
119 }
120 });
121
122 assertUnmodifiableCollection(map.keySet(), key);
123 assertUnmodifiableCollection(map.values(), value);
124 }
125
126 private static <T> void assertUnmodifiableCollection(final Collection<T> coll, final T element) {
127 assertThrowsUnsupportedOp(new Runnable() {
128 public void run() {
129 coll.clear();
130 }
131 });
132
133 assertThrowsUnsupportedOp(new Runnable() {
134 public void run() {
135 coll.remove(element);
136 }
137 });
138
139 assertThrowsUnsupportedOp(new Runnable() {
140 public void run() {
141 coll.removeAll(Collections.EMPTY_LIST);
142 }
143 });
144
145 assertThrowsUnsupportedOp(new Runnable() {
146 public void run() {
147 coll.add(element);
148 }
149 });
150
151 final Collection<T> empty = Collections.emptyList();
152 assertThrowsUnsupportedOp(new Runnable() {
153 public void run() {
154 coll.addAll(empty);
155 }
156 });
157
158 assertThrowsUnsupportedOp(new Runnable() {
159 public void run() {
160 coll.retainAll(empty);
161 }
162 });
163
164 assertThrowsUnsupportedOp(new Runnable() {
165 public void run() {
166 final Iterator<?> it = coll.iterator();
167 it.next();
168 it.remove();
169 }
170 });
171 }
172
173 static void assertThrowsUnsupportedOp(final Runnable runnable) {
174 try {
175 runnable.run();
176 fail("should have thrown UnsupportedOperationException");
177 }
178 catch (final UnsupportedOperationException ignore) {}
179 }
180 }