stevedlawrence commented on a change in pull request #463:
URL: https://github.com/apache/incubator-daffodil/pull/463#discussion_r560181520



##########
File path: 
daffodil-cli/src/it/scala/org/apache/daffodil/schematron/package.scala
##########
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil
+
+import org.apache.daffodil.CLI.Util
+import net.sf.expectit.matcher.Matchers.eof
+import net.sf.expectit.Result
+import net.sf.expectit.matcher.Matcher
+import net.sf.expectit.matcher.Matchers.contains
+import net.sf.expectit.matcher.Matchers.regexp
+import org.junit.Assert.fail
+
+import java.io.File
+import java.io.FileOutputStream
+import java.nio.file.Path
+import java.nio.file.Paths
+import scala.util.Failure
+import scala.util.Success
+import scala.util.Try
+
+package object schematron {
+  val FailureErrorCodeResult = 1
+
+  /**
+   * executes a command in a shell with the provided expectations and error 
code using a mustache syntax looks up files
+   * from local resources {path} or the daffodil-schematron resources {{path}}
+   * @param ec expected error code
+   * @param stderr join stderr in output
+   * @param body 2 tuple of daffodil arguments and expectation
+   */
+  def withShell[R <: Result](ec: Int = 0, stderr: Boolean = false)(body: => 
(String,  Matcher[R])): Unit = {
+    val (argstring, expectation) = body
+    val args = mustache.replaceAllIn(argstring, _ match {
+      case mustache2(p) => schPath(p).toString
+      case mustache1(p) => cliPath(p).toString
+    })
+
+    val joinStdErr = if(stderr) "2>&1" else ""
+    val cmd = Util.binPath :: args :: joinStdErr :: Nil mkString " "
+    val shell = Util.start("")
+    try {
+      shell.sendLine(cmd).expect(expectation)
+
+      val actualEc = shell.sendLine(echoEC).expect(contains("\n")).getBefore
+      Try(actualEc.toInt) match {
+        case Success(`ec`) => // good
+        case Success(v) => fail(s"wrong ec, $v")
+        case Failure(_) => fail(s"unparseable ec, $actualEc")
+      }
+
+      shell.send("exit\n")
+      shell.expect(eof)
+      shell.close()
+    } finally {
+      shell.close()
+    }
+  }
+
+  // two reasons for this bit of parsing indirection
+  // 1. support consuming resources from multiple projects
+  // 2. avoid doing the noisy and repetetive resolution in the unit tests
+  private val mustache = """\{{1,2}(.+?)}{1,2}""".r.unanchored
+  private val mustache1 = """\{(.+?)}""".r.unanchored
+  private val mustache2 = """\{\{(.+?)}}""".r.unanchored
+
+  private def schPath(p: String): Path = 
path(s"daffodil-schematron/src/test/resources/$p")
+  private def cliPath(p: String): Path = 
path(s"daffodil-cli/src/it/resources/org/apache/daffodil/CLI/$p")
+  private def path(p: String): Path = {
+    val daffpath = Util.daffodilPath(p)
+    Paths.get(if(Util.isWindows) Util.cmdConvert(daffpath) else 
daffpath).toAbsolutePath
+  }
+  private lazy val echoEC: String = s"echo ${if(Util.isWindows) "%errorlevel%" 
else "$?"}"
+
+  /**
+   * number of lines, any content on those lines
+   * @param n line count
+   * @return
+   */
+  def anyLines(n: Int): Matcher[_] = regexp(Seq.fill(n)(".+\n").mkString)
+
+  /**
+   * make a temp file containing the bytes
+   * @param str
+   * @return
+   */
+  def mktmp(d: Array[Byte]): Path = {
+    val f = File.createTempFile("schval", "data")
+    val os = new FileOutputStream(f)
+    os.write(d)
+    os.close()
+    f.toPath
+  }
+  def mktmp(str: String): Path = mktmp(str.getBytes)
+}

Review comment:
       This is great! But it fells like it belongs in ``CLI/Util.scala`` for 
other tests to use. Though, I guess there are lots of little bits that at are 
very specific to schematron tests, so maybe it's not quite ready? For example, 
single curly braces means the resource is in daffodil-schematron is very 
specific to this (and honestly, not very obvious).
   
   Something like this is definitely needed, and is almost certainly how 
DAFFODIL-2381 should be resolved.
   
   However, I don't really want there to be two different ways to write CLI 
tests long term, so we need to make sure we document that this is written 
differently from others CLI tests, and that that should probably be fixed as 
part of DAFFODIL-2381. Perhaps add a comment to DAFFODIL-2381 to specifically 
point out this code, and explain that this should become the basis for those 
changes, and maybe mention anything that is specific to schematron that likely 
needs to be replaced.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to