Skip to content

Commit 4a7eb4f

Browse files
author
Nicolai Parlog
committed
Wrote tests for nestings.
1 parent ec64891 commit 4a7eb4f

13 files changed

+524
-145
lines changed

src/org/codefx/nesting/property/NestedProperty.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
/**
99
* A property which is based on a {@link Nesting}.
1010
* <p>
11-
* <h2>Inner Observable Changes</h2> When the nesting's inner observable changes, this nested property's value changes
12-
* to the new observable's value. Like all other value changes this one also results in calling all change listeners.
11+
* <h2>Inner Observable's Value Changes</h2> This property is bound to the nesting's inner observable. So when that
12+
* observable's value changes so does this property.
13+
* <h2>Inner Observable Changes</h2> When the nesting's inner observable changes to a non-null value, this nested
14+
* property's value changes to the new observable's value. Like all other value changes this one also results in calling
15+
* all change listeners. If the new observable is null, the property keeps its value and no change listener is called.
1316
* <h2>Inner Observable Holds Null</h2> It is possible that a nesting's inner observable holds null (see class comment
1417
* in {@link Nesting}). In that case the {@link NestedProperty#innerObservableNull() innerObservableNull} property is
1518
* true and changes made to this property's value can not be propagated to another property. If the inner observable
16-
* changes to a non-null value, everything said above applies.
19+
* changes back to a non-null value, everything said above applies.
1720
*
1821
* @param <T>
1922
* the type of the value wrapped by the property
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package org.codefx.nesting;
2+
3+
import static org.codefx.nesting.testhelper.NestingAccess.getNestingObservable;
4+
import static org.junit.Assert.assertNull;
5+
import static org.junit.Assert.assertSame;
6+
import javafx.beans.Observable;
7+
import javafx.beans.value.ObservableValue;
8+
9+
import org.junit.Test;
10+
11+
/**
12+
* Abstract superclass to tests of deep nestings. By implementing the few abstract methods subclasses can run all tests
13+
* which apply to all implementations.
14+
*
15+
* @param <OO>
16+
* the type of the nesting hierarchy's outer observable
17+
* @param <IO>
18+
* the type the nesting hierarchy's inner observable which is also the type wrapped by the nesting
19+
*/
20+
public abstract class AbstractDeepNestingTest<OO extends Observable, IO extends Observable>
21+
extends AbstractNestingTest<OO, IO> {
22+
23+
// #region TESTS
24+
25+
// nested value
26+
27+
/**
28+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
29+
* one of the {@link #outerObservable}'s nested values is changed.
30+
*/
31+
@Test
32+
public void testWhenSettingNestedValue() {
33+
setNewValue(outerObservable, Level.NESTED, Value.ANY);
34+
assertSame(getNestingObservable(nesting), getInnerObservable(outerObservable));
35+
}
36+
37+
/**
38+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
39+
* one of the {@link #outerObservable}'s nested values is changed to one which contains null observables.
40+
*/
41+
@Test
42+
public void testWhenSettingNestedValueWithNullObservables() {
43+
setNewValue(outerObservable, Level.NESTED, Value.ANY_WITH_NULL_OBSERVABLE);
44+
assertNull(getNestingObservable(nesting));
45+
}
46+
47+
/**
48+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
49+
* one of the {@link #outerObservable}'s nested values is set to null.
50+
*/
51+
@Test
52+
public void testWhenSettingNestedValueToNull() {
53+
setNewValue(outerObservable, Level.NESTED, Value.NULL);
54+
assertNull(getNestingObservable(nesting));
55+
}
56+
57+
// outer value
58+
59+
/**
60+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
61+
* the {@link #outerObservable}'s outer value is changed.
62+
*/
63+
@Test
64+
public void testWhenSettingOuterValue() {
65+
setNewValue(outerObservable, Level.OUTER, Value.ANY);
66+
assertSame(getNestingObservable(nesting), getInnerObservable(outerObservable));
67+
}
68+
69+
/**
70+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
71+
* the {@link #outerObservable}'s outer value is changed to one which contains null observables.
72+
*/
73+
@Test
74+
public void testWhenSettingOuterValueWithNullObservables() {
75+
setNewValue(outerObservable, Level.OUTER, Value.ANY_WITH_NULL_OBSERVABLE);
76+
assertNull(getNestingObservable(nesting));
77+
}
78+
79+
/**
80+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} is updated correctly when
81+
* the {@link #outerObservable}'s outer value is set to null.
82+
*/
83+
@Test
84+
public void testWhenSettingOuterValueToNull() {
85+
setNewValue(outerObservable, Level.OUTER, Value.NULL);
86+
assertNull(getNestingObservable(nesting));
87+
}
88+
89+
//#end TESTS
90+
91+
// #region ABSTRACT METHODS
92+
93+
/**
94+
* Sets a new value of the specified kind on the specified level of the nesting hierarchy contained in the specified
95+
* outer observable.
96+
*
97+
* @param outerObservable
98+
* the {@link ObservableValue} which contains the nesting hierarchy's outer value
99+
* @param level
100+
* the {@link Level} on which the new value will be set
101+
* @param newValue
102+
* the kind of {@link Value} which will be set
103+
*/
104+
protected abstract void setNewValue(OO outerObservable, Level level, Value newValue);
105+
106+
//#end ABSTRACT METHODS
107+
108+
// #region INNER CLASSES
109+
110+
/**
111+
* Indicates on which level of the nesting hierarchy a new value will be set by
112+
* {@link AbstractDeepNestingTest#setNewValue(Observable, Level, Value) setNewValue}.
113+
*/
114+
protected enum Level {
115+
116+
/**
117+
* A level below the outer level.
118+
*/
119+
NESTED,
120+
121+
/**
122+
* The outer level.
123+
*/
124+
OUTER,
125+
}
126+
127+
/**
128+
* Indicates what kind of value will be set by {@link AbstractDeepNestingTest#setNewValue(Observable, Level, Value)
129+
* setNewValue}.
130+
*/
131+
protected enum Value {
132+
133+
/**
134+
* The new value will be some fully initialized instance.
135+
*/
136+
ANY,
137+
138+
/**
139+
* The new value will be an instance whose observables are null
140+
*/
141+
ANY_WITH_NULL_OBSERVABLE,
142+
143+
/**
144+
* The new value will be null.
145+
*/
146+
NULL,
147+
148+
}
149+
150+
//#end INNER CLASSES
151+
152+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.codefx.nesting;
2+
3+
import static org.codefx.nesting.testhelper.NestingAccess.setInnerValue;
4+
import static org.codefx.nesting.testhelper.NestingAccess.setOuterValue;
5+
import javafx.beans.Observable;
6+
import javafx.beans.property.Property;
7+
import javafx.beans.property.SimpleObjectProperty;
8+
9+
import org.codefx.nesting.testhelper.InnerValue;
10+
import org.codefx.nesting.testhelper.OuterValue;
11+
12+
/**
13+
* Superclass for tests for deep nestings which are based on the nesting hierarchy in the package
14+
* {@link org.codefx.nesting.testhelper testhelper}.
15+
* <p>
16+
* It leaves {@link #createNewNestingFromOuterObservable(Observable)} and {@link #getInnerObservable(Observable)}
17+
* unimplemented because they refer to the inner observable of generic type {@code O}.
18+
*
19+
* @param <O>
20+
* the type the nesting hierarchy's inner observable which is also the type wrapped by the nesting
21+
*/
22+
public abstract class AbstractDeepNestingTestForDefaultNesting<O extends Observable>
23+
extends AbstractDeepNestingTest<Property<OuterValue>, O> {
24+
25+
@Override
26+
protected Property<OuterValue> createNewNestingHierarchy() {
27+
OuterValue outer = OuterValue.createWithInnerType();
28+
return new SimpleObjectProperty<>(outer);
29+
}
30+
31+
@Override
32+
protected void setNewValue(Property<OuterValue> outerObservable, Level level, Value kindOfNewValue) {
33+
34+
switch (level) {
35+
case NESTED:
36+
switch (kindOfNewValue) {
37+
case ANY:
38+
setInnerValue(outerObservable, InnerValue.createWithObservables());
39+
break;
40+
case ANY_WITH_NULL_OBSERVABLE:
41+
setInnerValue(outerObservable, InnerValue.createWithNulls());
42+
break;
43+
case NULL:
44+
setInnerValue(outerObservable, null);
45+
break;
46+
default:
47+
throw new IllegalArgumentException();
48+
}
49+
break;
50+
case OUTER:
51+
switch (kindOfNewValue) {
52+
case ANY:
53+
setOuterValue(outerObservable, OuterValue.createWithInnerType());
54+
break;
55+
case ANY_WITH_NULL_OBSERVABLE:
56+
setOuterValue(outerObservable, OuterValue.createWithNull());
57+
break;
58+
case NULL:
59+
setOuterValue(outerObservable, null);
60+
break;
61+
default:
62+
throw new IllegalArgumentException();
63+
}
64+
break;
65+
default:
66+
throw new IllegalArgumentException();
67+
}
68+
}
69+
70+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.codefx.nesting;
2+
3+
import static org.codefx.nesting.testhelper.NestingAccess.getNestingObservable;
4+
import static org.junit.Assert.assertSame;
5+
import javafx.beans.Observable;
6+
import javafx.beans.value.ObservableValue;
7+
8+
import org.junit.Before;
9+
import org.junit.Test;
10+
11+
/**
12+
* Abstract superclass to tests of nestings. By implementing the few abstract methods subclasses can run all tests which
13+
* apply to all implementations.
14+
*
15+
* @param <OO>
16+
* the type of the nesting hierarchy's outer observable
17+
* @param <IO>
18+
* the type the nesting hierarchy's inner observable which is also the type wrapped by the nesting
19+
*/
20+
public abstract class AbstractNestingTest<OO extends Observable, IO extends Observable> {
21+
22+
// #region INSTANCES USED FOR TESTING
23+
24+
/**
25+
* The outer observable of the nesting hierarchy contained in {@link #nesting}.
26+
*/
27+
protected OO outerObservable;
28+
29+
/**
30+
* The nesting which is tested.
31+
*/
32+
protected Nesting<IO> nesting;
33+
34+
//#end INSTANCES USED FOR TESTING
35+
36+
/**
37+
* Creates a new instance of {@link #nesting} and {@link #outerObservable}.
38+
*/
39+
@Before
40+
public void setUp() {
41+
outerObservable = createNewNestingHierarchy();
42+
nesting = createNewNestingFromOuterObservable(outerObservable);
43+
}
44+
45+
// #region TESTS
46+
47+
/**
48+
* Tests whether the {@link #nesting}'s {@link Nesting#innerObservable() innerObservable} property contains the
49+
* {@link #outerObservable}'s inner observable.
50+
*/
51+
@Test
52+
public void testCorrectAfterConstruction() {
53+
assertSame(getNestingObservable(nesting), getInnerObservable(outerObservable));
54+
}
55+
56+
//#end TESTS
57+
58+
// #region ABSTRACT METHODS
59+
60+
/**
61+
* Creates a new nesting hierarchy and returns its outer observable. All returned instances must be new for each
62+
* call.
63+
*
64+
* @return an {@link ObservableValue} containing the outer value of a nesting hierarchy
65+
*/
66+
protected abstract OO createNewNestingHierarchy();
67+
68+
/**
69+
* Creates a new nesting from the specified outer observable.
70+
*
71+
* @param outerObservable
72+
* the {@link ObservableValue} which contains the nesting hierarchy's outer value
73+
* @return a new {@link Nesting} instance
74+
*/
75+
protected abstract Nesting<IO> createNewNestingFromOuterObservable(OO outerObservable);
76+
77+
/**
78+
* Returns the specified outer observable's inner observable which is represented by the nesting created by
79+
* {@link #createNewNestingFromOuterObservable(Observable) createNewNestingFromOuterObservable}.
80+
*
81+
* @param outerObservable
82+
* the outer observable of the nesting hierarchy
83+
* @return the inner observable which is wrapped in the nesting
84+
*/
85+
protected abstract IO getInnerObservable(OO outerObservable);
86+
87+
//#end ABSTRACT METHODS
88+
89+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.codefx.nesting;
2+
3+
import javafx.beans.Observable;
4+
5+
/**
6+
* Abstract superclass tests of {@link ShallowNesting ShallowNestings}. Implements all abstract methods from
7+
* {@link AbstractNestingTest} except the creation of the nesting.
8+
*
9+
* @param <O>
10+
* the type of the nesting hierarchy's only observable
11+
*/
12+
public abstract class AbstractShallowNestingTest<O extends Observable> extends AbstractNestingTest<O, O> {
13+
14+
@Override
15+
protected Nesting<O> createNewNestingFromOuterObservable(O outerObservable) {
16+
return new ShallowNesting<O>(outerObservable);
17+
}
18+
19+
@Override
20+
protected O getInnerObservable(O outerObservable) {
21+
return outerObservable;
22+
}
23+
24+
}

test/org/codefx/nesting/AllNestingTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
*/
1111
@RunWith(Suite.class)
1212
@SuiteClasses({
13-
AllNestedPropertyTests.class,
14-
DeepNestingTest.class,
13+
AllNestedPropertyTests.class,
14+
DeepNestingTest.class,
15+
ShallowNestingTest.class,
1516
})
1617
public class AllNestingTests {
1718
// no body needed

0 commit comments

Comments
 (0)