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