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