This is an automated email from the ASF dual-hosted git repository.

mbeckerle pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git


The following commit(s) were added to refs/heads/main by this push:
     new 3955ba507 Improve diagnostic in TDML Runner
3955ba507 is described below

commit 3955ba507d5034d94907fe7f6d549d110ceecec7
Author: Michael Beckerle <[email protected]>
AuthorDate: Fri Nov 1 17:11:14 2024 -0400

    Improve diagnostic in TDML Runner
    
    Note that this change enforces the syntax of TDML better.
    The dfdlInfoset element used to tolerate having spurious text in it,
    so long as it also had a root element.
    Two TDML files had to be fixed in Daffodil.
    If TDML files in schema projects have these spurious characters that
    were formerly ignored, this change will break
    those tests.
    
    DAFFODIL-533
---
 .../resources/org/apache/daffodil/xsd/tdml.xsd     | 10 ++-
 .../org/apache/daffodil/tdml/TDMLRunner.scala      | 82 ++++++++++++----------
 .../apache/daffodil/tdml/UnitTestTDMLRunner.scala  | 12 ++++
 .../daffodil/processor/tdml/TestTDMLRunner.scala   | 29 ++++++++
 .../section15/choice_groups/HiddenChoices.tdml     |  2 +-
 5 files changed, 94 insertions(+), 41 deletions(-)

diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd 
b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
index 6d4562f39..8a8441a1e 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
@@ -308,7 +308,15 @@
 
   <complexType name="dfdlInfosetType" mixed="true">
     <sequence>
-      <any namespace="##any" processContents="lax" minOccurs="0" 
maxOccurs="unbounded"/>
+      <!--
+      Can be empty if type is 'file'.
+      Otherwise, can be any single element (maxOccurs unbounded removed),
+      which is the root element of the infoset.
+
+      Mixed="true" because when type='file' the content is just a string
+      that is the file path
+      -->
+      <any namespace="##any" processContents="lax" minOccurs="0" 
maxOccurs="1"/>
     </sequence>
     <attribute name="type" use="optional" default="infoset">
       <simpleType>
diff --git 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
index 0cfe487d4..ad25deacf 100644
--- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
@@ -31,6 +31,7 @@ import java.nio.charset.StandardCharsets
 import scala.collection.mutable
 import scala.language.postfixOps
 import scala.util.Try
+import scala.xml.Elem
 import scala.xml.Node
 import scala.xml.NodeSeq
 import scala.xml.NodeSeq.seqToNodeSeq
