001    /**
002     * This is part of HW2: Environment Setup and Java Introduction for CSE 331.
003     */
004    package hw2.test;
005    import hw2.*;
006    import java.util.Set;
007    import java.util.HashSet;
008    
009    import org.junit.Test;
010    import org.junit.BeforeClass;
011    import static org.junit.Assert.*;
012    import static org.hamcrest.Matchers.greaterThan;
013    
014    /**
015     * BallContainerTest is a glassbox test of the BallContainer class.
016     *
017     * Recall that the BallContainer is a container for Balls. However, you can only
018     * put a Ball into a BallContainer once. After you put the Ball into the BallContainer,
019     * further attempts to do so will fail, since the Ball is already in
020     * the BallContainer! Similarly, you cannot expect to remove a Ball from a BallContainer
021     * if it is not inside the BallContainer.
022     *
023     * @see hw2.Ball
024     * @see hw2.BallContainer
025     */
026    public class BallContainerTest {
027    
028        private static BallContainer ballcontainer = null;
029        private static Ball[] b = null;
030    
031        private static final int NUM_BALLS_TO_TEST = 3;
032        private static final double BALL_UNIT_VOLUME = 20.0;
033        private static final double JUNIT_DOUBLE_DELTA = 0.0001;
034    
035        @BeforeClass
036        public static void setupForTests() throws Exception {
037            assertThat("Test case error, you must test at least 1 Ball!!", NUM_BALLS_TO_TEST, greaterThan(0));
038            ballcontainer = new BallContainer();
039    
040            // Let's create the balls we need.
041            b = new Ball[NUM_BALLS_TO_TEST];
042            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
043                b[i] = new Ball((i+1)*BALL_UNIT_VOLUME);
044            }
045        }
046    
047    
048        /** Test to check that BallContainer.add(Ball) is implemented correctly */
049        @Test
050        public void testAdd() {
051            double containerVolume;
052            ballcontainer.clear();
053            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
054                assertTrue("BallContainer.add(Ball) failed to add a new Ball!", ballcontainer.add(b[i]));
055                containerVolume = ballcontainer.getVolume();
056                assertFalse("BallContainer.add(Ball) seems to allow the same Ball to be added twice!", ballcontainer.add(b[i]));
057                assertEquals("BallContainer's volume has changed, but its contents have not!",
058                             containerVolume, ballcontainer.getVolume(),
059                             JUNIT_DOUBLE_DELTA);
060                assertTrue("BallContainer does not contain a ball after it is supposed to have been added!",
061                           ballcontainer.contains(b[i]));
062            }
063        }
064    
065        /** Test to check that BallContainer.remove(Ball) is implemented correctly */
066        @Test
067        public void testRemove() {
068            ballcontainer.clear();
069            double containerVolume;
070            assertFalse("BallContainer.remove(Ball) should fail because ballcontainer is empty, but it didn't!", ballcontainer.remove(b[0]));
071            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
072                ballcontainer.clear();
073                for (int j=0; j<i; j++) {
074                    ballcontainer.add(b[j]);
075                }
076                for (int j=0; j<i; j++) {
077                    assertTrue("BallContainer.remove(Ball) failed to remove a Ball that is supposed to be inside",
078                               ballcontainer.remove(b[j]));
079                    containerVolume = ballcontainer.getVolume();
080                    assertFalse("BallContainer still contains a ball after it is supposed to have been removed!",
081                                ballcontainer.contains(b[j]));
082                    assertEquals("BallContainer's volume has changed, but its contents have not!",
083                                 containerVolume, ballcontainer.getVolume(),
084                                 JUNIT_DOUBLE_DELTA);
085                }
086                for (int j=i; j<NUM_BALLS_TO_TEST; j++) {
087                    assertFalse("BallContainer.remove(Ball) did not fail for a Ball that is not inside", ballcontainer.remove(b[j]));
088                }
089            }
090        }
091    
092        /**
093         * Test to check that BallContainer.iterator() is implemented
094         * correctly.
095         */
096        @Test
097        public void testIterator() {
098            Set<Ball> allBalls = new HashSet<Ball>();
099            Set<Ball> seenBalls = new HashSet<Ball>();
100            ballcontainer.clear();
101            assertEquals("BallContainer is not empty after being cleared!",
102                         0, ballcontainer.size());
103            for (Ball aBall: b) {
104                ballcontainer.add(aBall);
105                allBalls.add(aBall);
106            }
107            int i=0;
108            for (Ball aBall: ballcontainer) {
109                assertTrue("Iterator returned a ball that isn't in the container: " + aBall,
110                           allBalls.contains(aBall));
111                assertFalse("Iterator returned the same ball twice: " + aBall,
112                            seenBalls.contains(aBall));
113                seenBalls.add(aBall);
114                i++;
115            }
116            assertEquals("BallContainer iterator did not return enough items!",
117                         i, b.length);
118        }
119    
120        /**
121         * Test that BallContainer.clear() is implemented correctly.
122         */
123        @Test
124        public void testClear() {
125            ballcontainer.clear();
126            assertEquals("BallContainer is not empty after being cleared!",
127                         0, ballcontainer.size());
128            ballcontainer.add(b[0]);
129            ballcontainer.clear();
130            assertEquals("BallContainer is not empty after being cleared!",
131                         0, ballcontainer.size());
132        }
133    
134        /** Test that we can put a Ball into a BallContainer */
135        @Test
136        public void testVolume() {
137            ballcontainer.clear();
138            assertEquals("Volume of empty BallContainer is not zero!",
139                         0, ballcontainer.getVolume(), JUNIT_DOUBLE_DELTA);
140            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
141                ballcontainer.add(b[i]);
142                assertEquals("Volume of BallContainer with "+(i+1)+" ball(s)",
143                             (i+1)*(i+2)*BALL_UNIT_VOLUME/2,
144                             ballcontainer.getVolume(),
145                             JUNIT_DOUBLE_DELTA);
146            }
147    
148        }
149    
150        /** Test that size() returns the correct number. */
151        @Test
152        public void testSize() {
153            ballcontainer.clear();
154            assertEquals("size() of empty BallContainer is not zero!",
155                         0, ballcontainer.size());
156            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
157                ballcontainer.add(b[i]);
158                assertEquals("size() of BallContainer with "+(i+1)+" ball(s)",
159                             i+1, ballcontainer.size());
160            }
161        }
162    
163        /** Test that size() returns the correct number. */
164        @Test
165        public void testContains() {
166            ballcontainer.clear();
167            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
168                assertFalse("Empty BallContainer seems to contain a ball!", ballcontainer.contains(b[i]));
169            }
170            for (int i=0; i<NUM_BALLS_TO_TEST; i++) {
171                ballcontainer.add(b[i]);
172                assertTrue("BallContainer does not contain a Ball that is supposed to be inside!", ballcontainer.contains(b[i]));
173                for (int j=i+1; j<NUM_BALLS_TO_TEST; j++) {
174                    assertFalse("BallContainer seems to contain a Ball that is not inside!", ballcontainer.contains(b[j]));
175                }
176            }
177        }
178    
179        /** Test that clear removes all balls. **/
180        @Test
181        public void testVolumeAfterClear() {
182            ballcontainer.add(b[0]);
183            ballcontainer.clear();
184            assertEquals("The volume of BallContainer after being cleared is not reset to 0!",
185                         0, ballcontainer.getVolume(), JUNIT_DOUBLE_DELTA);
186        }
187    
188    }