001 /** 002 * This is part of the Problem Set 0: Introduction for CSE331 003 */ 004 package ps0.test; 005 import ps0.*; 006 007 import java.util.Iterator; 008 import java.util.LinkedList; 009 import java.util.Random; 010 import java.util.Set; 011 import java.util.HashSet; 012 013 import junit.framework.TestCase; 014 015 /** 016 * BoxTest is a glassbox test of the Box class. 017 * 018 * Recall that like a BallContainer, the Box is a container for Balls and you 019 * can only put a Ball into a Box once. After you put the Ball into 020 * the Box, further attempts to do so will fail, since the Ball is 021 * already in the Box! Similarly, you cannot expect to remove a Ball 022 * from a Box if it is not inside the Box. 023 * 024 * In addition, a Box differs from a ballcontainer because it only has a finite 025 * volume. As Balls get put into a Box, it gets filled up. Once a Box 026 * is full, further attempts to put Balls into the Box will also fail. 027 * 028 * @see ps0.Ball 029 * @see ps0.BallContainer 030 * @see ps0.Box 031 */ 032 public class BoxTest extends TestCase { 033 034 private Box box = null; 035 private int NUM_BALLS_TO_TEST = 5; 036 private int BOX_CAPACITY = NUM_BALLS_TO_TEST - 1; 037 private Ball[] b = null; 038 private double BALL_UNIT_VOLUME = 10.0; 039 private double JUNIT_DOUBLE_DELTA = 0.0001; 040 private int TRIES_FOR_BALLS_TEST = 3; 041 042 protected void setUp() throws Exception { 043 assertEquals("Test case error, you must test at least 1 Ball!!", true, 044 NUM_BALLS_TO_TEST > 0); 045 assertEquals("This test case is set up assuming that the box cannot contain all the balls, please check and change parameters!", 046 true, NUM_BALLS_TO_TEST > BOX_CAPACITY); 047 048 double box_volume = 0; 049 050 // Let's create the balls we need. 051 b = new Ball[NUM_BALLS_TO_TEST]; 052 for (int i=0; i<NUM_BALLS_TO_TEST; i++) { 053 if (i<BOX_CAPACITY) { 054 box_volume += (i+1)*BALL_UNIT_VOLUME; 055 } 056 b[i] = new Ball((i+1)*BALL_UNIT_VOLUME); 057 } 058 059 // Now, we create the box once we figure out how big a box we 060 // need. 061 box = new Box(box_volume); 062 063 } 064 065 /** Test to check that Box.add(Ball) is implemented correctly */ 066 public void testAdd() { 067 box.clear(); 068 for (int i=0; i<BOX_CAPACITY; i++) { 069 assertEquals("Box.add(Ball) failed to add a new Ball!", 070 true, box.add(b[i])); 071 assertEquals("Box.add(Ball) seems to allow the same Ball to be added twice!", 072 false, box.add(b[i])); 073 assertEquals("Box does not contain a ball after it is supposed to have been added!", 074 true, box.contains(b[i])); 075 } 076 for (int i=BOX_CAPACITY; i<NUM_BALLS_TO_TEST; i++) { 077 assertEquals("Box.add(Ball) allows a Ball to be added even though it is already full!", 078 false, box.add(b[i])); 079 } 080 } 081 082 /** Test to check that Box.getBallsFromSmallest() is implemented correctly */ 083 public void testGetBalls() { 084 Random rnd = new Random(); 085 086 for (int k=0; k<TRIES_FOR_BALLS_TEST; k++) { 087 088 box.clear(); 089 090 // Let's put all the balls into a list. 091 LinkedList<Ball> list = new LinkedList<Ball>(); 092 for (int i=0; i<BOX_CAPACITY; i++) { 093 list.add(b[i]); 094 } 095 096 // First we add the balls to the box in some random order. 097 for (int i=0; i<BOX_CAPACITY; i++) { 098 box.add(list.remove(rnd.nextInt(list.size()))); 099 } 100 101 int contentsSize = box.size(); 102 // Next we call the iterator and check that the balls come out 103 // in the correct order. 104 Iterator<Ball> it = box.getBallsFromSmallest(); 105 int count = 0; 106 while (it.hasNext() && count < BOX_CAPACITY) { 107 Ball ball = it.next(); 108 assertEquals("Balls are not returned by Box.getBallsFromSmallest() iterator in the correct order", 109 true, b[count] == ball); 110 if (b[count] != ball) { 111 break; 112 } 113 count++; 114 } 115 assertEquals("Box.getBallsFromSmallest() did not return all the balls", 116 BOX_CAPACITY, count); 117 assertEquals("Number of balls in box was modified", 118 contentsSize, box.size()); 119 } 120 121 } 122 123 /** 124 * Test to check that Box.remove(Ball) is implemented 125 * correctly. Depending on how <code>getBallsFromSmallest()</code> 126 * is implemented, remove() might have to be overridden and this 127 * test helps ensure that remove() is not broken in the process. 128 */ 129 public void testRemove() { 130 box.clear(); 131 assertEquals("Box.remove(Ball) should fail because box is empty, but it didn't!", 132 false, box.remove(b[0])); 133 for (int i=0; i<BOX_CAPACITY; i++) { 134 box.clear(); 135 for (int j=0; j<i; j++) { 136 box.add(b[j]); 137 } 138 for (int j=0; j<i; j++) { 139 assertEquals("Box.remove(Ball) failed to remove a Ball that is supposed to be inside", 140 true, box.remove(b[j])); 141 assertEquals("Box still contains a ball after it is supposed to have been removed!", 142 false, box.contains(b[j])); 143 } 144 for (int j=i; j<NUM_BALLS_TO_TEST; j++) { 145 assertEquals("Box.remove(Ball) did not fail for a Ball that is not inside", 146 false, box.remove(b[j])); 147 } 148 } 149 } 150 151 152 /** Test to check that Box.clear() is implemented correctly */ 153 public void testClear() { 154 box.clear(); 155 assertEquals("Box is not empty after being cleared!", 0, box.size()); 156 box.add(b[0]); 157 box.clear(); 158 assertEquals("Box is not empty after being cleared!", 0, box.size()); 159 } 160 161 /** Test to check that check that we can put a Ball into a Box */ 162 public void testVolume() { 163 box.clear(); 164 assertEquals("Volume of empty Box is not zero!", 165 0, box.getVolume(), JUNIT_DOUBLE_DELTA); 166 for (int i=0; i<BOX_CAPACITY; i++) { 167 box.add(b[i]); 168 assertEquals("Volume of Box with one ball is supposed to be " + 169 ((i+1)*(i+2)*BALL_UNIT_VOLUME/2)+" but it's " + 170 box.getVolume()+" instead", 171 (i+1)*(i+2)*BALL_UNIT_VOLUME/2, box.getVolume(), 172 JUNIT_DOUBLE_DELTA); 173 } 174 } 175 176 /** Test to check that size() returns the correct number. */ 177 public void testSize() { 178 box.clear(); 179 assertEquals("size() of empty Box is not zero!", 0, box.size()); 180 for (int i=0; i<BOX_CAPACITY; i++) { 181 box.add(b[i]); 182 assertEquals("size() of Box with "+(i+1)+" ball(s) is supposed to be "+ 183 (i+1)+" but it's " +box.size()+" instead", 184 i+1, box.size()); 185 } 186 } 187 188 /** Test to check that size() returns the correct number. */ 189 public void testContains() { 190 box.clear(); 191 for (int i=0; i<BOX_CAPACITY; i++) { 192 assertEquals("Empty Box seems to contain a ball!", 193 false, box.contains(b[i])); 194 } 195 for (int i=0; i<BOX_CAPACITY; i++) { 196 box.add(b[i]); 197 assertEquals("Box does not contain a Ball that is supposed to be inside!", 198 true, box.contains(b[i])); 199 for (int j=i+1; j<BOX_CAPACITY; j++) { 200 assertEquals("Box seems to contain a Ball that is not inside!", 201 false, box.contains(b[j])); 202 } 203 } 204 } 205 206 /** 207 * Test to check that iterator() is implemented correctly. 208 */ 209 public void testIterator() { 210 Set<Ball> allBalls = new HashSet<Ball>(); 211 Set<Ball> seenBalls = new HashSet<Ball>(); 212 box.clear(); 213 for (Ball aBall : b) { 214 box.add(aBall); 215 allBalls.add(aBall); 216 } 217 int i = 0; 218 for (Ball aBall : box) { 219 assertTrue("Iterator returned a ball which isn't in the container", 220 allBalls.contains(aBall)); 221 assertFalse("Iterator returned the same ball twice", seenBalls 222 .contains(aBall)); 223 seenBalls.add(aBall); 224 i++; 225 } 226 assertEquals("BallContainer iterator did not return enough items!", 227 b.length -1, i); 228 } 229 }