001    package ps1.test;
002    
003    import ps1.*;
004    
005    import junit.framework.*;
006    
007    /**
008     * This class contains a set of test cases that can be used to test the
009     * implementation of the RatPoly class.
010     * <p>
011     */
012    public final class RatTermTest extends TestCase {
013    
014        // Get a RatNum for in an integer
015        private static RatNum num(int i) {
016            return new RatNum(i);
017        }
018    
019        private static RatNum num(int i, int j) {
020            return new RatNum(i, j);
021        }
022    
023        private static final RatNum nanNum = (num(1)).div(num(0));
024    
025        private static final RatTerm nanTerm = new RatTerm(nanNum, 3);
026    
027        // Convenient way to make a RatTerm equals to coeff*x^expt.
028        private static RatTerm term(int coeff, int expt) {
029            return new RatTerm(num(coeff), expt);
030        }
031    
032        // Convenient way to make a RatTerm equals to num/denom*x^expt.
033        private static RatTerm term(int numer, int denom, int expt) {
034            return new RatTerm(num(numer, denom), expt);
035        }
036    
037        public RatTermTest(String name) {
038            super(name);
039        }
040    
041        public void testCtor() {
042            term(1, 0);
043            term(2, 3);
044            term(4, 3, 6);
045            term(-2, 7, 3);
046        }
047    
048        public void testCtorZeroCoeff() {
049            term(0, 0);
050            term(0, 1);
051        }
052    
053        public void testCtorNaN() {
054            term(3, 0, 0);
055        }
056    
057        public void testGetCoeff() {
058            // Simple cases
059            assertTrue(term(3, 1).getCoeff().equals(num(3)));
060            assertTrue(term(2, 5, 2).getCoeff().equals(num(2, 5)));
061    
062            // Check zero
063            assertTrue(term(0, 0).getCoeff().equals(num(0)));
064    
065            // Check negative coeff
066            assertTrue(term(-2, 3, 2).getCoeff().equals(num(-2, 3)));
067    
068            // Check NaN
069            assertTrue(term(3, 0, 4).getCoeff().equals(nanNum));
070        }
071    
072        public void testGetExpt() {
073            // Simple
074            assertTrue(term(2, 4).getExpt() == 4);
075    
076            // Zero always have zero expt
077            assertTrue(term(0, 0).getExpt() == 0);
078            assertTrue(term(0, 1).getExpt() == 0);
079    
080        }
081    
082        public void testIsNaN() {
083            assertTrue(term(5, 0, 0).isNaN());
084    
085            // Check that 0/0*x^4 isNaN instead of zero
086            assertTrue(term(0, 0, 4).isNaN());
087    
088            // Check for false positives
089            assertFalse(term(2, 3, 2).isNaN());
090        }
091    
092        public void testIsZero() {
093            assertTrue(term(0, 0).isZero());
094            assertTrue(term(0, 1).isZero());
095            assertTrue(term(0, 4, 3).isZero());
096            assertTrue(term(0, -2, 2).isZero());
097    
098            // Check for false positives
099            assertFalse(term(1, 3, 0).isZero());
100    
101            // Check that 0/0*x^4 is not zero
102            assertFalse(term(0, 0, 4).isZero());
103        }
104    
105        // The forth argument to assertEquals states to what percision the
106        // values must to the same. Given the idiosyncrasies of Java's
107        // floating point math, it is often impossible to test for
108        // identical results. (These cases are all simple enough that
109        // there should be no issues, however.)
110        public void testEval() {
111            assertEquals(0.0, term(0, 0).eval(5.0), 0.0000001);
112            assertEquals(0.0, term(0, 5).eval(1.2), 0.0000001);
113            assertEquals(2.0, term(2, 0).eval(3.1), 0.0000001);
114            assertEquals(1.0, term(1, 0).eval(100.0), 0.0000001);
115            assertEquals(35.0, term(5, 1).eval(7.0), 0.0000001);
116            assertEquals(12.0, term(3, 2).eval(2.0), 0.0000001);
117            assertEquals(-16.0, term(-2, 3).eval(2.0), 0.0000001);
118            assertEquals(-3.0, term(3, 3).eval(-1.0), 0.0000001);
119            assertEquals(1.0, term(-1, 1).eval(-1.0), 0.0000001);
120            assertEquals(2.0, term(1, 2, 2).eval(2.0), 0.0000001);
121            assertEquals(.125, term(1, 2, 2).eval(.5), 0.0000001);
122            // For some reason it must be written like this. Some thing
123            // seem broken with the way Double.NaN's are compared.
124            assertTrue((new Double(Double.NaN)).equals(new Double(term(3, 0, 2)
125                    .eval(1.0))));
126        }
127    
128        public void testEquals() {
129            assertEquals(term(3, 5), term(3, 5));
130            assertEquals(term(1, 2, 4), term(1, 2, 4));
131            assertEquals(term(-2, 4, 2), term(1, -2, 2));
132            assertFalse(term(4, 6).equals(term(7, 8)));
133        }
134    
135        public void testEqualsZeroCoeff() {
136            assertEquals(term(0, 0), term(0, 0));
137            assertEquals(term(0, 1), term(0, 0));
138            assertFalse(term(0, 0).equals(term(3, 5)));
139        }
140    
141        public void testEqualsNaNCoeff() {
142            assertEquals(nanTerm, term(19, 0, 0));
143            assertEquals(nanTerm, term(0, 0, 0));
144            assertFalse(nanTerm.equals(term(3, 5)));
145            assertFalse(term(0, 3).equals(nanTerm));
146        }
147    
148        // All tests below depend on constructor and equals.
149    
150        // ValueOf tests
151    
152        private void testValueOf(String actual, RatTerm target) {
153            assertEquals(target, RatTerm.valueOf(actual));
154        }
155    
156        public void testValueOfSimple() {
157            testValueOf("x", term(1, 1));
158            testValueOf("-x", term(-1, 1));
159        }
160    
161        public void testValueOfConst() {
162            testValueOf("2", term(2, 0));
163            testValueOf("3/4", term(3, 4, 0));
164            testValueOf("-4", term(-4, 0));
165            testValueOf("-7/5", term(-7, 5, 0));
166        }
167    
168        public void testValueOfLeadingCoeff() {
169            testValueOf("2*x", term(2, 1));
170            testValueOf("3/7*x", term(3, 7, 1));
171            testValueOf("-4/3*x", term(-4, 3, 1));
172        }
173    
174        public void testValueOfPow() {
175            testValueOf("x^3", term(1, 3));
176            testValueOf("-x^4", term(-1, 4));
177        }
178    
179        public void testValueOfFull() {
180            testValueOf("4*x^2", term(4, 2));
181            testValueOf("2/5*x^6", term(2, 5, 6));
182            testValueOf("-3/2*x^2", term(-3, 2, 2));
183        }
184    
185        public void testValueOfNaN() {
186            testValueOf("NaN", term(1, 0, 0));
187        }
188    
189        public void testValueOfZero() {
190            testValueOf("0", term(0, 0));
191        }
192    
193        // toString tests
194    
195        private void testToString(String target, RatTerm actual) {
196            assertEquals(target, actual.toString());
197        }
198    
199        public void testToStringSimple() {
200            testToString("x", term(1, 1));
201            testToString("-x", term(-1, 1));
202        }
203    
204        public void testToStringConst() {
205            testToString("2", term(2, 0));
206            testToString("3/4", term(3, 4, 0));
207            testToString("-4", term(-4, 0));
208            testToString("-7/5", term(-7, 5, 0));
209        }
210    
211        public void testToStringLeadingCoeff() {
212            testToString("2*x", term(2, 1));
213            testToString("3/7*x", term(3, 7, 1));
214            testToString("-4/3*x", term(-4, 3, 1));
215        }
216    
217        public void testToStringPow() {
218            testToString("x^3", term(1, 3));
219            testToString("-x^4", term(-1, 4));
220        }
221    
222        public void testToStringFull() {
223            testToString("4*x^2", term(4, 2));
224            testToString("2/5*x^6", term(2, 5, 6));
225            testToString("-3/2*x^2", term(-3, 2, 2));
226        }
227    
228        public void testToStringNaN() {
229            testToString("NaN", term(1, 0, 0));
230        }
231    
232        public void testToStringZero() {
233            testToString("0", term(0, 0));
234        }
235    
236        // Operation tests
237        // Tests involving NaN and zero are given separately at end
238        public void testAdd() {
239            assertEquals(term(3, 0), term(1, 0).add(term(2, 0)));
240            assertEquals(term(4, 2), term(3, 2).add(term(1, 2)));
241            assertEquals(term(1, 2, 3), term(1, 6, 3).add(term(1, 3, 3)));
242            assertEquals(term(1, 8, 1), term(1, 4, 1).add(term(-1, 8, 1)));
243            assertEquals(term(-1, 8, 1), term(-1, 4, 1).add(term(1, 8, 1)));
244        }
245    
246        public void testSub() {
247            assertEquals(term(1, 0), term(2, 0).sub(term(1, 0)));
248            assertEquals(term(-1, 0), term(1, 0).sub(term(2, 0)));
249            assertEquals(term(2, 2), term(3, 2).sub(term(1, 2)));
250            assertEquals(term(-1, 6, 3), term(1, 6, 3).sub(term(1, 3, 3)));
251            assertEquals(term(3, 8, 1), term(1, 4, 1).sub(term(-1, 8, 1)));
252            assertEquals(term(-3, 8, 1), term(-1, 4, 1).sub(term(1, 8, 1)));
253        }
254    
255        public void testMul() {
256            assertEquals(term(2, 0), term(1, 0).mul(term(2, 0)));
257            assertEquals(term(3, 4), term(3, 2).mul(term(1, 2)));
258            assertEquals(term(1, 18, 6), term(1, 6, 3).mul(term(1, 3, 3)));
259            assertEquals(term(-1, 32, 2), term(1, 4, 1).mul(term(-1, 8, 1)));
260            assertEquals(term(2, 1), term(2, 1).mul(term(1, 0)));
261        }
262    
263        public void testDiv() {
264            assertEquals(term(1, 2, 0), term(1, 0).div(term(2, 0)));
265            assertEquals(term(3, 0), term(3, 2).div(term(1, 2)));
266            assertEquals(term(1, 2, 0), term(1, 6, 3).div(term(1, 3, 3)));
267            assertEquals(term(-2, 0), term(1, 4, 1).div(term(-1, 8, 1)));
268            assertEquals(term(2, 1), term(2, 1).div(term(1, 0)));
269            assertEquals(term(8, 3), term(-16, 5).div(term(-2, 2)));
270        }
271    
272        public void testOperationsOnNaN() {
273            assertEquals(nanTerm, nanTerm.add(term(3, 4)));
274            assertEquals(nanTerm, term(3, 4).add(nanTerm));
275            assertEquals(nanTerm, nanTerm.sub(term(3, 4)));
276            assertEquals(nanTerm, term(3, 4).sub(nanTerm));
277            assertEquals(nanTerm, nanTerm.mul(term(3, 4)));
278            assertEquals(nanTerm, term(3, 4).mul(nanTerm));
279            assertEquals(nanTerm, nanTerm.div(term(3, 4)));
280            assertEquals(nanTerm, term(3, 4).div(nanTerm));
281        }
282    
283        public void testOperationsOnZero() {
284            RatTerm t = term(-2, 3);
285            RatTerm zero = term(0, 0);
286            assertEquals(t, zero.add(t));
287            assertEquals(t, t.add(zero));
288            assertEquals(term(2, 3), zero.sub(t));
289            assertEquals(t, t.sub(zero));
290            assertEquals(zero, zero.mul(t));
291            assertEquals(zero, t.mul(zero));
292            assertEquals(zero, zero.div(t));
293            assertEquals(nanTerm, t.div(zero));
294            assertEquals(0, t.sub(t).getExpt());
295        }
296    
297        // add and sub should disallow non-zero arguments that differ in
298        // exponent.
299        public void testDifferentExptArgs() {
300            assertTrue(addDifferentExpts(term(1, 2), term(1, 4)));
301            assertTrue(addDifferentExpts(term(3, 2, 0), term(7, 3, 1)));
302            assertTrue(subDifferentExpts(term(1, 2), term(1, 4)));
303            assertTrue(subDifferentExpts(term(3, 2, 0), term(7, 3, 1)));
304        }
305    
306        public boolean addDifferentExpts(RatTerm arg1, RatTerm arg2) {
307            try {
308                arg1.add(arg2);
309                // Should not have reached this line:
310                // cannot allow adding non-zero RatTerms of different exponents
311                return false;
312            } catch (IllegalArgumentException e) {
313                return true;
314            }
315        }
316    
317        public boolean subDifferentExpts(RatTerm arg1, RatTerm arg2) {
318            try {
319                arg1.sub(arg2);
320                // Should not have reached this line:
321                // cannot allow adding non-zero RatTerms of different exponents
322                return false;
323            } catch (IllegalArgumentException e) {
324                return true;
325            }
326        }
327    
328        public void testDifferentiate() {
329            assertEquals(term(1, 0), term(1, 1).differentiate());
330            assertEquals(term(0, 0), term(99, 0).differentiate());
331            assertEquals(term(5, 0), term(5, 1).differentiate());
332            assertEquals(term(14, 1), term(7, 2).differentiate());
333            assertEquals(term(-2, 3), term(-1, 2, 4).differentiate());
334            assertEquals(nanTerm, nanTerm.differentiate());
335            assertEquals(nanTerm, (new RatTerm(RatNum.NaN, 0)).differentiate());
336        }
337    
338        public void testAntiDifferentiate() {
339            assertEquals(term(1, 1), term(1, 0).antiDifferentiate());
340            assertEquals(term(1, 2), term(2, 1).antiDifferentiate());
341            assertEquals(term(4, 3, 3), term(4, 2).antiDifferentiate());
342            assertEquals(nanTerm, nanTerm.antiDifferentiate());
343        }
344    
345    }