001: /*
002: * $Id: TestDatePartFunction.java,v 1.7 2005/03/03 02:22:00 ahimanikya Exp $
003: * =======================================================================
004: * Copyright (c) 2004 Axion Development Team. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above
011: * copyright notice, this list of conditions and the following
012: * disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The names "Tigris", "Axion", nor the names of its contributors may
020: * not be used to endorse or promote products derived from this
021: * software without specific prior written permission.
022: *
023: * 4. Products derived from this software may not be called "Axion", nor
024: * may "Tigris" or "Axion" appear in their names without specific prior
025: * written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
030: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
032: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
033: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
034: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
035: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
037: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038: * =======================================================================
039: */
040:
041: package org.axiondb.functions;
042:
043: import java.sql.Timestamp;
044: import java.text.DateFormatSymbols;
045: import java.util.HashMap;
046:
047: import junit.framework.Test;
048: import junit.framework.TestSuite;
049:
050: import org.axiondb.AxionException;
051: import org.axiondb.ColumnIdentifier;
052: import org.axiondb.Literal;
053: import org.axiondb.RowDecorator;
054: import org.axiondb.engine.rows.SimpleRow;
055: import org.axiondb.types.TimestampType;
056:
057: /**
058: * Unit tests for DatePart function.
059: *
060: * @version $Revision: 1.7 $ $Date: 2005/03/03 02:22:00 $
061: * @author Jonathan Giron
062: */
063: public class TestDatePartFunction extends BaseFunctionTest {
064:
065: public TestDatePartFunction(String testName) {
066: super (testName);
067: }
068:
069: public void setUp() throws Exception {
070: super .setUp();
071: TimestampType.setTimeZone("GMT");
072: }
073:
074: /* (non-Javadoc)
075: * @see org.axiondb.functions.BaseFunctionTest#makeFunction()
076: */
077: protected ConcreteFunction makeFunction() {
078: return new DatePartFunction();
079: }
080:
081: public static Test suite() {
082: TestSuite suite = new TestSuite(TestDatePartFunction.class);
083: return suite;
084: }
085:
086: public void testValidDateParts() throws Exception {
087: DatePartFunction function = new DatePartFunction();
088: ColumnIdentifier datePartLbl = new ColumnIdentifier(
089: "datePartLbl");
090: ColumnIdentifier timestampLbl = new ColumnIdentifier(
091: "timestampLbl");
092:
093: function.addArgument(datePartLbl);
094: function.addArgument(timestampLbl);
095:
096: HashMap map = new HashMap();
097: map.put(datePartLbl, new Integer(0));
098: map.put(timestampLbl, new Integer(1));
099:
100: // Sample time: 2004-04-01 20:30:58.450Z
101: TimestampType.setTimeZone("GMT");
102: final Timestamp input = new Timestamp(34L * 365L * 24L * 60L
103: * 60L * 1000L //year
104: + 9L * 24L * 60L * 60L * 1000L + // leap years
105: // '72,'76,'80,'84,'88,'92,'96, 2000,
106: // 2004
107: +(31L + 28L + 31L) * 24L * 60L * 60L * 1000L // April 01
108: + ((20L * 60L) + 30L) * 60L * 1000L // 8:30 PM
109: + 58 * 1000L // 58 seconds
110: + 450L // 450 milliseconds
111: );
112:
113: final Timestamp inputAm = new Timestamp(34L * 365L * 24L * 60L
114: * 60L * 1000L //year
115: + 9L * 24L * 60L * 60L * 1000L + // leap years
116: // '72,'76,'80,'84,'88,'92,'96, 2000,
117: // 2004
118: +(31L + 28L + 31L) * 24L * 60L * 60L * 1000L // April 01
119: + ((8L * 60L) + 30L) * 60L * 1000L // 8:30 AM
120: + 58 * 1000L // 58 seconds
121: + 450L // 450 milliseconds
122: );
123:
124: RowDecorator dec = new RowDecorator(map);
125:
126: // Test year.
127: Literal part = new Literal("YEAR");
128: dec.setRow(new SimpleRow(new Object[] { part, input }));
129: Object returnVal = function.evaluate(dec);
130: assertEquals("Expected valid return for date-part input '"
131: + part.toString() + "'; ", "2004", returnVal);
132:
133: // Test month.
134: part = new Literal("MONTH");
135: dec.setRow(new SimpleRow(new Object[] { part, input }));
136: returnVal = function.evaluate(dec);
137: assertEquals("Expected valid return for date-part input '"
138: + part.toString() + "'; ", "04", returnVal);
139:
140: // Test year.
141: part = new Literal("DAY");
142: dec.setRow(new SimpleRow(new Object[] { part, input }));
143: returnVal = function.evaluate(dec);
144: assertEquals("Expected valid return for date-part input '"
145: + part.toString() + "'; ", "01", returnVal);
146:
147: // Test hour (single- or double-digit, 0-23)
148: part = new Literal("HOUR");
149: dec.setRow(new SimpleRow(new Object[] { part, input }));
150: returnVal = function.evaluate(dec);
151: assertEquals("Expected valid return for date-part input '"
152: + part.toString() + "'; ", "20", returnVal);
153:
154: dec.setRow(new SimpleRow(new Object[] { part, inputAm }));
155: returnVal = function.evaluate(dec);
156: assertEquals("Expected valid return for date-part input '"
157: + part.toString() + "'; ", "8", returnVal);
158:
159: // Test hour (padded double-digit, 01-12)
160: part = new Literal("HOUR12");
161: dec.setRow(new SimpleRow(new Object[] { part, input }));
162: returnVal = function.evaluate(dec);
163: assertEquals("Expected valid return for date-part input '"
164: + part.toString() + "'; ", "08", returnVal);
165:
166: dec.setRow(new SimpleRow(new Object[] { part, inputAm }));
167: returnVal = function.evaluate(dec);
168: assertEquals("Expected valid return for date-part input '"
169: + part.toString() + "'; ", "08", returnVal);
170:
171: // Test hour (padded double-digit, 0-23)
172: part = new Literal("HOUR24");
173: dec.setRow(new SimpleRow(new Object[] { part, input }));
174: returnVal = function.evaluate(dec);
175: assertEquals("Expected valid return for date-part input '"
176: + part.toString() + "'; ", "20", returnVal);
177:
178: dec.setRow(new SimpleRow(new Object[] { part, inputAm }));
179: returnVal = function.evaluate(dec);
180: assertEquals("Expected valid return for date-part input '"
181: + part.toString() + "'; ", "08", returnVal);
182:
183: // Test minute.
184: part = new Literal("MINUTE");
185: dec.setRow(new SimpleRow(new Object[] { part, input }));
186: returnVal = function.evaluate(dec);
187: assertEquals("Expected valid return for date-part input '"
188: + part.toString() + "'; ", "30", returnVal);
189:
190: // Test second.
191: part = new Literal("SECOND");
192: dec.setRow(new SimpleRow(new Object[] { part, input }));
193: returnVal = function.evaluate(dec);
194: assertEquals("Expected valid return for date-part input '"
195: + part.toString() + "'; ", "58", returnVal);
196:
197: // Test millisecond.
198: part = new Literal("MILLISECOND");
199: dec.setRow(new SimpleRow(new Object[] { part, input }));
200: returnVal = function.evaluate(dec);
201: assertEquals("Expected valid return for date-part input '"
202: + part.toString() + "'; ", "450", returnVal);
203:
204: // Test am/pm.
205: part = new Literal("AMPM");
206: dec.setRow(new SimpleRow(new Object[] { part, input }));
207: returnVal = function.evaluate(dec);
208: assertEquals("Expected valid return for date-part input '"
209: + part.toString() + "'; ", "PM", returnVal);
210:
211: // Test quarter.
212: part = new Literal("QUARTER");
213: dec.setRow(new SimpleRow(new Object[] { part, input }));
214: returnVal = function.evaluate(dec);
215: assertEquals("Expected valid return for date-part input '"
216: + part.toString() + "'; ", "2", returnVal);
217:
218: // Test week.
219: part = new Literal("WEEK");
220: dec.setRow(new SimpleRow(new Object[] { part, input }));
221: returnVal = function.evaluate(dec);
222: assertEquals("Expected valid return for date-part input '"
223: + part.toString() + "'; ", "14", returnVal);
224:
225: // Test three-letter month abbreviation.
226: part = new Literal("MONTH3");
227: dec.setRow(new SimpleRow(new Object[] { part, input }));
228: returnVal = function.evaluate(dec);
229: assertEquals("Expected valid return for date-part input '"
230: + part.toString() + "'; ", "APR", returnVal);
231:
232: // Test full month.
233: part = new Literal("MONTHFULL");
234: dec.setRow(new SimpleRow(new Object[] { part, input }));
235: returnVal = function.evaluate(dec);
236: assertEquals("Expected valid return for date-part input '"
237: + part.toString() + "'; ", "APRIL", returnVal);
238:
239: // Test day of week (number).
240: part = new Literal("WEEKDAY");
241: dec.setRow(new SimpleRow(new Object[] { part, input }));
242: returnVal = function.evaluate(dec);
243: assertEquals("Expected valid return for date-part input '"
244: + part.toString() + "'; ", "5", returnVal);
245:
246: // Test three-letter day of week abbreviation
247: part = new Literal("WEEKDAY3");
248: dec.setRow(new SimpleRow(new Object[] { part, input }));
249: returnVal = function.evaluate(dec);
250: assertEquals("Expected valid return for date-part input '"
251: + part.toString() + "'; ", new DateFormatSymbols()
252: .getShortWeekdays()[5].toUpperCase(), returnVal);
253:
254: // Test full day of week.
255: part = new Literal("WEEKDAYFULL");
256: dec.setRow(new SimpleRow(new Object[] { part, input }));
257: returnVal = function.evaluate(dec);
258: assertEquals("Expected valid return for date-part input '"
259: + part.toString() + "'; ", new DateFormatSymbols()
260: .getWeekdays()[5].toUpperCase(), returnVal);
261:
262: }
263:
264: public void testNullTimestampInputYieldsNull() {
265: DatePartFunction function = new DatePartFunction();
266: ColumnIdentifier datePartLbl = new ColumnIdentifier(
267: "datePartLbl");
268: ColumnIdentifier timestampLbl = new ColumnIdentifier(
269: "timestampLbl");
270:
271: function.addArgument(datePartLbl);
272: function.addArgument(timestampLbl);
273:
274: HashMap map = new HashMap();
275: map.put(datePartLbl, new Integer(0));
276: map.put(timestampLbl, new Integer(1));
277:
278: RowDecorator dec = new RowDecorator(map);
279: dec.setRow(new SimpleRow(new Object[] { "DAY", null }));
280: try {
281: assertNull(
282: "Expected null return for DatePart with null for timestamp input.",
283: function.evaluate(dec));
284: } catch (Exception e) {
285: fail("Null for timestamp input of DatePart should not have thrown an Exception: "
286: + e);
287: }
288: }
289:
290: public void testNullDatePartThrowsException() {
291: DatePartFunction function = new DatePartFunction();
292: ColumnIdentifier datePartLbl = new ColumnIdentifier(
293: "datePartLbl");
294: ColumnIdentifier timestampLbl = new ColumnIdentifier(
295: "timestampLbl");
296:
297: function.addArgument(datePartLbl);
298: function.addArgument(timestampLbl);
299:
300: HashMap map = new HashMap();
301: map.put(datePartLbl, new Integer(0));
302: map.put(timestampLbl, new Integer(1));
303:
304: RowDecorator dec = new RowDecorator(map);
305: dec.setRow(new SimpleRow(
306: new Object[] { null, new Timestamp(0) }));
307:
308: try {
309: function.evaluate(dec);
310: fail("Null value for date-part should have thrown an Exception");
311: } catch (AxionException e) {
312: // Desired effect - do nothing.
313: }
314: }
315:
316: public void testInvalidPartIdentThrowsException() {
317: DatePartFunction function = new DatePartFunction();
318: ColumnIdentifier datePartLbl = new ColumnIdentifier(
319: "datePartLbl");
320: ColumnIdentifier timestampLbl = new ColumnIdentifier(
321: "timestampLbl");
322:
323: function.addArgument(datePartLbl);
324: function.addArgument(timestampLbl);
325:
326: HashMap map = new HashMap();
327: map.put(datePartLbl, new Integer(0));
328: map.put(timestampLbl, new Integer(1));
329:
330: RowDecorator dec = new RowDecorator(map);
331:
332: try {
333: dec.setRow(new SimpleRow(new Object[] { "CRAP",
334: new Timestamp(0) }));
335: function.evaluate(dec);
336: fail("Invalid value for date-part should have thrown an Exception");
337: } catch (AxionException e) {
338: // Desired effect - do nothing.
339: }
340:
341: try {
342: dec.setRow(new SimpleRow(new Object[] { "DAY",
343: new Object[] { "string" } }));
344: function.evaluate(dec);
345: fail("Invalid value for date-source should have thrown an Exception");
346: } catch (AxionException e) {
347: // Desired effect - do nothing.
348: }
349:
350: try {
351: dec.setRow(new SimpleRow(new Object[] { "DAY", "string" }));
352: function.evaluate(dec);
353: fail("Invalid value for date-source should have thrown an Exception");
354: } catch (IllegalArgumentException e) {
355: // Desired effect - do nothing.
356: } catch (AxionException e) {
357:
358: }
359:
360: }
361:
362: public void testMakeNewInstance() {
363: DatePartFunction function = new DatePartFunction();
364: assertTrue(function.makeNewInstance() instanceof DatePartFunction);
365: assertTrue(function.makeNewInstance() != function
366: .makeNewInstance());
367: }
368:
369: public void testInvalid() throws Exception {
370: DatePartFunction function = new DatePartFunction();
371: assertTrue(!function.isValid());
372: }
373:
374: public void testValid() throws Exception {
375: DatePartFunction function = new DatePartFunction();
376: function.addArgument(new ColumnIdentifier("foo"));
377: function.addArgument(new ColumnIdentifier("bar"));
378: assertTrue(function.isValid());
379: }
380: }
|