| package edu.illinois.ncsa.daffodil.util |
| |
| /* Copyright (c) 2012-2013 Tresys Technology, LLC. All rights reserved. |
| * |
| * Developed by: Tresys Technology, LLC |
| * http://www.tresys.com |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy of |
| * this software and associated documentation files (the "Software"), to deal with |
| * the Software without restriction, including without limitation the rights to |
| * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
| * of the Software, and to permit persons to whom the Software is furnished to do |
| * so, subject to the following conditions: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimers. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimers in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * 3. Neither the names of Tresys Technology, nor the names of its contributors |
| * may be used to endorse or promote products derived from this Software |
| * without specific prior written permission. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE |
| * SOFTWARE. |
| */ |
| |
| import scala.xml._ |
| import edu.illinois.ncsa.daffodil.xml.XMLUtils |
| import edu.illinois.ncsa.daffodil.xml.XMLUtils._ |
| import java.io.File |
| import java.io.FileNotFoundException |
| import edu.illinois.ncsa.daffodil.Implicits._ |
| import edu.illinois.ncsa.daffodil.compiler.Compiler |
| import java.nio.channels.ReadableByteChannel |
| import org.junit.Assert.assertEquals |
| |
| /* |
| * This is not a file of tests. |
| * |
| * These are utilities to support unit testing schemas |
| */ |
| object TestUtils { |
| |
| /** |
| * Compares two XML Elements, after having stripped off all attributes. |
| * |
| * TODO: we might start using xsi:type attributes at some point. If so fix this to |
| * save that attribute. |
| * |
| * NOTE: Has Side Effects: strips off attributes |
| */ |
| def assertEqualsXMLElements(expected: Node, actual: Node) { |
| val exp = Utility.trim(XMLUtils.removeAttributes(expected)) |
| val act = Utility.trim(XMLUtils.removeAttributes(actual)) |
| XMLUtils.compareAndReport(exp, act) |
| } |
| |
| /** |
| * We want to be able to run tests from Eclipse or from batch builds that |
| * are rooted in a different directory, so, since Java/JVMs don't have a notion |
| * of setting the current directory to a specific value for interpreting things, |
| * we have to do that ourselves manually like this. |
| * |
| * When you specify a file for use in a test, you want to specify it |
| * relative to the root of the sub-project of which it is part. I.e., within core, |
| * the file you specify should be relative to daffodil/sub-projects/core. |
| * |
| * Returns null if the file cannot be found. |
| */ |
| def findFile(fn: String): File = findFile(new File(fn)) |
| def findFile(f: File): File = { |
| if (f.exists()) return f |
| val cwd = new File("").getAbsolutePath |
| throw new FileNotFoundException("Couldn't find file " + f + " relative to " + cwd + ".") |
| } |
| |
| def testString(testSchema: Node, data: String) = { |
| runSchemaOnData(testSchema, Misc.stringToReadableByteChannel(data)) |
| } |
| |
| def testBinary(testSchema: Node, hexData: String) = { |
| val b = Misc.hex2Bytes(hexData) |
| val rbc = Misc.byteArrayToReadableByteChannel(b) |
| runSchemaOnData(testSchema, rbc) |
| } |
| |
| def testFile(testSchema: Node, fileName: String) = { |
| runSchemaOnData(testSchema, Misc.fileToReadableByteChannel(new java.io.File(fileName))) |
| } |
| |
| def testUnparsing(testSchema: scala.xml.Elem, infoset: Node, unparseTo: String) { |
| val compiler = Compiler() |
| val pf = compiler.compile(Seq.empty, testSchema) |
| if (pf.isError) { |
| val msgs = pf.getDiagnostics.map(_.getMessage).mkString("\n") |
| throw new Exception(msgs) |
| } |
| val u = pf.onPath("/") |
| if (u.isError) { |
| val msgs = u.getDiagnostics.map(_.getMessage).mkString("\n") |
| throw new Exception(msgs) |
| } |
| val outputStream = new java.io.ByteArrayOutputStream() |
| val out = java.nio.channels.Channels.newChannel(outputStream) |
| val actual = u.unparse(out, infoset) |
| if (actual.isError) { |
| val msgs = actual.getDiagnostics.map(_.getMessage).mkString("\n") |
| throw new Exception(msgs) |
| } |
| val unparsed = outputStream.toString |
| // System.err.println("parsed: " + infoset) |
| // System.err.println("unparsed: " + unparsed) |
| out.close() |
| assertEquals(unparseTo, unparsed) |
| } |
| |
| def testUnparsingBinary(testSchema: scala.xml.Elem, infoset: Node, unparseTo: Array[Byte]) { |
| val compiler = Compiler() |
| val pf = compiler.compile(Seq.empty, testSchema) |
| val u = pf.onPath("/") |
| val outputStream = new java.io.ByteArrayOutputStream() |
| val out = java.nio.channels.Channels.newChannel(outputStream) |
| val actual = u.unparse(out, infoset) |
| if (actual.isError) { |
| val msgs = actual.getDiagnostics.map(_.getMessage).mkString("\n") |
| throw new Exception(msgs) |
| } |
| val unparsed = outputStream.toByteArray() |
| // System.err.println("parsed: " + infoset) |
| // System.err.println("unparsed: " + unparsed) |
| out.close() |
| assertEquals(unparsed.length, unparseTo.length) |
| for (i <- 0 until unparsed.length) { |
| assertEquals(unparseTo(i), unparsed(i)) |
| } |
| } |
| |
| def runSchemaOnData(testSchema: Node, data: ReadableByteChannel) = { |
| val compiler = Compiler() |
| val pf = compiler.compile(Seq.empty, testSchema) |
| val isError = pf.isError |
| val msgs = pf.getDiagnostics.map(_.getMessage).mkString("\n") |
| |
| if (isError) { |
| throw new Exception(msgs) |
| } |
| val p = pf.onPath("/") |
| val pIsError = p.isError |
| if (pIsError) { |
| throw new Exception(msgs) |
| } |
| val d = data |
| val actual = p.parse(d) |
| if (actual.isError) { |
| val msgs = actual.getDiagnostics.map(_.getMessage).mkString("\n") |
| throw new Exception(msgs) |
| } |
| actual |
| } |
| |
| } |