001: package jimm.datavision.test;
002:
003: import jimm.datavision.*;
004: import jimm.datavision.source.Column;
005: import jimm.datavision.source.Query;
006: import jimm.datavision.test.mock.source.MockDataSource;
007: import java.io.*;
008: import java.util.HashMap;
009: import java.util.Iterator;
010: import junit.framework.TestCase;
011: import junit.framework.TestSuite;
012: import junit.framework.Test;
013:
014: public class FormulaTest extends TestCase {
015:
016: protected static final File EXAMPLE_REPORT = new File(AllTests
017: .testDataFile("test.xml"));
018:
019: protected Report report;
020:
021: public static Test suite() {
022: return new TestSuite(FormulaTest.class);
023: }
024:
025: public FormulaTest(String name) {
026: super (name);
027: }
028:
029: public void setUp() {
030: report = new Report();
031: report.setDataSource(new MockDataSource(report));
032: }
033:
034: public void testSingleTokens() throws IOException {
035: HashMap testVals = new HashMap();
036: Long theAnswer = new Long(42);
037: testVals.put("42", theAnswer);
038: testVals.put(" 42", theAnswer);
039: testVals.put("42 ", theAnswer);
040: testVals.put(" 42 ", theAnswer);
041: testVals.put(" \t 42 \t", theAnswer);
042: testVals.put("66.6", new Double(66.6));
043: testVals.put("\"foo\"", "foo");
044: testVals.put("\"don't forget apostrophes\"",
045: "don't forget apostrophes");
046: testVals.put("\"or \\\"quoted quotes\\\" either\"",
047: "or \"quoted quotes\" either");
048:
049: runTests(testVals);
050: }
051:
052: public void testExpressions() throws IOException {
053: HashMap testVals = new HashMap();
054: Long theAnswer = new Long(42);
055: Double theAnswerAsDouble = new Double(42);
056: String theAnswerAsString = "42";
057: Long aBoringAnswer = new Long(36);
058:
059: testVals.put("39 + 3", theAnswer);
060: testVals.put(" 39 + 3 ", theAnswer);
061: testVals.put(" 39\t+ 3", theAnswer);
062: testVals.put(" 39 +\t3", theAnswer);
063: testVals.put("39 + 3", theAnswer);
064: testVals.put("45 - 3", theAnswer);
065: testVals.put("21 * 2", theAnswer);
066: testVals.put("84.00 / 2.0", theAnswerAsDouble);
067: testVals.put(" \"foo\" + \"bar\"", "foobar");
068: testVals.put("\"foo\" * 3", "foofoofoo");
069: testVals.put("\"foo\" * 3.5", "foofoofoo");
070: testVals.put("\"foo\" * 3.5.to_i", "foofoofoo");
071: testVals.put("42.3343.floor", theAnswer);
072: testVals.put("42.3343.round", theAnswer);
073: testVals.put("41.3343.ceil", theAnswer);
074: testVals.put("6 ** 2", aBoringAnswer);
075: testVals.put("[42, 36].max", theAnswer);
076: testVals.put("[36, 42].max", theAnswer);
077: testVals.put("[42, 36].min", aBoringAnswer);
078: testVals.put("[36, 42].min", aBoringAnswer);
079: testVals.put("42.abs", theAnswer);
080: testVals.put("-42.abs", theAnswer);
081: testVals.put("str='45';str.gsub!(/5/,'2');str.to_i", theAnswer);
082: testVals.put("Math.sqrt(1764)", theAnswerAsDouble);
083: testVals.put("Math.sqrt(Math.sqrt(1764) ** 2)",
084: theAnswerAsDouble);
085:
086: testVals.put("'42abc'[0, 2]", theAnswerAsString);
087:
088: runTests(testVals);
089: }
090:
091: public void testDisplay() throws Exception {
092: report.read(EXAMPLE_REPORT);
093:
094: Formula f = report.findFormula(new Long(1));
095: assertNotNull(f);
096:
097: assertEquals(
098: "{jobs.hourly rate}.nil? ? nil : {jobs.hourly rate} / 100.0",
099: f.getEditableExpression());
100:
101: f.setExpression("{?1}");
102: assertEquals("{?1}", f.getExpression());
103: assertEquals("{?String Param}", f.getEditableExpression());
104:
105: f.setEditableExpression("{?String Param}");
106: assertEquals("{?1}", f.getExpression());
107: assertEquals("{?String Param}", f.getEditableExpression());
108:
109: f.setEditableExpression("{!Short Title}");
110: assertEquals("{!1}", f.getExpression());
111: assertEquals("{!Short Title}", f.getEditableExpression());
112: }
113:
114: public void runTests(HashMap testVals) throws IOException {
115: Formula f = new Formula(null, report, "Unnamed Formula");
116: for (Iterator iter = testVals.keySet().iterator(); iter
117: .hasNext();) {
118: String evalStr = (String) iter.next();
119: Object answer = testVals.get(evalStr);
120:
121: f.setExpression(evalStr);
122: Object calculated = f.eval();
123: assertEquals(answer, calculated);
124: assertEquals(answer.getClass(), calculated.getClass());
125: }
126: }
127:
128: public void testContainsColumns() throws Exception {
129: report.read(EXAMPLE_REPORT);
130:
131: UserColumn uc = report.findUserColumn(new Long(1));
132: assertNotNull(uc);
133:
134: // Pick any formula that has a formula field in the report. Change
135: // the formula's expression to be the user column.
136: Formula f = report.findFormula(new Long(2));
137: assertNotNull(f);
138: f.setExpression(uc.formulaString());
139:
140: // If a formula contains a user column and the user column isn't used
141: // in any report field (but the formula is), prove that the query will
142: // contain the user column.
143: Query q = (Query) report.getDataSource().getQuery();
144: q.findSelectablesUsed();
145: assertTrue("user col contained in formula isn't in query", q
146: .indexOfSelectable(uc) >= 0);
147:
148: // Now make the formula's expression a Ruby expression that "hides" a
149: // column that isn't otherwise in the report. By "hide" I mean that a
150: // simple search for "{" won't work; the formula will have to use its
151: // "exceptAfter" ivar to ignore the "#{" Ruby expession start.
152: f.setExpression("#{{aggregate_test.col1}}");
153: Column col = report.findColumn("aggregate_test.col1");
154: assertNotNull(col);
155: q.findSelectablesUsed();
156: assertTrue(
157: "col contained in Ruby string expression isn't in query",
158: q.indexOfSelectable(col) >= 0);
159: }
160:
161: public void testIgnoreNonColumns() {
162: Formula f = new Formula(new Long(0), report,
163: "ignore non-columns");
164: try {
165: f.setEditableExpression("x = 42");
166: f.eval(null);
167:
168: f.setEditableExpression("x = {}; x[:z] = 42");
169: f.eval(null);
170:
171: f.setEditableExpression("x = { }; x[:z] = 42");
172: f.eval(null);
173: } catch (Exception e) {
174: fail(e.toString());
175: }
176: }
177:
178: public static void main(String[] args) {
179: junit.textui.TestRunner.run(suite());
180: System.exit(0);
181: }
182:
183: }
|