KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jimm > datavision > test > ReportRunTest


1 package jimm.datavision.test;
2 import jimm.datavision.*;
3 import jimm.datavision.field.*;
4 import jimm.datavision.layout.CharSepLE;
5 import jimm.datavision.test.mock.source.MockDataSource;
6 import java.io.*;
7 import java.util.Date JavaDoc;
8 import java.text.DecimalFormat JavaDoc;
9 import java.text.SimpleDateFormat JavaDoc;
10 import junit.framework.TestCase;
11 import junit.framework.TestSuite;
12 import junit.framework.Test;
13
14 /**
15  * Reads a report from an XML file, runs it, and verifies the output. Uses
16  * the {}@link CharSepLE} layout engine to produce a tab-delimited output
17  * file.
18  * <p>
19  * These tests are tightly coupled with the contents of the files
20  * <code>test.xml</code> and <code>test_parameters.xml</code> and the data
21  * generated by the {@link MockDataSource}.
22  *
23  * @author Jim Menard, <a HREF="mailto:jimm@io.com">jimm@io.com</a>
24  */

25 public class ReportRunTest extends TestCase {
26
27 protected static final File EXAMPLE_REPORT =
28     new File(AllTests.testDataFile("test.xml"));
29 protected static final File PARAM_INPUT_FILE =
30     new File(AllTests.testDataFile("test_parameters.xml"));
31 protected static final File OUT_FILE =
32     new File(System.getProperty("java.io.tmpdir"),
33          "datavision_report_run_test_out.txt");
34 // This must match the format string for the report.date field in
35
// EXAMPLE_REPORT.
36
protected static final String JavaDoc REPORT_DATE_FORMAT = "yyyy-MM-dd";
37 // This must be an alphabetically sorted list of office names from the
38
// offices table.
39
static final String JavaDoc OFFICES[] = {
40     "Chicago", "New Jersey", "New York"
41 };
42 // The value of parameter one, which is at the beginning of the
43
// report header.
44
protected static final String JavaDoc STRING_PARAM_VALUE = "Chicago";
45 // The value of the report.title special field, which appears
46
// in the report header.
47
protected static final String JavaDoc REPORT_TITLE = "Example Report";
48
49 protected Report report;
50 protected DecimalFormat JavaDoc dollarFormatter;
51 protected DecimalFormat JavaDoc lastColFormatter;
52 protected SimpleDateFormat JavaDoc titleDateFormatter;
53 protected int reportRowNumber;
54 protected int officeRowNumber;
55 protected int postDateRowNumber;
56
57 public static Test suite() {
58     return new TestSuite(ReportRunTest.class);
59 }
60
61 public ReportRunTest(String JavaDoc name) {
62     super(name);
63 }
64
65 public void setUp() throws Exception JavaDoc {
66     dollarFormatter = new DecimalFormat JavaDoc("$#,###.00");
67     lastColFormatter = new DecimalFormat JavaDoc("#,###.##");
68     titleDateFormatter = new SimpleDateFormat JavaDoc(REPORT_DATE_FORMAT);
69
70     report = new Report();
71     report.setDataSource(new MockDataSource(report));
72     reportRowNumber = officeRowNumber = postDateRowNumber = 1;
73
74     report.read(EXAMPLE_REPORT);
75
76     if (report.hasParameterFields())
77     report.setParameterXMLInput(PARAM_INPUT_FILE);
78
79     OUT_FILE.deleteOnExit();
80     PrintWriter out = new PrintWriter(new FileWriter(OUT_FILE));
81     report.setLayoutEngine(new CharSepLE(out, '\t'));
82 }
83
84 public void tearDown() {
85     if (OUT_FILE.exists())
86     OUT_FILE.delete();
87 }
88
89 public void testReportRun() throws IOException, FileNotFoundException {
90     // Run report in this thread, not a separate one. Running the
91
// report closes the output stream.
92
report.runReport();
93
94     // Open the output and look for various things.
95
BufferedReader in = new BufferedReader(new FileReader(OUT_FILE));
96
97     expectHeaders(in);
98
99     // Each of the office groups. checkOfficeGroup() returns the total
100
// dollar amount (really the total id number amount, but that is proved
101
// to be the same thing within checkDetailLine()).
102
int total = 0;
103     for (int i = 0; i < OFFICES.length; ++i)
104     total += checkOfficeGroup(in, OFFICES[i]);
105
106     // The grand total.
107
String JavaDoc line = in.readLine();
108     assertNotNull(line);
109     if (line.startsWith("Page "))
110     assertNotNull(line = in.readLine());
111
112     assertEquals("Grand Total:\t" + dollarFormatter.format(total)
113          + "\t" + (reportRowNumber - 1)
114          + "\t" + (reportRowNumber - 1),
115          line);
116
117     // The final page number.
118
assertNotNull(line = in.readLine());
119     assertEquals("Page ", line.substring(0, 5));
120
121     // Make sure we are at the end of the file.
122
assertNull(in.readLine());
123
124     in.close();
125 }
126
127 protected void expectHeaders(BufferedReader in) throws IOException {
128     String JavaDoc line;
129
130     // Line 1: report title and formatted date.
131
// since that will most definitely be different.
132
assertNotNull(line = in.readLine());
133     assertEquals(0, line.indexOf(STRING_PARAM_VALUE + '\t'
134                  + REPORT_TITLE + '\t'
135                  + titleDateFormatter.format(new Date JavaDoc())));
136
137     // Line 2: the page header.
138
assertNotNull(line = in.readLine());
139     assertEquals(0, line.indexOf("Job #\tTitle\tHourly Rate"));
140 }
141
142 /**
143  * Checks a group (header plus detail lines) and returns the total
144  * of the dollar amounts in the group.
145  *
146  * @param in the input reader
147  * @param officeName the group name
148  * @return the total dollar amount in the group
149  */

150 protected int checkOfficeGroup(BufferedReader in, String JavaDoc officeName)
151     throws IOException
152 {
153     String JavaDoc line;
154     int aggregate = 0;
155
156     officeRowNumber = 1;
157
158     // The office name. Skip page delimiters ("Page" at foot and
159
// page headers at top).
160
assertNotNull(line = in.readLine());
161     while (line.startsWith("Page ") || line.startsWith("Job #\t"))
162     assertNotNull(line = in.readLine());
163     assertEquals(officeName, line);
164
165     Object JavaDoc postDateGroupEnd;
166     while ((postDateGroupEnd = checkPostDateGroup(in)) instanceof Integer JavaDoc)
167     aggregate += ((Integer JavaDoc)postDateGroupEnd).intValue();
168     line = (String JavaDoc)postDateGroupEnd;
169
170     assertEquals("Total:\t" + dollarFormatter.format(aggregate)
171          + "\t" + (reportRowNumber - 1)
172          + "\t" + (officeRowNumber - 1),
173          line);
174
175     return aggregate;
176 }
177
178 /**
179  * Checks a subgroup (header plus detail lines) and returns the total
180  * of the dollar amounts in the group. If the next report section is
181  * not a subgroup, it will be a group total line; we return the line
182  *
183  * @param in the input reader
184  * @return either an Integer containing the total or the next line read
185  * from the report
186  */

187 protected Object JavaDoc checkPostDateGroup(BufferedReader in) throws IOException {
188     int aggregate = 0;
189     String JavaDoc line;
190
191     postDateRowNumber = 1;
192
193     // Read either post date or next (super)group name. Return false if we
194
// see a non-date group name; that means we're done. Skip page
195
// delimiters ("Page" at foot and page headers at top).
196
while (true) {
197     assertNotNull(line = in.readLine());
198     if (line.startsWith("Page ") || line.startsWith("Job #\t"))
199         continue;
200     if (line.startsWith("Total:"))
201         return line;
202
203     // Primitive date check
204
assertTrue(Character.isDigit(line.charAt(0)) && line.length() == 10
205            && line.charAt(4) == '-' && line.charAt(7) == '-');
206     break;
207     }
208
209     // The detail lines. Collect the id number from the beginning of each
210
// detail line. It is the same as the dollar amount value. Add that
211
// amount to the aggregate.
212
while (true) {
213     assertNotNull(line = in.readLine());
214     if (line.startsWith("Post Date Total:"))
215         break;
216     if (line.startsWith("Page ") || line.startsWith("Job #\t"))
217         continue;
218
219     aggregate += checkDetailLine(line);
220     }
221
222     assertEquals("Post Date Total:\t" + dollarFormatter.format(aggregate)
223          + "\t" + (reportRowNumber - 1)
224          + "\t" + (postDateRowNumber - 1),
225          line);
226
227     return new Integer JavaDoc(aggregate);
228 }
229
230 /**
231  * Checks the format of a detail line and returns the integer id found
232  * at the beginning of line. This is the same as the dollar amount.
233  *
234  * @param line a detail line
235  * @return the id number
236  */

237 protected int checkDetailLine(String JavaDoc line) {
238     // Read job id from the beginning of the line.
239
int id = Integer.parseInt(line.substring(0, line.indexOf("\t")));
240
241     // The description, at random, may be repeated ("job 3 job 3"). We
242
// check for the first full description.
243
String JavaDoc str = "" + id + "\tThis is the short description of job " + id;
244     assertTrue("line does not start with \"" + str + "\"",
245            line.startsWith(str));
246
247     // Check for the remaining columns at the end of the line. We are also
248
// assuring that the dollar amount is the same as the id number.
249
if (id == 0) {
250     assertEquals("0\tThis is the short description of job 0\t\t\t\t"
251              + reportRowNumber + "\t" + postDateRowNumber,
252              line);
253     }
254     else {
255     str = "\t" + (id * 100)
256         + "\t" + dollarFormatter.format(id)
257         + "\t" + lastColFormatter.format(id)
258         + "\t" + reportRowNumber
259         + "\t" + postDateRowNumber;
260     assertTrue("line \"" + line + "\" does not end with \"" + str,
261            line.endsWith(str));
262     }
263
264     ++reportRowNumber;
265     ++officeRowNumber;
266     ++postDateRowNumber;
267
268     return id;
269 }
270
271 // Performs everything the old testWhereClause() did, so I removed that one.
272
public void testParamInWhereClause() throws IOException, FileNotFoundException
273 {
274     // Set where clause and parameter value file
275
report.getDataSource().getQuery()
276     .setEditableWhereClause("office.name = {?String Param}");
277     report.setParameterXMLInput(PARAM_INPUT_FILE);
278
279     // Run report in this thread, not a separate one. Running the
280
// report closes the output stream.
281
Date JavaDoc now = new Date JavaDoc(); // Get date as near report run time as possible
282
report.runReport();
283
284     // Open the output and look for various things.
285
BufferedReader in = new BufferedReader(new FileReader(OUT_FILE));
286     String JavaDoc line;
287
288     // Line 1. Look for report title and the date (ignore the time,
289
// since that will most definitely be different.
290
assertNotNull(line = in.readLine());
291
292     // There is an infinitessimally small chance the next assertion will
293
// fail even though the report is correct. Imagine the date "now"
294
// retrieved above is created just before midnight. Further imagine
295
// that the report.date special field's value isn't retrieved until
296
// just after midnight. Not terribly likely, but I'm in a CYA mood.
297
assertEquals(0, line.indexOf(STRING_PARAM_VALUE + '\t'
298                  + REPORT_TITLE + '\t'
299                  + titleDateFormatter.format(now)));
300
301     // Line 2: the page header.
302
assertNotNull(line = in.readLine());
303     assertEquals(0, line.indexOf("Job #\tTitle\tHourly Rate"));
304
305     // The single office group we asked for. checkOfficeGroup() returns
306
// the total dollar amount (really the total id number amount, but
307
// that is proved to be be the same thing within checkDetailLine()).
308
int total = checkOfficeGroup(in, STRING_PARAM_VALUE);
309
310     // The grand total.
311
assertNotNull(line = in.readLine());
312     if (line.startsWith("Page "))
313     assertNotNull(line = in.readLine());
314
315     assertEquals("Grand Total:\t" + dollarFormatter.format(total)
316          + "\t" + (reportRowNumber - 1)
317          + "\t" + (reportRowNumber - 1),
318          line);
319
320     in.close();
321 }
322
323 // We used to throw an exception if there were no records returned
324
// by the query but there was a column field in the page header or
325
// report header.
326
public void testNoRecords() {
327     try {
328     // Add a column field to the report header
329
Section pageHeader =
330         report.getFirstSectionByArea(SectionArea.PAGE_HEADER);
331     assertNotNull(pageHeader);
332     ColumnField f = new ColumnField(null, report, pageHeader,
333                     "office.name", true);
334     pageHeader.addField(f);
335
336     // Create a query that returns 0 records
337
report.getDataSource().getQuery().setEditableWhereClause("1 = 2");
338
339     // Run the report. We shouldn't throw an exception.
340
report.runReport();
341     }
342     catch (Exception JavaDoc e) {
343     fail("should not throw an exception just 'cause there are no records");
344     }
345 }
346
347 public void testUseReportValue() throws Exception JavaDoc {
348     Formula f = report.findFormula("1");
349     f.setEditableExpression("val = $report.value('jobs.hourly rate'); val.nil? ? nil : val / 100.0");
350
351     // Run report in this thread, not a separate one. Running the
352
// report closes the output stream.
353
report.runReport();
354
355     // Open the output and look for various things.
356
BufferedReader in = new BufferedReader(new FileReader(OUT_FILE));
357
358     expectHeaders(in);
359
360     // Each of the office groups. checkOfficeGroup() returns the total
361
// dollar amount (really the total id number amount, but that is proved
362
// to be the same thing within checkDetailLine()).
363
int total = 0;
364     for (int i = 0; i < OFFICES.length; ++i)
365     total += checkOfficeGroup(in, OFFICES[i]);
366
367     // The grand total.
368
String JavaDoc line = in.readLine();
369     assertNotNull(line);
370     if (line.startsWith("Page "))
371     assertNotNull(line = in.readLine());
372
373     assertEquals("Grand Total:\t" + dollarFormatter.format(total)
374          + "\t" + (reportRowNumber - 1)
375          + "\t" + (reportRowNumber - 1),
376          line);
377
378     // The final page number.
379
assertNotNull(line = in.readLine());
380     assertEquals("Page ", line.substring(0, 5));
381
382     // Make sure we are at the end of the file.
383
assertNull(in.readLine());
384
385     in.close();
386 }
387
388 public static void main(String JavaDoc[] args) {
389     junit.textui.TestRunner.run(suite());
390     System.exit(0);
391 }
392
393 }
394
Popular Tags