1616
1717package gr .geompokon .bitarray ;
1818
19- import org .junit .jupiter .api .BeforeEach ;
20- import org .junit .jupiter .api .DisplayName ;
19+ import org .junit .jupiter .api .*;
2120import org .junit .jupiter .params .ParameterizedTest ;
21+ import org .junit .jupiter .params .provider .MethodSource ;
2222import org .junit .jupiter .params .provider .ValueSource ;
2323
24- import java .util .ArrayList ;
24+ import java .util .List ;
2525import java .util .Random ;
2626import java .util .UnknownFormatConversionException ;
27+ import java .util .stream .Collectors ;
28+ import java .util .stream .Stream ;
2729
28- import static org .junit . jupiter .api .Assertions .assertEquals ;
29- import static org .junit . jupiter .api .Assertions .fail ;
30+ import static org .assertj . core .api .Assertions .assertThat ;
31+ import static org .assertj . core .api .Assertions .assertThatThrownBy ;
3032
33+ @ DisplayName ("BitArray Unit Tests" )
3134class BitArrayTest {
3235
3336 static BitArray bitArray ;
34- static ArrayList <Boolean > boolArray ;
35- static Random random ;
3637
37- /**
38- * Start each test with a fresh array
39- */
38+ static final int SEED = 101 ;
39+ static final Random consistentRandom = new Random ( SEED );
40+
4041 @ BeforeEach
4142 void setUp () {
4243 bitArray = new BitArray ();
43- boolArray = new ArrayList <>();
44- random = new Random ();
4544 }
4645
47- /**
48- * Clears both arrays and adds the same {@code noOfElements} random booleans to both. That is, a call to
49- * boolArray.equals(bitArray) is always successful afterwards
50- *
51- * @param noOfElements number of random booleans to be added
52- */
53- void initArrays (int noOfElements ) {
54- bitArray .clear ();
55- boolArray .clear ();
56- for (int i = 0 ; i < noOfElements ; i ++) {
57- boolean element = random .nextBoolean ();
58- bitArray .add (element );
59- boolArray .add (element );
46+
47+ @ Nested
48+ @ DisplayName ("Copy tests" )
49+ @ TestInstance (TestInstance .Lifecycle .PER_CLASS )
50+ class CopyTests {
51+
52+ @ ParameterizedTest (name = "{0} elements" )
53+ @ DisplayName ("Result of copy constructor should have the same elements" )
54+ @ MethodSource ("gr.geompokon.bitarray.BitArrayTest#testCaseBooleans" )
55+ void copy_constructor_returns_identical_list (List <Boolean > elementsToAdd ) {
56+ // given
57+ bitArray .addAll (elementsToAdd );
58+
59+ // when
60+ BitArray copy = new BitArray (bitArray );
61+
62+ // then
63+ assertThat (copy ).isEqualTo (bitArray );
6064 }
61- }
6265
63- /**
64- * Asserts that the two lists have the same exact contents
65- */
66- void myAssertSameArrays () {
67- for (int i = 0 ; i < boolArray .size (); i ++) {
68- assertEquals (boolArray .get (i ), bitArray .get (i ));
66+ @ ParameterizedTest (name = "{0} elements" )
67+ @ DisplayName ("Result of copy constructor should be a separate object" )
68+ @ MethodSource ("gr.geompokon.bitarray.BitArrayTest#testCaseBooleans" )
69+ void copy_constructor_returns_new_Object (List <Boolean > elementsToAdd ) {
70+ // given
71+ bitArray .addAll (elementsToAdd );
72+
73+ // when
74+ BitArray copy = new BitArray (bitArray );
75+
76+ // then
77+ assertThat (copy == bitArray ).isFalse ();
6978 }
70- }
7179
72- /**
73- * Make the bit array from the boolean array
74- */
75- @ ParameterizedTest
76- @ ValueSource (ints = {0 , 1 , 5 , 10 , 50 , 100 })
77- @ DisplayName ("Copy constructor result should have same size and elements" )
78- void testCopyConstructor (int elementsToAdd ) {
79- initArrays (elementsToAdd );
80- bitArray = new BitArray (boolArray );
81-
82- myAssertSameArrays ();
83- }
8480
85- @ ParameterizedTest
86- @ ValueSource (ints = {0 , 1 , 5 , 10 , 50 , 100 })
87- @ DisplayName ("Result of clone() should have the same elements" )
88- void testClone (int elementsToAdd ) {
89- initArrays (elementsToAdd );
90- BitArray clone = bitArray .clone ();
81+ @ ParameterizedTest (name = "{0} elements" )
82+ @ DisplayName ("Result of clone() should have the same elements" )
83+ @ MethodSource ("gr.geompokon.bitarray.BitArrayTest#testCaseBooleans" )
84+ void clone_returns_identical_list (List <Boolean > elementsToAdd ) {
85+ // given
86+ bitArray .addAll (elementsToAdd );
87+
88+ // when
89+ BitArray copy = bitArray .clone ();
9190
92- assertEquals (bitArray , clone );
91+ // then
92+ assertThat (copy ).isEqualTo (bitArray );
93+ }
94+
95+
96+ @ ParameterizedTest (name = "{0} elements" )
97+ @ DisplayName ("Result of clone should be a separate object" )
98+ @ MethodSource ("gr.geompokon.bitarray.BitArrayTest#testCaseBooleans" )
99+ void clone_returns_new_Object (List <Boolean > elementsToAdd ) {
100+ // given
101+ bitArray .addAll (elementsToAdd );
102+
103+ // when
104+ BitArray copy = bitArray .clone ();
105+
106+ // then
107+ assertThat (copy == bitArray ).isFalse ();
108+ }
93109 }
94110
95111
96- @ ParameterizedTest
97- @ ValueSource (ints = {0 , 1 , 5 , 10 , 50 , 100 })
98- @ DisplayName ("Serialized and immediately deserialized array should be the same as original" )
99- void testToFromString (int elementsToAdd ) {
100- // test array with elements
101- initArrays (elementsToAdd );
102- BitArray copy = BitArray .fromString (bitArray .toString ());
112+ @ Nested
113+ @ DisplayName ("Serialization Tests" )
114+ @ TestInstance (TestInstance .Lifecycle .PER_CLASS )
115+ class SerializationTests {
116+
117+ @ ParameterizedTest (name = "{0} elements" )
118+ @ DisplayName ("Serialized and immediately deserialized array should be the same as original" )
119+ @ MethodSource ("gr.geompokon.bitarray.BitArrayTest#testCaseBooleans" )
120+ void toString_and_fromString_do_not_alter_content (List <Boolean > elementsToAdd ) {
121+ // given
122+ bitArray .addAll (elementsToAdd );
103123
104- assertEquals (bitArray , copy );
124+ // when
125+ String serialized = bitArray .toString ();
126+ BitArray deserialized = BitArray .fromString (serialized );
127+
128+ // then
129+ assertThat (deserialized ).isEqualTo (bitArray );
130+ }
131+
132+ @ ParameterizedTest
133+ @ ValueSource (strings = {"[0 1]" , "Size = 2, [true true]" , "Size =z, [0 1]" , "Size = 3, [0 1]" })
134+ @ DisplayName ("Bad strings should throw specific exceptions" )
135+ void fromString_throws_on_bad_string (String faultyString ) {
136+ // when/then
137+ assertThatThrownBy (() -> {
138+ BitArray impossibleList = BitArray .fromString (faultyString );
139+ System .out .println (impossibleList );
140+ impossibleList .add (Boolean .FALSE );
141+ }).isInstanceOf (UnknownFormatConversionException .class );
142+ }
105143 }
106144
107- @ ParameterizedTest
108- @ ValueSource (strings = {"[0 1]" , "Size = 2, [true true]" , "Size =z, [0 1]" , "Size = 3, [0 1]" })
109- @ DisplayName ("Bad strings should throw specific exceptions" )
110- void testBadFromString (String faultyString ) {
111- try {
112- BitArray .fromString (faultyString );
113- } catch (Exception e ) {
114- if (!(e instanceof UnknownFormatConversionException
115- || e instanceof IndexOutOfBoundsException
116- || e instanceof NumberFormatException )) {
117- fail (e );
118- }
145+
146+ static Stream <Named <List <Boolean >>> testCaseBooleans () {
147+ synchronized (consistentRandom ) {
148+ consistentRandom .setSeed (SEED );
149+ return Stream .of (
150+ Named .of ("0" , List .of ()),
151+ Named .of ("1" , List .of (Boolean .FALSE )),
152+ Named .of ("2" , List .of (Boolean .TRUE , Boolean .FALSE )),
153+ Named .of ("5" , List .of (Boolean .TRUE , Boolean .FALSE , Boolean .FALSE , Boolean .TRUE , Boolean .TRUE )),
154+ Named .of ("100" , Stream .generate (consistentRandom ::nextBoolean ).limit (100 ).collect (Collectors .toList ()))
155+ );
119156 }
120157 }
121158}
0 commit comments