6
6
import static org .junit .Assert .assertFalse ;
7
7
import static org .junit .Assert .assertSame ;
8
8
import static org .junit .Assert .assertTrue ;
9
+ import static org .junit .Assert .fail ;
9
10
import static org .mockito .Mockito .mock ;
10
11
import static org .mockito .Mockito .times ;
11
12
import static org .mockito .Mockito .verify ;
12
13
import static org .mockito .Mockito .verifyNoMoreInteractions ;
13
- import static org .mockito .Mockito .verifyZeroInteractions ;
14
14
import javafx .beans .property .SimpleStringProperty ;
15
15
import javafx .beans .property .StringProperty ;
16
16
import javafx .beans .value .ChangeListener ;
@@ -40,10 +40,15 @@ public abstract class AbstractNestedChangeListenerHandleTest {
40
40
private NestingAccess .EditableNesting <StringProperty > nesting ;
41
41
42
42
/**
43
- * The added listener. This {@link ChangeListener} will be mocked to verify possible invocations.
43
+ * The default listener. This {@link ChangeListener} will be mocked to verify invocations.
44
44
*/
45
45
private ChangeListener <String > listener ;
46
46
47
+ /**
48
+ * A listener which fails the test when being called.
49
+ */
50
+ private ChangeListener <String > listenerWhichFailsWhenCalled ;
51
+
47
52
/**
48
53
* The tested nested listener, which adds the {@link #listener} to the {@link #nesting}.
49
54
*/
@@ -65,11 +70,15 @@ public void setUp() {
65
70
innerObservable = new SimpleStringProperty ("initial value" );
66
71
nesting = NestingAccess .EditableNesting .createWithInnerObservable (innerObservable );
67
72
listener = mock (ChangeListener .class );
73
+ listenerWhichFailsWhenCalled = (obs , oldValue , newValue ) -> fail ();
68
74
}
69
75
70
76
/**
71
77
* Creates a new, initially attached nested listener from the specified nesting and listener.
72
78
*
79
+ * @param <T>
80
+ * the value wrapped by the nesting's inner observable, which is also the type observed by the change
81
+ * listener
73
82
* @param nesting
74
83
* the {@link Nesting} to which the listener will be added
75
84
* @param listener
@@ -85,6 +94,9 @@ private <T> NestedChangeListenerHandle<T> createAttachedNestedListenerHandle(
85
94
/**
86
95
* Creates a new, initially detached nested listener from the specified nesting and listener.
87
96
*
97
+ * @param <T>
98
+ * the value wrapped by the nesting's inner observable, which is also the type observed by the change
99
+ * listener
88
100
* @param nesting
89
101
* the {@link Nesting} to which the listener will be added
90
102
* @param listener
@@ -100,10 +112,15 @@ private <T> NestedChangeListenerHandle<T> createDetachedNestedListenerHandle(
100
112
/**
101
113
* Creates a new nested listener from the specified nesting and listener.
102
114
*
115
+ * @param <T>
116
+ * the value wrapped by the nesting's inner observable, which is also the type observed by the change
117
+ * listener
103
118
* @param nesting
104
119
* the {@link Nesting} to which the listener will be added
105
120
* @param listener
106
121
* the {@link ChangeListener} which will be added to the nesting
122
+ * @param attachedOrDetached
123
+ * indicates whether the listener will be initially attached or detached
107
124
* @return a new {@link NestedChangeListenerHandle}
108
125
*/
109
126
protected abstract <T > NestedChangeListenerHandle <T > createNestedListenerHandle (
@@ -140,11 +157,8 @@ public void testObservablePresentAfterConstruction() {
140
157
*/
141
158
@ Test
142
159
public void testNoInteractionWithListenerDuringConstruction () {
143
- nestedListenerHandle = createDetachedNestedListenerHandle (nesting , listener );
144
- verifyZeroInteractions (listener );
145
-
146
- nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
147
- verifyZeroInteractions (listener );
160
+ nestedListenerHandle = createDetachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
161
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
148
162
}
149
163
150
164
// changing value
@@ -155,10 +169,8 @@ public void testNoInteractionWithListenerDuringConstruction() {
155
169
*/
156
170
@ Test
157
171
public void testChangingValueWhenInitiallyDetached () {
158
- nestedListenerHandle = createDetachedNestedListenerHandle (nesting , listener );
172
+ nestedListenerHandle = createDetachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
159
173
innerObservable .set ("new value" );
160
-
161
- verifyZeroInteractions (listener );
162
174
}
163
175
164
176
/**
@@ -174,50 +186,29 @@ public void testChangingValue() {
174
186
verifyNoMoreInteractions (listener );
175
187
}
176
188
177
- /**
178
- * Tests whether no listener invocation occurs when the nesting's inner observable's value is changed after the
179
- * listener was detached.
180
- */
181
- @ Test
182
- public void testChangingValueAfterDetach () {
183
- nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
184
- // change something while attached
185
- innerObservable .set ("new value" );
186
-
187
- // detach and change something
188
- nestedListenerHandle .detach ();
189
- innerObservable .set ("new value while detached" );
190
-
191
- // assert that 'changed' was called only once
192
- verify (listener , times (1 )).changed (innerObservable , "initial value" , "new value" );
193
- verifyNoMoreInteractions (listener );
194
- }
195
-
196
189
// changing observable
197
190
198
191
/**
199
192
* Tests whether no listener invocation occurs when the nesting's inner observable is changed.
200
193
*/
201
194
@ Test
202
195
public void testChangingObservable () {
203
- nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
196
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
204
197
StringProperty newObservable = new SimpleStringProperty ("new observable's initial value" );
205
198
setNestingObservable (nesting , newObservable );
206
199
207
200
assertTrue (nestedListenerHandle .isInnerObservablePresent ());
208
- verifyZeroInteractions (listener );
209
201
}
210
202
211
203
/**
212
204
* Tests whether no listener invocation occurs when the nesting's inner observable is changed to null.
213
205
*/
214
206
@ Test
215
207
public void testChangingObservableToNull () {
216
- nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
208
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
217
209
setNestingObservable (nesting , null );
218
210
219
211
assertFalse (nestedListenerHandle .isInnerObservablePresent ());
220
- verifyZeroInteractions (listener );
221
212
}
222
213
223
214
// changing observable and value
@@ -248,7 +239,7 @@ public void testChangingNewObservablesValue() {
248
239
*/
249
240
@ Test
250
241
public void testChangingOldObservablesValue () {
251
- nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
242
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
252
243
// set a new observable ...
253
244
StringProperty newObservable = new SimpleStringProperty ("new observable's initial value" );
254
245
setNestingObservable (nesting , newObservable );
@@ -257,9 +248,65 @@ public void testChangingOldObservablesValue() {
257
248
258
249
// ... and change the old observable's value
259
250
innerObservable .setValue ("intial observable's new value" );
251
+ }
252
+
253
+ // attach & detach
254
+
255
+ /**
256
+ * Tests whether no listener invocation occurs when the nesting's inner observable's value is changed after the
257
+ * listener was detached.
258
+ */
259
+ @ Test
260
+ public void testDetach () {
261
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
262
+ nestedListenerHandle .detach ();
263
+
264
+ innerObservable .set ("new value while detached" );
265
+ }
266
+
267
+ /**
268
+ * Tests whether the listener ignores values after it was detached repeatedly.
269
+ */
270
+ @ Test
271
+ public void testMultipleDetach () {
272
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listenerWhichFailsWhenCalled );
273
+ nestedListenerHandle .detach ();
274
+ nestedListenerHandle .detach ();
275
+ nestedListenerHandle .detach ();
276
+
277
+ innerObservable .set ("new value while detached" );
278
+ }
260
279
261
- // assert the listener was not invoked
262
- verifyZeroInteractions (listener );
280
+ /**
281
+ * Tests whether the listener is correctly invoked when the nesting's observable changes its value after the
282
+ * listener was detached and reattached.
283
+ */
284
+ @ Test
285
+ public void testReattach () {
286
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
287
+ nestedListenerHandle .detach ();
288
+ nestedListenerHandle .attach ();
289
+ innerObservable .set ("new value" );
290
+
291
+ // assert that 'changed' was called once and with the right arguments
292
+ verify (listener , times (1 )).changed (innerObservable , "initial value" , "new value" );
293
+ verifyNoMoreInteractions (listener );
294
+ }
295
+
296
+ /**
297
+ * Tests whether the listener is only called once even when attached is called repeatedly.
298
+ */
299
+ @ Test
300
+ public void testMultipleAttach () {
301
+ nestedListenerHandle = createAttachedNestedListenerHandle (nesting , listener );
302
+ nestedListenerHandle .attach ();
303
+ nestedListenerHandle .attach ();
304
+ nestedListenerHandle .attach ();
305
+ innerObservable .set ("new value" );
306
+
307
+ // assert that 'changed' was called only once
308
+ verify (listener , times (1 )).changed (innerObservable , "initial value" , "new value" );
309
+ verifyNoMoreInteractions (listener );
263
310
}
264
311
265
312
//#end TESTS
0 commit comments