001package org.hl7.fhir.utilities.ucum.tests;
002
003/*******************************************************************************
004 * Crown Copyright (c) 2006 - 2014, Copyright (c) 2006 - 2014 Kestral Computing & Health Intersections P/L.
005 * All rights reserved. This program and the accompanying materials
006 * are made available under the terms of the Eclipse Public License v1.0
007 * which accompanies this distribution, and is available at
008 * http://www.eclipse.org/legal/epl-v10.html
009 * 
010 * Contributors:
011 *    Kestral Computing P/L - initial implementation
012 *    Health Intersections P/L - port to java, ongoing maintenance
013 *    
014 ******************************************************************************/
015
016import java.io.FileInputStream;
017import java.io.IOException;
018
019import org.hl7.fhir.exceptions.UcumException;
020import org.hl7.fhir.utilities.Utilities;
021import org.hl7.fhir.utilities.ucum.Decimal;
022import org.hl7.fhir.utilities.ucum.Pair;
023import org.hl7.fhir.utilities.ucum.UcumEssenceService;
024import org.hl7.fhir.utilities.ucum.UcumService;
025import org.xmlpull.v1.XmlPullParser;
026import org.xmlpull.v1.XmlPullParserException;
027import org.xmlpull.v1.XmlPullParserFactory;
028
029public class UcumTester {
030
031        /**
032         * @param args
033         * @throws IOException 
034         * @throws XmlPullParserException 
035         * @throws UcumException 
036         * @ 
037         */
038        public static void main(String[] args) throws XmlPullParserException, IOException, UcumException  {
039                if (args.length == 0) {
040                        System.out.println("UCUM Tester - parameters:");
041                        System.out.println("  -definitions [filename] - filename for the UCUM definitions");
042                        System.out.println("  -tests [fileanme] - filename for the UCUM tests");
043                        System.out.println("See http://unitsofmeasure.org/trac/ for source files for both ucum definitions");
044                        System.out.println("(ucum-essence.xml) and tests (http://unitsofmeasure.org/trac/wiki/FunctionalTests)");
045                } else {
046                        UcumTester worker = new UcumTester();
047                        int i = 0;
048                        while (i < args.length) {
049                                String a = args[i];
050                                i++;
051                                if (a.equalsIgnoreCase("-definitions"))
052                                        worker.setDefinitions(args[i]);
053                                else if (a.equalsIgnoreCase("-tests"))
054                                        worker.setTests(args[i]);
055                                else 
056                                        System.out.println("Unknown parameter: '"+a+"'");
057                                i++;
058                        }
059                        worker.execute();
060                }
061        }
062
063        private String definitions;
064        private String tests;
065        public String getDefinitions() {
066                return definitions;
067        }
068        public void setDefinitions(String definitions) {
069                this.definitions = definitions;
070        }
071        public String getTests() {
072                return tests;
073        }
074        public void setTests(String tests) {
075                this.tests = tests;
076        }
077        
078
079        private UcumService ucumSvc;
080        private int errCount;
081        
082        private void execute() throws XmlPullParserException, IOException, UcumException  {
083
084                testDecimal();
085                
086                ucumSvc = new UcumEssenceService(definitions);
087          errCount = 0;
088                XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
089                factory.setNamespaceAware(true);
090                XmlPullParser xpp = factory.newPullParser();
091
092                xpp.setInput(new FileInputStream(tests), null);
093
094                int eventType = xpp.next();
095                if (eventType != XmlPullParser.START_TAG)
096                        throw new XmlPullParserException("Unable to process XML document");
097                if (!xpp.getName().equals("ucumTests")) 
098                        throw new XmlPullParserException("Unable to process XML document: expected 'ucumTests' but found '"+xpp.getName()+"'");
099
100                xpp.next();
101                while (xpp.getEventType() != XmlPullParser.END_TAG) {
102                        if (xpp.getEventType() == XmlPullParser.TEXT) {
103                                if (Utilities.isWhitespace(xpp.getText()))
104                                        xpp.next();
105                                else
106                                        throw new XmlPullParserException("Unexpected text "+xpp.getText());
107                        } else if (xpp.getName().equals("history")) 
108                                skipElement(xpp);
109                        else if (xpp.getName().equals("validation")) 
110                                runValidationTests(xpp);
111                        else if (xpp.getName().equals("displayNameGeneration")) 
112                                runDisplayNameGeneration(xpp);
113                        else if (xpp.getName().equals("conversion")) 
114                                runConversion(xpp);
115                        else if (xpp.getName().equals("multiplication")) 
116                                runMultiplication(xpp);
117                        else 
118                                throw new XmlPullParserException("unknown element name "+xpp.getName());
119                }
120                xpp.next();
121                if (errCount > 0)
122                        System.err.println(Integer.toString(errCount)+" errors");
123        }
124        
125        private void runMultiplication(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
126                xpp.next();
127                while (xpp.getEventType() != XmlPullParser.END_TAG) {
128                        if (xpp.getEventType() == XmlPullParser.TEXT) {
129                                if (Utilities.isWhitespace(xpp.getText()))
130                                        xpp.next();
131                                else
132                                        throw new XmlPullParserException("Unexpected text "+xpp.getText());
133                        } else if (xpp.getName().equals("case")) 
134                                runMultiplicationCase(xpp);
135                        else 
136                                throw new XmlPullParserException("unknown element name "+xpp.getName());
137                }
138                xpp.next();       
139  }
140        
141        private void runMultiplicationCase(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
142                
143          String id = xpp.getAttributeValue(null, "id");
144          String v1 = xpp.getAttributeValue(null, "v1");
145          String u1 = xpp.getAttributeValue(null, "u1");
146          String v2 = xpp.getAttributeValue(null, "v2");
147          String u2 = xpp.getAttributeValue(null, "u2");
148          String vRes = xpp.getAttributeValue(null, "vRes");
149          String uRes = xpp.getAttributeValue(null, "uRes");
150          
151          Pair o1 = new Pair(new Decimal(v1), u1);
152          Pair o2 = new Pair(new Decimal(v2), u2);
153          Pair o3 = ucumSvc.multiply(o1, o2);
154
155                debug("Multiplication Test "+id+": the value '"+v1+" "+u1+"' * '"+v2+" "+u2+"' ==> "+o3.getValue().toString()+" "+o3.getCode());
156
157          // if (!res.toPlainString().equals(outcome)) { - that assumes that we can get the precision right, which we can't
158                if (o3.getValue().comparesTo(new Decimal(vRes)) != 0 || !o3.getCode().equals(uRes)) {
159                errCount++;
160                System.err.println("Test "+id+": The value '"+vRes+" "+uRes+"' was expected, but the result was "+o3.getValue().toString()+" "+o3.getCode());
161          }
162                while (xpp.getEventType() != XmlPullParser.END_TAG) 
163            xpp.next();
164                xpp.next();
165                
166  }
167        
168        private void testDecimal() throws UcumException  {
169    testAsInteger();
170    testStringSupport();
171    testCompares();
172    testAddition();
173    testMultiplication();
174  }
175        
176        private void testMultiplication() throws UcumException  {
177          testMultiply("2", "2", "4");
178          testMultiply("2", "0.5", "1");
179          testMultiply("0", "0", "0");
180          testMultiply("0", "1", "0");
181          testMultiply("4", "4", "16");
182          testMultiply("20", "20", "400");
183          testMultiply("200", "20", "4000");
184          testMultiply("400", "400", "160000");
185          testMultiply("2.0", "2.0", "4.0");
186          testMultiply("2.00", "2.0", "4.0");
187          testMultiply("2.0", "0.2", "0.4");
188          testMultiply("2.0", "0.20", "0.40");
189          testMultiply("13", "13", "169");
190          testMultiply("12", "89", "1068");
191          testMultiply("1234", "6789", "8377626");
192
193          testMultiply("10000", "0.0001", "1");
194          testMultiply("10000", "0.00010", "1.0");
195          testMultiply("10000", "0.000100", "1.00");
196          testMultiply("10000", "0.0001000", "1.000");
197          testMultiply("10000", "0.00010000", "1.0000");
198          testMultiply("10000", "0.000100000", "1.00000");
199          testMultiply("10000.0", "0.000100000", "1.00000");
200          testMultiply("10000.0", "0.0001000000", "1.00000");
201          testMultiply("10000.0", "0.00010000000", "1.00000");
202
203          testMultiply("2", "-2", "-4");
204          testMultiply("-2", "2", "-4");
205          testMultiply("-2", "-2", "4");
206
207          testMultiply("35328734682734", "2349834295876423", "83016672387407213199375780482");
208          testMultiply("35328734682734000000000", "2349834295876423000000000", "83016672387407213199375780482000000000000000000");
209          testMultiply("3532873468.2734", "23498342958.76423", "83016672387407213199.375780482");
210
211          testDivide("500", "4", "125");
212          testDivide("1260257", "37", "34061");
213
214          testDivide("127", "4", "31.75");
215          testDivide("10", "10", "1");
216          testDivide("1", "1", "1");
217          testDivide("10", "3", "3.3");
218          testDivide("10.0", "3", "3.33");
219          testDivide("10.00", "3", "3.333");
220          testDivide("10.00", "3.0", "3.3");
221          testDivide("100", "1", "100");
222          testDivide("1000", "10", "100");
223          testDivide("100001", "10", "10000.1");
224          testDivide("100", "10", "10");
225          testDivide("1", "10", "0.1");
226          testDivide("1", "15", "0.067");
227          testDivide("1.0", "15", "0.067");
228          testDivide("1.00", "15.0", "0.0667");
229          testDivide("1", "0.1", "10");
230          testDivide("1", "0.10", "10");
231          testDivide("1", "0.010", "100");
232          testDivide("1", "1.5", "0.67");
233          testDivide("1.0", "1.5", "0.67");
234          testDivide("10", "1.5", "6.7");
235
236          testDivide("-1", "1", "-1");
237          testDivide("1", "-1", "-1");
238          testDivide("-1", "-1", "1");
239
240          testDivide("2", "2", "1");
241          testDivide("20", "2", "10");
242          testDivide("22", "2", "11");
243
244          testDivide("83016672387407213199375780482", "2349834295876423", "35328734682734");
245          testDivide("83016672387407213199375780482000000000000000000", "2349834295876423000000000", "35328734682734000000000");
246          testDivide("83016672387407213199.375780482", "23498342958.76423", "3532873468.2734");
247
248          testDivInt("500", "4", "125");
249          testDivInt("1260257", "37", "34061");
250          testDivInt("127", "4", "31");
251          testDivInt("10", "10", "1");
252          testDivInt("1", "1", "1");
253          testDivInt("100", "1", "100");
254          testDivInt("1000", "10", "100");
255          testDivInt("100001", "10", "10000");
256          testDivInt("1", "1.5", "0");
257          testDivInt("10", "1.5", "6");
258
259          testModulo("10", "1", "0");
260          testModulo("7", "4", "3");
261
262          testMultiply("2", "2", "4");
263          testMultiply("2.0", "2.0", "4.0");
264          testMultiply("2.00", "2.0", "4.0");
265
266          testDivide("10",  "3", "3.3");
267          testDivide("10.0",  "3", "3.33");
268          testDivide("10.00",  "3", "3.333");
269          testDivide("10.00",  "3.0", "3.3");
270          testDivide("10",  "3.0", "3.3");
271
272          
273  }
274
275        private void testModulo(String s1, String s2, String s3) throws UcumException   {
276          Decimal v1 = new Decimal(s1);
277          Decimal v2 = new Decimal(s2);
278          Decimal v3 = v1.modulo(v2);
279    check(v3.asDecimal().equals(s3), s1+" % "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
280  }
281
282        private void testDivInt(String s1, String s2, String s3) throws UcumException   {
283          Decimal v1 = new Decimal(s1);
284          Decimal v2 = new Decimal(s2);
285          Decimal v3 = v1.divInt(v2);
286    check(v3.asDecimal().equals(s3), s1+" /(int) "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
287  }
288
289        private void testDivide(String s1, String s2, String s3)  throws UcumException  {
290          Decimal v1 = new Decimal(s1);
291          Decimal v2 = new Decimal(s2);
292          Decimal v3 = v1.divide(v2);
293    check(v3.asDecimal().equals(s3), s1+" / "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
294  }
295
296        private void testMultiply(String s1, String s2, String s3) throws UcumException  {
297          Decimal v1 = new Decimal(s1);
298          Decimal v2 = new Decimal(s2);
299          Decimal v3 = v1.multiply(v2);
300    check(v3.asDecimal().equals(s3), s1+" * "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
301  }
302
303        private void testAddition() throws UcumException  {
304          testAdd("1", "1", "2");
305          testAdd("0", "1", "1");
306          testAdd("0", "0", "0");
307          testAdd("5", "5", "10");
308          testAdd("10", "1", "11");
309          testAdd("11", "12", "23");
310          testAdd("15", "16", "31");
311          testAdd("150", "160", "310");
312          testAdd("153", "168", "321");
313          testAdd("15300000000000000000000000000000000001", "1680", "15300000000000000000000000000000001681");
314          testAdd("1", ".1", "1.1");
315          testAdd("1", ".001", "1.001");
316          testAdd(".1", ".1", "0.2");
317          testAdd(".1", ".01", "0.11");
318
319          testSubtract("2", "1", "1");
320          testSubtract("2", "0", "2");
321          testSubtract("0", "0", "0");
322          testSubtract("0", "2", "-2");
323          testSubtract("2", "2", "0");
324          testSubtract("1", "2", "-1");
325          testSubtract("20", "1", "19");
326          testSubtract("2", ".1", "1.9");
327          testSubtract("2", ".000001", "1.999999");
328          testSubtract("2", "2.000001", "-0.000001");
329          testSubtract("3.5", "35.5", "-32.0");
330
331          testAdd("5", "6", "11");
332          testAdd("5", "-6", "-1");
333          testAdd("-5", "6", "1");
334          testAdd("-5", "-6", "-11");
335
336          testSubtract("5", "6", "-1");
337          testSubtract("6", "5", "1");
338          testSubtract("5", "-6", "11");
339          testSubtract("6", "-5", "11");
340          testSubtract("-5", "6", "-11");
341          testSubtract("-6", "5", "-11");
342          testSubtract("-5", "-6", "1");
343          testSubtract("-6", "-5", "-1");
344
345          testAdd("2", "0.001", "2.001");
346          testAdd("2.0", "0.001", "2.001");
347          
348  }
349        
350        private void testSubtract(String s1, String s2, String s3) throws UcumException  {
351          Decimal v1 = new Decimal(s1);
352          Decimal v2 = new Decimal(s2);
353          Decimal v3 = v1.subtract(v2);
354    check(v3.asDecimal().equals(s3), s1+" - "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
355  }
356        
357        private void testAdd(String s1, String s2, String s3) throws UcumException  {
358          Decimal v1 = new Decimal(s1);
359          Decimal v2 = new Decimal(s2);
360          Decimal v3 = v1.add(v2);
361    check(v3.asDecimal().equals(s3), s1+" + "+s2+" = "+s3+", but the library returned "+v3.asDecimal());
362  }
363        
364        private void testCompares() throws UcumException  {
365                testCompares("1", "1", 0);
366                testCompares("0", "0", 0);
367                testCompares("0", "1", -1);
368                testCompares("1", "0", 1);
369                
370                testCompares("10", "10", 0);
371                testCompares("100", "100", 0);
372                testCompares("0.1", "0.1", 0);
373                testCompares("0.01", "0.01", 0);
374                testCompares("0.01", "0.0100", 0);
375                testCompares("1", "1.00000000", 0);
376                testCompares("1.111111", "1.111111", 0);
377        }
378        
379        private void testCompares(String v1, String v2, int outcome) throws UcumException  {
380          Decimal d1 = new Decimal(v1);
381          Decimal d2 = new Decimal(v2);
382          int result = d1.comparesTo(d2);
383          check(result == outcome, "Compare fail: "+v1+".compares("+v2+") should be "+Integer.toString(outcome)+" but was "+Integer.toString(result));    
384  }
385        
386        private void testStringSupport() throws UcumException  {
387          testString("1", "1", "1e0");
388          testString("0", "0", "0e0");
389          testString("10", "10", "1.0e1");
390          testString("99", "99", "9.9e1");
391          testString("-1", "-1", "-1e0");
392          testString("-0", "0", "0e0");
393          testString("-10", "-10", "-1.0e1");
394          testString("-99", "-99", "-9.9e1");
395
396          testString("1.1", "1.1", "1.1e0");
397          testString("-1.1", "-1.1", "-1.1e0");
398          testString("11.1", "11.1", "1.11e1");
399          testString("1.11", "1.11", "1.11e0");
400          testString("1.111", "1.111", "1.111e0");
401          testString("0.1", "0.1", "1e-1");
402          testString("00.1", "0.1", "1e-1");
403          testString(".1", "0.1", "1e-1");
404          testString("1.0", "1.0", "1.0e0");
405          testString("1.00", "1.00", "1.00e0");
406          testString("1.000000000000000000000000000000000000000", "1.000000000000000000000000000000000000000", "1.000000000000000000000000000000000000000e0");
407
408          testString("-11.1", "-11.1", "-1.11e1");
409          testString("-1.11", "-1.11", "-1.11e0");
410          testString("-1.111", "-1.111", "-1.111e0");
411          testString("-0.1", "-0.1", "-1e-1");
412          testString("-00.1", "-0.1", "-1e-1");
413          testString("-.1", "-0.1", "-1e-1");
414          testString("-1.0", "-1.0", "-1.0e0");
415          testString("-1.00", "-1.00", "-1.00e0");
416          testString("-1.000000000000000000000000000000000000000", "-1.000000000000000000000000000000000000000", "-1.000000000000000000000000000000000000000e0");
417
418          testString("0.0", "0.0", "0.0e0");
419          testString("0.0000", "0.0000", "0.0000e0");
420          testString("0.1", "0.1", "1e-1");
421          testString("00.1", "0.1", "1e-1");
422          testString("0.100", "0.100", "1.00e-1");
423          testString("100", "100", "1.00e2");
424          testString("1.0", "1.0", "1.0e0");
425          testString("1.1", "1.1", "1.1e0");
426          testString("-0.1", "-0.1", "-1e-1");
427          testString("0.01", "0.01", "1e-2");
428          testString("0.001", "0.001", "1e-3");
429          testString("0.0001", "0.0001", "1e-4");
430          testString("00.0001", "0.0001", "1e-4");
431          testString("000.0001", "0.0001", "1e-4");
432          testString("-0.01", "-0.01", "-1e-2");
433          testString("10.01", "10.01", "1.001e1");
434          testString("0.0001", "0.0001", "1e-4");
435          testString("0.00001", "0.00001", "1e-5");
436          testString("0.000001", "0.000001", "1e-6");
437          testString("0.0000001", "0.0000001", "1e-7");
438          testString("0.000000001", "0.000000001", "1e-9");
439          testString("0.00000000001", "0.00000000001", "1e-11");
440          testString("0.0000000000001", "0.0000000000001", "1e-13");
441          testString("0.000000000000001", "0.000000000000001", "1e-15");
442          testString("0.00000000000000001", "0.00000000000000001", "1e-17");
443          testString("10.1", "10.1", "1.01e1");
444          testString("100.1", "100.1", "1.001e2");
445          testString("1000.1", "1000.1", "1.0001e3");
446          testString("10000.1", "10000.1", "1.00001e4");
447          testString("100000.1", "100000.1", "1.000001e5");
448          testString("1000000.1", "1000000.1", "1.0000001e6");
449          testString("10000000.1", "10000000.1", "1.00000001e7");
450          testString("100000000.1", "100000000.1", "1.000000001e8");
451          testString("1000000000.1", "1000000000.1", "1.0000000001e9");
452          testString("10000000000.1", "10000000000.1", "1.00000000001e10");
453          testString("100000000000.1", "100000000000.1", "1.000000000001e11");
454          testString("1000000000000.1", "1000000000000.1", "1.0000000000001e12");
455          testString("10000000000000.1", "10000000000000.1", "1.00000000000001e13");
456          testString("100000000000000.1", "100000000000000.1", "1.000000000000001e14");
457//        testString("1e-3", "1e-3");   , "1e-3");  e0  }
458
459          testTrunc("1", "1");
460          testTrunc("1.01", "1");
461          testTrunc("-1.01", "-1");
462          testTrunc("0.01", "0");
463          testTrunc("-0.01", "0");
464          testTrunc("0.1", "0");
465          testTrunc("0.0001", "0");
466          testTrunc("100.000000000000000000000000000000000000000001", "100");
467  }
468        
469        private void testTrunc(String s1, String s2) throws UcumException  {
470          Decimal o1 = new Decimal(s1);
471          Decimal o2 = o1.trunc();
472    check(o2.asDecimal().equals(s2), "wrong trunc - expected "+s2+" but got "+o2.asDecimal());
473  }
474        
475        private void testString(String s, String st, String std) throws UcumException  {
476          Decimal dec = new Decimal(s);
477          String s1 = dec.toString();
478          String s2 = dec.asScientific();
479
480          check(s1.equals(st), "decimal: expected "+st+" but got "+s1);
481          check(s2.equals(std), "scientific: expected "+std+" but got "+s2);
482
483          dec = new Decimal(std);
484    s1 = dec.asDecimal();
485          check(s1.equals(st), "decimal(2): expected "+st+" but got "+s1);        
486  }
487        
488        private void testAsInteger() throws UcumException  {
489          testInteger(0);
490          testInteger(1);
491          testInteger(2);
492          testInteger(64);
493          testInteger(Integer.MAX_VALUE);
494          testInteger(-1);
495          testInteger(-2);
496          testInteger(-64);
497          testInteger(Integer.MIN_VALUE);         
498  }
499        
500        private void testInteger(int i) throws UcumException  {
501                Decimal d = new Decimal(i);
502                check(d.asInteger() == i, "Failed to round trip the integer "+Integer.toString(i));
503        }
504        
505        private void check(boolean b, String msg) {
506          if (!b)
507                throw new Error(msg);     
508  }
509        
510        private void runConversion(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
511                xpp.next();
512                while (xpp.getEventType() != XmlPullParser.END_TAG) {
513                        if (xpp.getEventType() == XmlPullParser.TEXT) {
514                                if (Utilities.isWhitespace(xpp.getText()))
515                                        xpp.next();
516                                else
517                                        throw new XmlPullParserException("Unexpected text "+xpp.getText());
518                        } else if (xpp.getName().equals("case")) 
519                                runConversionCase(xpp);
520                        else 
521                                throw new XmlPullParserException("unknown element name "+xpp.getName());
522                }
523                xpp.next();
524  }
525
526        private void runConversionCase(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
527                
528          String id = xpp.getAttributeValue(null, "id");
529          String value = xpp.getAttributeValue(null, "value");
530          String srcUnit = xpp.getAttributeValue(null, "srcUnit");
531          String dstUnit = xpp.getAttributeValue(null, "dstUnit");
532          String outcome = xpp.getAttributeValue(null, "outcome");
533          System.out.println("case "+id+": "+value+" "+srcUnit+" -> "+outcome+" "+dstUnit);
534          Decimal res = ucumSvc.convert(new Decimal(value), srcUnit, dstUnit);
535                debug("Convert Test "+id+": the value '"+value+" "+srcUnit+"' ==> "+res.toString()+" "+dstUnit);
536
537          // if (!res.toPlainString().equals(outcome)) { - that assumes that we can get the precision right, which we can't
538                if (res.comparesTo(new Decimal(outcome)) != 0) {
539                errCount++;
540                System.err.println("Test "+id+": The value '"+outcome+"' was expected the result was "+res.toString());
541          }
542                while (xpp.getEventType() != XmlPullParser.END_TAG) 
543            xpp.next();
544                xpp.next();
545  }
546        
547        
548        private void debug(String string) {
549                System.out.println(string);
550          
551  }
552        private void runDisplayNameGeneration(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
553                xpp.next();
554                while (xpp.getEventType() != XmlPullParser.END_TAG) {
555                        if (xpp.getEventType() == XmlPullParser.TEXT) {
556                                if (Utilities.isWhitespace(xpp.getText()))
557                                        xpp.next();
558                                else
559                                        throw new XmlPullParserException("Unexpected text "+xpp.getText());
560                        } else if (xpp.getName().equals("case")) 
561                                runDisplayNameGenerationCase(xpp);
562                        else 
563                                throw new XmlPullParserException("unknown element name "+xpp.getName());
564                }
565                xpp.next();
566  }
567
568        private void runDisplayNameGenerationCase(XmlPullParser xpp) throws XmlPullParserException, IOException, UcumException  {
569          String id = xpp.getAttributeValue(null, "id");
570          String unit = xpp.getAttributeValue(null, "unit");
571          String display = xpp.getAttributeValue(null, "display");
572          
573          String res = ucumSvc.analyse(unit);
574                debug("Analyse Test "+id+": the unit '"+unit+"' ==> "+res);
575
576          if (!res.equals(display)) {
577                errCount++;
578                System.err.println("Test "+id+": The unit '"+unit+"' was expected to be displayed as '"+display+"', but was displayed as "+res);
579          }
580                while (xpp.getEventType() != XmlPullParser.END_TAG) 
581            xpp.next();
582                xpp.next();
583  }
584        
585        private void runValidationTests(XmlPullParser xpp) throws XmlPullParserException, IOException  {
586                xpp.next();
587                while (xpp.getEventType() != XmlPullParser.END_TAG) {
588                        if (xpp.getEventType() == XmlPullParser.TEXT) {
589                                if (Utilities.isWhitespace(xpp.getText()))
590                                        xpp.next();
591                                else
592                                        throw new XmlPullParserException("Unexpected text "+xpp.getText());
593                        } else if (xpp.getName().equals("case")) 
594                                runValidationCase(xpp);
595                        else 
596                                throw new XmlPullParserException("unknown element name "+xpp.getName());
597                }
598                xpp.next();
599  }
600        
601        private void runValidationCase(XmlPullParser xpp) throws XmlPullParserException, IOException  {
602          String id = xpp.getAttributeValue(null, "id");
603          String unit = xpp.getAttributeValue(null, "unit");
604          boolean valid = "true".equals(xpp.getAttributeValue(null, "valid"));
605          String reason = xpp.getAttributeValue(null, "reason");
606          
607          String res = ucumSvc.validate(unit);
608                boolean result = res == null;
609                if (result)
610                  debug("Validation Test "+id+": the unit '"+unit+"' is valid");
611                else
612                  debug("Validation Test "+id+": the unit '"+unit+"' is not valid because "+res);
613
614          if (valid != result) {
615                errCount++;
616                if (valid)
617                        System.err.println("Test "+id+": The unit '"+unit+"' was expected to be valid, but wasn't accepted");
618                else
619                        System.err.println("Test "+id+": The unit '"+unit+"' was expected to be invalid because '"+reason+"', but was accepted");
620          }
621                while (xpp.getEventType() != XmlPullParser.END_TAG) 
622            xpp.next();
623                xpp.next();
624  }
625        
626        private void skipElement(XmlPullParser xpp) throws XmlPullParserException, IOException  {
627                xpp.next();
628                while (xpp.getEventType() != XmlPullParser.END_TAG) {
629                        if (xpp.getEventType() == XmlPullParser.START_TAG)
630                                skipElement(xpp);
631                        else 
632                                xpp.next();
633                }
634                xpp.next();
635  }
636
637
638}