1   package com.lexicalscope.fluentreflection.bean.endtoend;
2   
3   import static ch.lambdaj.Lambda.selectFirst;
4   import static com.lexicalscope.fluentreflection.bean.BeanMap.map;
5   import static com.lexicalscope.fluentreflection.bean.endtoend.MapEntryMatcher.mapEntry;
6   import static org.hamcrest.MatcherAssert.assertThat;
7   import static org.hamcrest.Matchers.*;
8   
9   import java.util.HashMap;
10  import java.util.Map;
11  
12  import org.junit.Test;
13  
14  /*
15   * Copyright 2011 Tim Wood
16   *
17   * Licensed under the Apache License, Version 2.0 (the "License");
18   * you may not use this file except in compliance with the License.
19   * You may obtain a copy of the License at
20   *
21   * http://www.apache.org/licenses/LICENSE-2.0
22   *
23   * Unless required by applicable law or agreed to in writing, software
24   * distributed under the License is distributed on an "AS IS" BASIS,
25   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26   * See the License for the specific language governing permissions and
27   * limitations under the License. 
28   */
29  
30  public class TestBeanMap {
31      static class Bean {
32          private int readWriteProperty;
33          private String readOnlyProperty;
34          private Object writeOnlyProperty;
35  
36          String getReadOnlyProperty() {
37              return readOnlyProperty;
38          }
39  
40          int getReadWriteProperty() {
41              return readWriteProperty;
42          }
43  
44          void setReadWriteProperty(final int readWriteProperty) {
45              this.readWriteProperty = readWriteProperty;
46          }
47  
48          void setWriteOnlyProperty(final Object writeOnlyProperty) {
49              this.writeOnlyProperty = writeOnlyProperty;
50          }
51      }
52  
53      private final Bean bean = new Bean();
54      private final Map<String, Object> map = map(bean);
55  
56      @Test(expected = IllegalArgumentException.class) public void putNonExistentPropertyCausesException() {
57          map.put("notAProperty", "anything");
58      }
59  
60      @Test public void getNonExistentPropertyGivesNull() {
61          assertThat(map.get("notAProperty"), equalTo(null));
62      }
63  
64      @Test public void propertyIsPresent() {
65          assertThat(map.containsKey("readWriteProperty"), equalTo(true));
66      }
67  
68      @Test public void initalValueOfPropertyIsZero() {
69          assertThat(map.get("readWriteProperty"), equalTo((Object) 0));
70      }
71  
72      @Test public void settingValueOfPropertyUpdatesObject() {
73          assertThat(map.put("readWriteProperty", 14), equalTo((Object) 0));
74          assertThat(bean.getReadWriteProperty(), equalTo(14));
75      }
76  
77      @Test public void settingValueOfObjectUpdatesMap() {
78          bean.setReadWriteProperty(14);
79          assertThat(map.get("readWriteProperty"), equalTo((Object) 14));
80      }
81  
82      @Test public void settingValueOfMapReturnsOldValue() {
83          bean.setReadWriteProperty(14);
84          assertThat(map.put("readWriteProperty", 15), equalTo((Object) 14));
85      }
86  
87      @Test public void readOnlyPropertyIsPresent() {
88          assertThat(map.containsKey("readOnlyProperty"), equalTo(true));
89      }
90  
91      @Test public void initalValueOfReadOnlyPropertyIsNull() {
92          assertThat(map.get("readOnlyProperty"), equalTo((Object) null));
93      }
94  
95      @Test public void settingValueOfReadOnlyPropertyIsIgnoredByObject() {
96          assertThat(map.put("readOnlyProperty", "14"), equalTo((Object) null));
97          assertThat(bean.getReadOnlyProperty(), equalTo(null));
98      }
99  
100     @Test public void changesToReadOnlyPropertyAreReturnedByMap() {
101         bean.readOnlyProperty = "new value";
102         assertThat(map.get("readOnlyProperty"), equalTo((Object) "new value"));
103     }
104 
105     @Test public void settingValueOfReadOnlyPropertyInMapReturnsOldValue() {
106         bean.readOnlyProperty = "old value";
107         assertThat(map.put("readOnlyProperty", "new value"), equalTo((Object) "old value"));
108     }
109 
110     @Test public void writeOnlyPropertyIsPresent() {
111         assertThat(map.containsKey("writeOnlyProperty"), equalTo(true));
112     }
113 
114     @Test public void initalValueOfWriteOnlyPropertyIsNull() {
115         assertThat(map.get("writeOnlyProperty"), equalTo((Object) null));
116     }
117 
118     @Test public void settingValueOfWriteOnlyPropertyUpdatesObject() {
119         assertThat(map.put("writeOnlyProperty", "new value"), equalTo((Object) null));
120         assertThat(bean.writeOnlyProperty, equalTo((Object) "new value"));
121     }
122 
123     @Test public void changesToWriteOnlyPropertyAreIgnoredByMap() {
124         bean.setWriteOnlyProperty("new value");
125         assertThat(map.get("writeOnlyProperty"), equalTo((Object) null));
126     }
127 
128     @Test public void settingValueOfWriteOnlyPropertyInMapReturnsNullValue() {
129         bean.setWriteOnlyProperty("old value");
130         assertThat(map.put("writeOnlyProperty", "new value"), equalTo((Object) null));
131     }
132 
133     @Test(expected = UnsupportedOperationException.class) public void clearIsUnsupported() {
134         map.clear();
135     }
136 
137     @Test(expected = UnsupportedOperationException.class) public void removeIsUnsupported() {
138         map.remove("writeOnlyProperty");
139     }
140 
141     @Test public void containsInitialReadableValues() {
142         assertThat(map.containsValue(0), equalTo(true));
143         assertThat(map.containsValue(null), equalTo(true));
144     }
145 
146     @Test public void containsChangedReadableValues() {
147         bean.setReadWriteProperty(14);
148         assertThat(map.containsValue(14), equalTo(true));
149         assertThat(map.containsValue(0), equalTo(false));
150     }
151 
152     @Test public void doesNotContainsWriteOnlyValues() {
153         bean.setWriteOnlyProperty("myValue");
154         assertThat(map.containsValue("myValue"), equalTo(false));
155     }
156 
157     @Test public void valuesContainsAllValues() {
158         bean.setReadWriteProperty(14);
159         bean.readOnlyProperty = "my value";
160         assertThat(map.values(), containsInAnyOrder((Object) 14, "my value", null));
161     }
162 
163     @Test public void keySetContainsAllProperties() {
164         assertThat(map.keySet(), containsInAnyOrder("readWriteProperty", "readOnlyProperty", "writeOnlyProperty"));
165     }
166 
167     @Test public void beanWithPropertiesGivesNotEmptyMap() {
168         assertThat(map.isEmpty(), equalTo(false));
169     }
170 
171     @Test public void beanWithoutPropertiesGivesNotEmptyMap() {
172         class EmptyBean {}
173         assertThat(map(new EmptyBean()).isEmpty(), equalTo(true));
174     }
175 
176     @Test public void beanWithPropertiesHasCorrectSize() {
177         assertThat(map.size(), equalTo(3));
178     }
179 
180     @Test public void beanWithoutPropertiesHasZeroSize() {
181         class EmptyBean {}
182         assertThat(map(new EmptyBean()).size(), equalTo(0));
183     }
184 
185     @Test public void putAllUpdatesWritableProperties() {
186         final Map<String, Object> newMap = new HashMap<String, Object>();
187         newMap.put("readWriteProperty", 14);
188         newMap.put("writeOnlyProperty", "My Value");
189 
190         map.putAll(newMap);
191 
192         assertThat(bean.getReadWriteProperty(), equalTo(14));
193         assertThat(bean.writeOnlyProperty, equalTo((Object) "My Value"));
194     }
195 
196     @Test public void putAllIgnoresReadOnlyProperties() {
197         final Map<String, Object> newMap = new HashMap<String, Object>();
198         newMap.put("readOnlyProperty", "My Value");
199 
200         map.putAll(newMap);
201 
202         assertThat(bean.getReadOnlyProperty(), equalTo(null));
203     }
204 
205     @Test(expected = IllegalArgumentException.class) public void putAllWithNonExistentPropertyThrowsException() {
206         final Map<String, Object> newMap = new HashMap<String, Object>();
207         newMap.put("notAProperty", 14);
208 
209         map.putAll(newMap);
210     }
211 
212     @Test public void entrySetContainsAllPropertiesAndReadableValues() {
213         bean.setReadWriteProperty(14);
214         bean.readOnlyProperty = "my value";
215         assertThat(map.entrySet(), hasItem(mapEntry("readWriteProperty", (Object) 14)));
216         assertThat(map.entrySet(), hasItem(mapEntry("readOnlyProperty", (Object) "my value")));
217     }
218 
219     @Test public void entrySetAllowsValuesToBeChanged() {
220         final Map.Entry<String, Object> entry = selectFirst(map.entrySet(), mapEntry("readWriteProperty"));
221         entry.setValue(14);
222         assertThat(bean.getReadWriteProperty(), equalTo(14));
223     }
224 
225     @Test(expected = UnsupportedOperationException.class) public void cannotRemoveFromKeySet() {
226         map.keySet().remove("readWriteProperty");
227     }
228 
229     @Test(expected = UnsupportedOperationException.class) public void cannotRemoveFromKeySetIterator() {
230         map.keySet().iterator().remove();
231     }
232 
233     @Test(expected = UnsupportedOperationException.class) public void cannotRemoveFromEntrySet() {
234         map.entrySet().remove(map.entrySet().iterator().next());
235     }
236 
237     @Test(expected = UnsupportedOperationException.class) public void cannotRemoveFromEntrySetIterator() {
238         map.entrySet().iterator().remove();
239     }
240 }