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