@@ -2769,41 +2770,52 @@ case class Infoset(i: NodeSeq, parent: TestCase) {
 
 case class DFDLInfoset(di: Node, parent: Infoset) {
 
-  private lazy val infosetNodeSeq = {
-    val testCase: TestCase = parent.parent
-    val loader = testCase.parent.loader
-    val optDataSchema: Option[URI] = {
-      testCase.optSchemaFileURI.orElse(testCase.optEmbeddedSchema.map { 
_.uriForLoading })
-    }
-    val src =
-      (di \ "@type").toString match {
-        case "infoset" | "" => {
-          val rawElem = di.child.filter {
-            _.isInstanceOf[scala.xml.Elem]
-          }.head
-          UnitTestSchemaSource(rawElem, testCase.tcName)
-        }
-        case "file" => {
-          val path = di.text.trim()
-          val maybeURI = parent.parent.parent.findTDMLResource(path)
-          val uri = maybeURI.getOrElse(
-            throw new FileNotFoundException(
-              "TDMLRunner: infoset file '" + path + "' was not found"
-            )
-          )
-          URISchemaSource(uriToDiagnosticFile(uri), uri)
-        }
-        case value => Assert.abort("Unknown value for type attribute on 
dfdlInfoset: " + value)
-      }
+  private lazy val testCase: TestCase = parent.parent
+  private lazy val loader = testCase.parent.loader
+  private val ty: String = {
+    val t = (di \ "@type").text.trim
+    if (t.isEmpty) "infoset" else t
+  }
+
+  private val elemOrStr: Either[Elem, String] = {
+    val (elems, others) = di.child.partition(_.isInstanceOf[scala.xml.Elem])
+    (elems, others.text.trim) match {
+      case (Seq(elem: Elem), "") if (ty == "infoset") => Left(elem)
+      case (Seq(), str) if (ty == "file") => Right(str)
+      case _ =>
+        Assert.usageError(
+          """dfdlInfoset element must contain a single root element or a file 
path (when 'type="file"')."""
+        )
+    }
+  }
+
+  lazy val contents: Elem = {
+    elemOrStr match {
+      case Left(elem) => elem
+      case Right(path) => infosetNodeFromFile(path)
+    }
+  }
+
+  private def infosetNodeFromFile(path: String): Elem = {
+
+    val maybeURI = parent.parent.parent.findTDMLResource(path)
+    val uri = maybeURI.getOrElse(
+      throw new FileNotFoundException(
+        "TDMLRunner: infoset file '" + path + "' was not found"
+      )
+    )
+    val infosetSrc = URISchemaSource(uriToDiagnosticFile(uri), uri)
+
+    val testSuite = testCase.parent
+    val before = testSuite.loadingExceptions.clone()
+
+    val elem = loader.load(infosetSrc, None) // no schema
     //
     // TODO: DAFFODIL-288 validate the infoset also
     // You can pass the optDataSchema, which appears to be the correct thing
     // but in many cases it doesn't seem to be able to resolve things.
     //
-    val testSuite = testCase.parent
-    val before = testSuite.loadingExceptions.clone()
-    // val elem: Node = loader.load(src, optDataSchema)
-    val elem = loader.load(src, None) // no schema
+    // val elem: Node = loader.load(infosetSrc, optDataSchema)
 
     // The expected infoset is loaded using the normalizeCRLFtoLF mode (which
     // is the default), so MS-DOS/Windows CRLFs in expected data XML files will
@@ -2818,17 +2830,9 @@ case class DFDLInfoset(di: Node, parent: Infoset) {
       val newExceptions = (testSuite.loadingExceptions -- before).toSeq
       testCase.toss(TDMLException(newExceptions, None), None)
     }
-    elem
+    elem.asInstanceOf[Elem]
   }
 
-  lazy val contents = {
-    Assert.usage(
-      infosetNodeSeq.size == 1,
-      "dfdlInfoset element must contain a single root element"
-    )
-    val c = infosetNodeSeq.head
-    c
-  }
 }
 
 object DiagnosticType extends Enumeration {
diff --git 
a/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/UnitTestTDMLRunner.scala
 
b/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/UnitTestTDMLRunner.scala
index e4299c1a2..c71ae205f 100644
--- 
a/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/UnitTestTDMLRunner.scala
+++ 
b/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/UnitTestTDMLRunner.scala
@@ -21,6 +21,7 @@ import java.io.File
 
 import org.apache.daffodil.lib.Implicits._
 import org.apache.daffodil.lib.Implicits.using
+import org.apache.daffodil.lib.exceptions.UsageException
 import org.apache.daffodil.lib.util._
 import org.apache.daffodil.lib.xml.XMLUtils
 
@@ -336,6 +337,17 @@ class UnitTestTDMLRunner {
     assertEquals(expected, actual.toList)
   }
 
+  @Test def testDFDLInfosetEmptyDiagnosticMsg(): Unit = {
+    val xml = <tdml:dfdlInfoset/>
+    val exc = intercept[UsageException] {
+      val di = new DFDLInfoset(xml, null)
+      di.contents
+    }
+    val m = exc.getMessage
+    assertTrue(m.contains("dfdlInfoset"))
+    assertTrue(m.contains("single root element"))
+  }
+
   @Test def testLSB1(): Unit = {
     val xml = <document bitOrder="LSBFirst">
                 <documentPart type="bits">00000010</documentPart>
diff --git 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
index e2f346f23..1d4ccf74d 100644
--- 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
+++ 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
@@ -18,6 +18,7 @@
 package org.apache.daffodil.processor.tdml
 
 import java.io.File
+import java.io.FileNotFoundException
 
 import org.apache.daffodil.lib.Implicits._
 import org.apache.daffodil.lib.Implicits.using
@@ -1061,4 +1062,32 @@ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
     assertTrue(exc.getMessage.contains("Either tdml:infoset or tdml:error"))
     assertTrue(exc.getMessage.contains("must be present in the test"))
   }
+
+  @Test def testInfosetFileNotFound() = {
+    val testSuite =
+      <tdml:testSuite suiteName="theSuiteName" xmlns:tdml={tdml} 
xmlns:dfdl={dfdl}
+                      xmlns:xs={xsd}>
+        <tdml:defineSchema name="mySchema">
+          <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+          <dfdl:format ref="GeneralFormat"/>
+          <xs:element name="data" type="xs:int" dfdl:lengthKind="delimited"/>
+        </tdml:defineSchema>
+        <tdml:unparserTestCase name="infosetFileNotFound" root="data" 
model="mySchema">
+          <tdml:infoset>
+            <tdml:dfdlInfoset 
type="file">/this/does/not/exist.xml</tdml:dfdlInfoset>
+          </tdml:infoset>
+          <tdml:document/>
+        </tdml:unparserTestCase>
+      </tdml:testSuite>
+
+    val runner = new Runner(testSuite)
+    val e = intercept[FileNotFoundException] {
+      runner.runOneTest("infosetFileNotFound")
+    }
+    runner.reset
+    val msg = e.getMessage()
+    assertTrue(msg.contains("not found"))
+    assertTrue(msg.contains("/this/does/not/exist.xml"))
+  }
+
 }
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
index e4094ac65..f0b199022 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
@@ -217,7 +217,7 @@
   <tdml:unparserTestCase name="nestedNoOVCinHiddenContext" root="e7"
     model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
     <tdml:infoset>
-      <tdml:dfdlInfoset>)
+      <tdml:dfdlInfoset>
         <ex:e7/>
       </tdml:dfdlInfoset>
     </tdml:infoset>

Reply via email to