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

olabusayo 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 3e936cfec Add support for validation of length facet
3e936cfec is described below

commit 3e936cfec9c1f2897be2b619a4c586a13b4304c5
Author: olabusayoT <[email protected]>
AuthorDate: Mon Mar 25 15:28:41 2024 -0400

    Add support for validation of length facet
    
    - add support for length facet, setting minLength and maxLength with the 
value of length, when hasLength is true, and those variables are queried
    - ensure length and minLength and maxLength facets are not declared 
together (Xerces Error, but we have asserts in case Xerces validation is turned 
off)
    - fix error message for isSimpleType check in computeMinMaxLength definition
    - add tests for validation=limited and validation=on
    - added hexBinary tests including test with length=0
    - remove greater than or equal to zero checks for 
check[Length,MinLength,MaxLength] functions
    - remove some commented out code
    - add test to verify local facet len must be equal to base restriction 
length
    - add test that ensures dfdl:length is not less than base length facet
    - add reptype tests
    - convert SDE to Assert.invariantFailed for the case when hasLength is true 
and minLen/maxLen is anything but false
    
    DAFFODIL-2842
---
 .../apache/daffodil/core/dsom/ElementBase.scala    |  45 +--
 .../org/apache/daffodil/core/dsom/Facets.scala     |  65 +++--
 .../daffodil/core/dsom/RestrictionUnion.scala      |   7 +
 .../apache/daffodil/core/dsom/SimpleTypes.scala    |   2 +-
 .../core/grammar/ElementBaseGrammarMixin.scala     |  20 +-
 .../core/runtime1/SimpleTypeRuntime1Mixin.scala    |   1 +
 .../apache/daffodil/runtime1/dsom/Facets1.scala    |   1 +
 .../daffodil/runtime1/processors/RuntimeData.scala |  52 +++-
 .../daffodil/extensions/repType/repType.tdml       |  85 +++++-
 .../section02/validation_errors/Validation.tdml    | 304 ++++++++++++++++++++-
 .../text_number_props/TextNumberPropsUnparse.tdml  |  27 +-
 .../apache/daffodil/extensions/TestRepType.scala   |   9 +
 .../validation_errors/TestValidationErr.scala      |  35 +++
 .../TestTextNumberPropsUnparse.scala               |   1 +
 14 files changed, 583 insertions(+), 71 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
index 15740e4e8..a8c8f35f1 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
@@ -83,8 +83,8 @@ trait ElementBase
   requiredEvaluationsIfActivated(isSimpleType)
   requiredEvaluationsIfActivated(if (hasPattern) patternValues)
   requiredEvaluationsIfActivated(if (hasEnumeration) enumerationValues)
-  requiredEvaluationsIfActivated(if (hasMinLength) minLength)
-  requiredEvaluationsIfActivated(if (hasMaxLength) maxLength)
+  requiredEvaluationsIfActivated(if (hasMinLength || hasLength) minLength)
+  requiredEvaluationsIfActivated(if (hasMaxLength || hasLength) maxLength)
   requiredEvaluationsIfActivated(if (hasMinInclusive) minInclusive)
   requiredEvaluationsIfActivated(if (hasMaxInclusive) maxInclusive)
   requiredEvaluationsIfActivated(if (hasMinExclusive) minExclusive)
@@ -711,8 +711,8 @@ trait ElementBase
       Assert.invariant(repElement.lengthKind =:= LengthKind.Implicit)
       // it's a string with implicit length. get from facets
       schemaDefinitionUnless(
-        repElement.hasMaxLength,
-        "String with dfdl:lengthKind='implicit' must have an XSD maxLength 
facet value.",
+        repElement.hasMaxLength || repElement.hasLength,
+        "String with dfdl:lengthKind='implicit' must have a length or 
maxLength facet value.",
       )
       val ml = repElement.maxLength
       ml.longValue()
@@ -941,8 +941,9 @@ trait ElementBase
 
   private lazy val hasPattern: Boolean = 
typeDef.optRestriction.exists(_.hasPattern)
   private lazy val hasEnumeration: Boolean = 
typeDef.optRestriction.exists(_.hasEnumeration)
-  protected lazy val hasMinLength = 
typeDef.optRestriction.exists(_.hasMinLength)
-  protected lazy val hasMaxLength = 
typeDef.optRestriction.exists(_.hasMaxLength)
+  protected lazy val hasLength: Boolean = 
typeDef.optRestriction.exists(_.hasLength)
+  protected lazy val hasMinLength: Boolean = 
typeDef.optRestriction.exists(_.hasMinLength)
+  protected lazy val hasMaxLength: Boolean = 
typeDef.optRestriction.exists(_.hasMaxLength)
   private lazy val hasMinInclusive = 
typeDef.optRestriction.exists(_.hasMinInclusive)
   private lazy val hasMaxInclusive = 
typeDef.optRestriction.exists(_.hasMaxInclusive)
   private lazy val hasMinExclusive = 
typeDef.optRestriction.exists(_.hasMinExclusive)
@@ -963,18 +964,19 @@ trait ElementBase
   /**
    * Compute minLength and maxLength together to share error-checking
    * and case dispatch that would otherwise have to be repeated.
+   *
+   * Also set them to the value of length, in the case we've used the length 
facet
    */
   final lazy val (minLength: java.math.BigDecimal, maxLength: 
java.math.BigDecimal) =
     computeMinMaxLength
-  // TODO: why are we using java.math.BigDecimal, when scala has a much
-  // nicer decimal class?
+
   private val zeroBD = new java.math.BigDecimal(0)
   private val unbBD = new java.math.BigDecimal(-1) // TODO: should this be a 
tunable limit?
 
   private def computeMinMaxLength: (java.math.BigDecimal, 
java.math.BigDecimal) = {
     schemaDefinitionUnless(
       isSimpleType,
-      "Facets minLength and maxLength are allowed only on types string and 
hexBinary.",
+      "The length facet or minLength/maxLength facets are not allowed on 
complex types",
     )
     typeDef match {
       case _ if hasRepType => {
@@ -986,7 +988,7 @@ trait ElementBase
         val pt = prim.primType
         schemaDefinitionWhen(
           (pt == PrimType.String || pt == PrimType.HexBinary) && lengthKind == 
LengthKind.Implicit,
-          "Facets minLength and maxLength must be defined for type %s with 
lengthKind='implicit'",
+          "The length facet or minLength/maxLength facets must be defined for 
type %s with lengthKind='implicit'",
           pt.name,
         )
         //
@@ -1001,12 +1003,17 @@ trait ElementBase
         val pt = st.primType
         val typeOK = pt == PrimType.String || pt == PrimType.HexBinary
         schemaDefinitionWhen(
-          !typeOK && (hasMinLength || hasMaxLength),
-          "Facets minLength and maxLength are not allowed on types derived 
from type %s.\nThey are allowed only on typed derived from string and 
hexBinary.",
+          !typeOK && (hasLength || hasMinLength || hasMaxLength),
+          "The length facet or minLength/maxLength facets are not allowed on 
types derived from type %s.\nThey are allowed only on types derived from string 
and hexBinary.",
           pt.name,
         )
-        val res = (hasMinLength, hasMaxLength, lengthKind) match {
-          case (true, true, LengthKind.Implicit) => {
+        val res = (hasLength, hasMinLength, hasMaxLength, lengthKind) match {
+          case (true, false, false, _) => (r.lengthValue, r.lengthValue)
+          case (true, _, _, _) =>
+            Assert.invariantFailed(
+              "Facet length cannot be defined with minLength and maxLength 
facets",
+            )
+          case (false, true, true, LengthKind.Implicit) => {
             schemaDefinitionUnless(
               r.minLengthValue.compareTo(r.maxLengthValue) == 0,
               "The minLength and maxLength must be equal for type %s with 
lengthKind='implicit'. Values were minLength of %s, maxLength of %s.",
@@ -1016,7 +1023,7 @@ trait ElementBase
             )
             (r.minLengthValue, r.maxLengthValue)
           }
-          case (true, true, _) => {
+          case (false, true, true, _) => {
             schemaDefinitionWhen(
               r.minLengthValue.compareTo(r.maxLengthValue) > 0,
               // always true, so we don't bother to specify the type in the 
message.
@@ -1026,13 +1033,13 @@ trait ElementBase
             )
             (r.minLengthValue, r.maxLengthValue)
           }
-          case (_, _, LengthKind.Implicit) =>
+          case (false, _, _, LengthKind.Implicit) =>
             SDE(
               "When lengthKind='implicit', both minLength and maxLength facets 
must be specified.",
             )
-          case (false, true, _) => (zeroBD, r.maxLengthValue)
-          case (false, false, _) => (zeroBD, unbBD)
-          case (true, false, _) => (r.minLengthValue, unbBD)
+          case (false, false, true, _) => (zeroBD, r.maxLengthValue)
+          case (false, false, false, _) => (zeroBD, unbBD)
+          case (false, true, false, _) => (r.minLengthValue, unbBD)
           case _ => Assert.impossible()
         }
         res
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Facets.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Facets.scala
index 0c448f106..3cdf64f16 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Facets.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Facets.scala
@@ -51,6 +51,9 @@ trait Facets { self: Restriction =>
   private def fractionDigits(xml: Node): String = {
     retrieveFacetValueFromRestrictionBase(xml, Facet.fractionDigits)
   }
+  private def length(xml: Node): String = {
+    retrieveFacetValueFromRestrictionBase(xml, Facet.length)
+  }
   private def maxExclusive(xml: Node): String = {
     retrieveFacetValueFromRestrictionBase(xml, Facet.maxExclusive)
   }
@@ -93,8 +96,27 @@ trait Facets { self: Restriction =>
   final lazy val localMaxInclusiveValue: String = maxInclusive(xml)
   final lazy val localMinExclusiveValue: String = minExclusive(xml)
   final lazy val localMaxExclusiveValue: String = maxExclusive(xml)
-  final lazy val localMinLengthValue: String = minLength(xml)
-  final lazy val localMaxLengthValue: String = maxLength(xml)
+  final lazy val localLengthValue: String = length(xml)
+  final lazy val localMinLengthValue: String = {
+    val ml = minLength(xml)
+    // Xerces checks for the case where length and min/maxLength are used 
together,
+    // so we won't get to this code in those cases unless Xerces validation is 
turned off
+    Assert.usage(
+      ml.isEmpty || localLengthValue.isEmpty,
+      "Facets length and minLength cannot be specified together",
+    )
+    ml
+  }
+  final lazy val localMaxLengthValue: String = {
+    val ml = maxLength(xml)
+    // Xerces checks for the case where length and min/maxLength are used 
together,
+    // so we won't get to this code in those cases unless Xerces validation is 
turned off
+    Assert.usage(
+      ml.isEmpty || localLengthValue.isEmpty,
+      "Facets length and maxLength cannot be specified together",
+    )
+    ml
+  }
   final lazy val localTotalDigitsValue: String = totalDigits(xml)
   final lazy val localFractionDigitsValue: String = fractionDigits(xml)
   final lazy val localEnumerationValue: String = {
@@ -140,6 +162,8 @@ trait Facets { self: Restriction =>
     (localEnumerationValue.length > 0) || 
(getRemoteFacetValues(Facet.enumeration).size > 0)
   final lazy val hasPattern: Boolean =
     (localPatternValue.length > 0) || 
(getRemoteFacetValues(Facet.pattern).size > 0)
+  final lazy val hasLength: Boolean =
+    (localLengthValue != "") || (getRemoteFacetValues(Facet.length).size > 0)
   final lazy val hasMinLength: Boolean =
     (localMinLengthValue != "") || (getRemoteFacetValues(Facet.minLength).size 
> 0)
   final lazy val hasMaxLength: Boolean =
@@ -230,6 +254,8 @@ trait Facets { self: Restriction =>
   // TODO: Tidy up.  Can likely replace getFacetValue with a similar call to 
combinedBaseFacets
   // as combinedBaseFacets should contain the 'narrowed' values.
   //
+  final lazy val lengthValue: java.math.BigDecimal =
+    getFacetValue(localLengthValue, Facet.length, hasLength)
   final lazy val minLengthValue: java.math.BigDecimal =
     getFacetValue(localMinLengthValue, Facet.minLength, hasMinLength)
   final lazy val maxLengthValue: java.math.BigDecimal =
@@ -247,12 +273,6 @@ trait Facets { self: Restriction =>
   final lazy val fractionDigitsValue: java.math.BigDecimal =
     getFacetValue(localFractionDigitsValue, Facet.fractionDigits, 
hasFractionDigits)
 
-  //  private def errorOnLocalLessThanBaseFacet(local: Long, base: Long, 
theFacetType: Facet.Type) = {
-  //    if (local < base) SDE("SimpleTypes: The local %s (%s) was less than 
the base %s (%s) ", theFacetType, local, theFacetType, base)
-  //  }
-  //  private def errorOnLocalGreaterThanBaseFacet(local: Long, base: Long, 
theFacetType: Facet.Type) = {
-  //    if (local > base) SDE("SimpleTypes: The local %s (%s) was greater than 
the base %s (%s) ", theFacetType, local, theFacetType, base)
-  //  }
   private def errorOnLocalLessThanBaseFacet(
     local: BigInteger,
     base: BigInteger,
@@ -313,14 +333,21 @@ trait Facets { self: Restriction =>
         base,
       )
   }
-
-  //  private def getRemoteFacets(theFacetType: Facet.Type): Seq[FacetValueR] 
= {
-  //    val remoteValues = remoteBaseFacets.filter { case (f, _) => f == 
theFacetType }
-  //    if (remoteValues.size > 0) {
-  //      val res: Seq[FacetValueR] = remoteValues.map { case (f, v) => (f, 
v.r) }
-  //      res
-  //    } else Seq.empty
-  //  }
+  private def errorOnLocalNotEqualToBaseFacet(
+    local: BigInteger,
+    base: BigInteger,
+    theFacetType: Facet.Type,
+  ) = {
+    val res = local.compareTo(base)
+    if (res != 0)
+      SDE(
+        "SimpleTypes: The local %s (%s) was not equal to the base %s (%s) ",
+        theFacetType,
+        local,
+        theFacetType,
+        base,
+      )
+  }
 
   private def getRemoteFacetValues(theFacetType: Facet.Type): Seq[FacetValue] 
= {
     val res = remoteBaseFacets.filter { case (f, _) => f == theFacetType }
@@ -387,6 +414,10 @@ trait Facets { self: Restriction =>
         errorOnLocalLessThanBaseFacet(theLocalFacet, theRemoteFacet, facetType)
         localFacet
       }
+      case Facet.length => {
+        errorOnLocalNotEqualToBaseFacet(theLocalFacet, theRemoteFacet, 
facetType)
+        localFacet
+      }
       case Facet.maxLength | Facet.fractionDigits => {
         errorOnLocalGreaterThanBaseFacet(theLocalFacet, theRemoteFacet, 
facetType)
         localFacet
@@ -679,7 +710,7 @@ trait Facets { self: Restriction =>
     //  a negative number, zero, or a positive number as this BigInteger is 
numerically less than,
     //  equal to, or greater than o, which must be a BigInteger.
     facetType match {
-      case Facet.minLength | Facet.maxLength | Facet.fractionDigits => {
+      case Facet.length | Facet.minLength | Facet.maxLength | 
Facet.fractionDigits => {
         // Non-negative Integers.  BigInt
         narrowNonNegativeFacets(localFacet, remoteFacet, facetType)
       }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RestrictionUnion.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RestrictionUnion.scala
index 2bd168fea..72a49cdba 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RestrictionUnion.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RestrictionUnion.scala
@@ -118,6 +118,9 @@ final class Restriction private (xmlArg: Node, val 
simpleTypeDef: SimpleTypeDefB
   lazy val localBaseFacets: ElemFacets = {
     val myFacets: Queue[FacetValue] = Queue.empty // val not var - it's a 
mutable collection
     if (localPatternValue.length > 0) { myFacets.enqueue((Facet.pattern, 
localPatternValue)) }
+    if (localLengthValue.length > 0) {
+      myFacets.enqueue((Facet.length, localLengthValue))
+    }
     if (localMinLengthValue.length > 0) {
       myFacets.enqueue((Facet.minLength, localMinLengthValue))
     }
@@ -163,6 +166,10 @@ final class Restriction private (xmlArg: Node, val 
simpleTypeDef: SimpleTypeDefB
       val cPattern = lPattern.union(rPattern)
       cPattern.foreach(x => combined.enqueue(x))
     }
+    if (hasLength) {
+      val cValue = getCombinedValue(Facet.length)
+      combined.enqueue((Facet.length, cValue.toString()))
+    }
     if (hasMinLength) {
       val cValue = getCombinedValue(Facet.minLength)
       combined.enqueue((Facet.minLength, cValue.toString()))
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
index 7541ee495..7462251ec 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
@@ -147,7 +147,7 @@ abstract class SimpleTypeDefBase(xml: Node, lexicalParent: 
SchemaComponent)
     optRestriction
       .map { r =>
         if (
-          r.hasPattern || r.hasEnumeration || r.hasMinLength || r.hasMaxLength 
||
+          r.hasPattern || r.hasEnumeration || r.hasLength || r.hasMinLength || 
r.hasMaxLength ||
           r.hasMinInclusive || r.hasMaxInclusive || r.hasMinExclusive || 
r.hasMaxExclusive ||
           r.hasTotalDigits || r.hasFractionDigits
         ) false
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
index f94daf153..9177c7d25 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
@@ -1616,29 +1616,33 @@ trait ElementBaseGrammarMixin
      * the type is a type that respects minLength and maxLength, and the 
constant length
      * is not in range.
      */
-    val isTypeUsingMinMaxLengthFacets = typeDef.typeNode match {
+    val isTypeUsingLengthOrMinMaxLengthFacets = typeDef.typeNode match {
       case s: NodeInfo.String.Kind => true
       case s: NodeInfo.HexBinary.Kind => true
       case _ => false
     }
     if (
       (lengthKind eq LengthKind.Explicit) &&
-      isTypeUsingMinMaxLengthFacets &&
+      isTypeUsingLengthOrMinMaxLengthFacets &&
       optLengthConstant.isDefined
     ) {
       val len = optLengthConstant.get
-      val maxLengthLong = maxLength.longValueExact
-      val minLengthLong = minLength.longValueExact
+      lazy val maxLengthLong = maxLength.longValueExact
+      lazy val minLengthLong = minLength.longValueExact
       def warn(m: String, value: Long): Unit = SDW(
         WarnID.FacetExplicitLengthOutOfRange,
-        "Explicit dfdl:length of %s is out of range for facet %sLength='%s'.",
+        "Explicit dfdl:length of %s is out of range for facet %s='%s'.",
         len,
         m,
         value,
       )
-      if (maxLengthLong != -1 && len > maxLengthLong) warn("max", 
maxLengthLong)
-      Assert.invariant(minLengthLong >= 0)
-      if (minLengthLong > 0 && len < minLengthLong) warn("min", minLengthLong)
+      if (hasLength && len != minLengthLong && len != maxLengthLong)
+        warn("length", minLengthLong)
+      else if (hasMinLength || hasMaxLength) {
+        if (maxLengthLong != -1 && len > maxLengthLong) warn("maxLength", 
maxLengthLong)
+        Assert.invariant(minLengthLong >= 0)
+        if (minLengthLong > 0 && len < minLengthLong) warn("minLength", 
minLengthLong)
+      }
     }
 
     /*
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
index e16efdda3..ca61e68b1 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
@@ -34,6 +34,7 @@ trait SimpleTypeRuntime1Mixin { self: SimpleTypeDefBase =>
         noFacetChecks,
         optRestriction.toSeq.flatMap { r => if (r.hasPattern) r.patternValues 
else Nil },
         optRestriction.flatMap { r => toOpt(r.hasEnumeration, 
r.enumerationValues.get) },
+        optRestriction.flatMap { r => toOpt(r.hasLength, r.lengthValue) },
         optRestriction.flatMap { r => toOpt(r.hasMinLength, r.minLengthValue) 
},
         optRestriction.flatMap { r => toOpt(r.hasMaxLength, r.maxLengthValue) 
},
         optRestriction.flatMap { r => toOpt(r.hasMinInclusive, 
r.minInclusiveValue) },
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/Facets1.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/Facets1.scala
index 76c889430..15bf73f7d 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/Facets1.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/Facets1.scala
@@ -24,6 +24,7 @@ object Facet extends Enum {
   sealed abstract trait Type extends EnumValueType
   case object enumeration extends Type
   case object fractionDigits extends Type
+  case object length extends Type
   case object maxExclusive extends Type
   case object maxInclusive extends Type
   case object maxLength extends Type
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
index 08135c1f1..f7fd63a6f 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
@@ -229,6 +229,7 @@ final class SimpleTypeRuntimeData(
   val noFacetChecks: Boolean,
   val patternValues: Seq[FacetTypes.FacetValueR],
   val enumerationValues: Option[String],
+  val length: Option[java.math.BigDecimal],
   val minLength: Option[java.math.BigDecimal],
   val maxLength: Option[java.math.BigDecimal],
   val minInclusive: Option[java.math.BigDecimal],
@@ -345,24 +346,20 @@ final class SimpleTypeRuntimeData(
         return Error("facet enumeration(s): 
%s".format(e.enumerationValues.mkString(",")))
       }
     }
-
+    // Check length
+    e.length.foreach { length =>
+      if (!checkLength(currentElement, length, e, primType))
+        return Error("facet length (%s)".format(length))
+    }
     // Check minLength
     e.minLength.foreach { minLength =>
-      val minAsLong = minLength.longValue()
-      val isMinLengthGreaterThanEqToZero = minAsLong.compareTo(0L) >= 0
-      if (isMinLengthGreaterThanEqToZero) {
-        if (!checkMinLength(currentElement, minLength, e, primType))
-          return Error("facet minLength (%s)".format(minLength))
-      }
+      if (!checkMinLength(currentElement, minLength, e, primType))
+        return Error("facet minLength (%s)".format(minLength))
     }
     // Check maxLength
     e.maxLength.foreach { maxLength =>
-      val maxAsLong = maxLength.longValue()
-      val isMaxLengthGreaterThanEqToZero = maxAsLong.compareTo(0L) >= 0
-      if (isMaxLengthGreaterThanEqToZero) {
-        if (!checkMaxLength(currentElement, maxLength, e, primType))
-          return Error("facet maxLength (%s)".format(maxLength))
-      }
+      if (!checkMaxLength(currentElement, maxLength, e, primType))
+        return Error("facet maxLength (%s)".format(maxLength))
     }
     // Check minInclusive
     e.minInclusive.foreach { minInclusive =>
@@ -407,7 +404,32 @@ final class SimpleTypeRuntimeData(
     // Note: dont check occurs counts // if(!checkMinMaxOccurs(e, 
pstate.arrayIterationPos)) { return java.lang.Boolean.FALSE }
     OK
   }
+  private def checkLength(
+    diNode: DISimple,
+    lenValue: java.math.BigDecimal,
+    e: ThrowsSDE,
+    primType: PrimType,
+  ): java.lang.Boolean = {
+    val lenAsLong = lenValue.longValueExact()
+    primType match {
+      case PrimType.String => {
+        val data = diNode.dataValue.getString
+        val dataLen = data.length.toLong
+        val isDataLengthEqual = dataLen.compareTo(lenAsLong) == 0
+        if (isDataLengthEqual) java.lang.Boolean.TRUE
+        else java.lang.Boolean.FALSE
+      }
+      case PrimType.HexBinary => {
+        val data = diNode.dataValue.getByteArray
 
+        val dataLen = data.length.toLong
+        val isDataLengthEqual = dataLen.compareTo(lenAsLong) == 0
+        if (isDataLengthEqual) java.lang.Boolean.TRUE
+        else java.lang.Boolean.FALSE
+      }
+      case _ => e.SDE("Facet length is only valid for string and hexBinary.")
+    }
+  }
   private def checkMinLength(
     diNode: DISimple,
     minValue: java.math.BigDecimal,
@@ -431,7 +453,7 @@ final class SimpleTypeRuntimeData(
         if (isDataLengthEqual) java.lang.Boolean.TRUE
         else java.lang.Boolean.FALSE
       }
-      case _ => e.SDE("MinLength facet is only valid for string and 
hexBinary.")
+      case _ => e.SDE("Facet minLength is only valid for string and 
hexBinary.")
     }
   }
 
@@ -460,7 +482,7 @@ final class SimpleTypeRuntimeData(
         if (isDataLengthEqual) java.lang.Boolean.TRUE
         else java.lang.Boolean.FALSE
       }
-      case _ => e.SDE("MaxLength facet is only valid for string and 
hexBinary.")
+      case _ => e.SDE("Facet maxLength is only valid for string and 
hexBinary.")
     }
   }
 
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/repType/repType.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/repType/repType.tdml
index b1b21f8b4..6c1f9f549 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/repType/repType.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/repType/repType.tdml
@@ -758,7 +758,7 @@
           <xs:element name="field" dfdlx:repType="tns:rep">
             <xs:simpleType>
               <xs:restriction base="xs:string">
-                <!-- "t" is actually the only valid value due to min/maxLength 
-->
+                <!-- "one" is actually the only valid value due to 
min/maxLength -->
                 <xs:enumeration value="one" dfdlx:repValues="1" />
                 <xs:enumeration value="t" dfdlx:repValues="2" />
                 <xs:enumeration value="three" dfdlx:repValues="3" />
@@ -771,9 +771,29 @@
       </xs:complexType>
     </xs:element>
 
+    <xs:element name="root2">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="field" dfdlx:repType="tns:rep">
+            <xs:simpleType>
+              <xs:restriction base="xs:string">
+                <!-- "t" is actually the only valid value due to length -->
+                <xs:enumeration value="one" dfdlx:repValues="1" />
+                <xs:enumeration value="t" dfdlx:repValues="2" />
+                <xs:enumeration value="three" dfdlx:repValues="3" />
+                <xs:length value="1" />
+              </xs:restriction>
+            </xs:simpleType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
   </tdml:defineSchema>
 
-  <tdml:parserTestCase name="repType_length_facet_01" 
model="repType-LengthFacets.dfdl.xsd" validation="limited">
+  <tdml:parserTestCase name="repType_length_facet_01"
+                       root="root1"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
     <tdml:document>
       <tdml:documentPart type="byte">01</tdml:documentPart>
     </tdml:document>
@@ -786,7 +806,9 @@
     </tdml:infoset>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="repType_length_facet_02" 
model="repType-LengthFacets.dfdl.xsd" validation="limited">
+  <tdml:parserTestCase name="repType_length_facet_02"
+                       root="root1"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
     <tdml:document>
       <tdml:documentPart type="byte">02</tdml:documentPart>
     </tdml:document>
@@ -804,7 +826,9 @@
     </tdml:validationErrors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="repType_length_facet_03" 
model="repType-LengthFacets.dfdl.xsd" validation="limited">
+  <tdml:parserTestCase name="repType_length_facet_03"
+                       root="root1"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
     <tdml:document>
       <tdml:documentPart type="byte">03</tdml:documentPart>
     </tdml:document>
@@ -822,6 +846,59 @@
     </tdml:validationErrors>
   </tdml:parserTestCase>
 
+  <tdml:parserTestCase name="repType_length_facet_04"
+                       root="root2"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
+    <tdml:document>
+      <tdml:documentPart type="byte">01</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <root2>
+          <field>one</field>
+        </root2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:validationErrors>
+      <tdml:error>ex:field</tdml:error>
+      <tdml:error>facet length (1)</tdml:error>
+    </tdml:validationErrors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="repType_length_facet_05"
+                       root="root2"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
+    <tdml:document>
+      <tdml:documentPart type="byte">02</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <root2>
+          <field>t</field>
+        </root2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="repType_length_facet_06"
+                       root="root2"
+                       model="repType-LengthFacets.dfdl.xsd" 
validation="limited">
+    <tdml:document>
+      <tdml:documentPart type="byte">03</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <root2>
+          <field>three</field>
+        </root2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:validationErrors>
+      <tdml:error>ex:field</tdml:error>
+      <tdml:error>facet length (1)</tdml:error>
+    </tdml:validationErrors>
+  </tdml:parserTestCase>
+
   <tdml:defineSchema name="repType-Negative.dfdl.xsd">
 
     <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
index 25c6c677a..982cd1b29 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
@@ -385,7 +385,24 @@
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
-    
+
+    <xs:element name="eString_minMaxLen7" dfdl:lengthKind="implicit" 
dfdl:inputValueCalc="{ 'string' }">
+      <xs:simpleType>
+          <xs:restriction base="xs:string">
+              <xs:minLength value="7"/>
+              <xs:maxLength value="7"/>
+          </xs:restriction>
+      </xs:simpleType>
+    </xs:element>
+
+    <xs:element name="eString_len7" dfdl:lengthKind="implicit" 
dfdl:inputValueCalc="{ 'string' }">
+      <xs:simpleType>
+          <xs:restriction base="xs:string">
+              <xs:length value="7"/>
+          </xs:restriction>
+      </xs:simpleType>
+    </xs:element>
+
     <xs:element name="e3" dfdl:lengthKind="delimited" dfdl:inputValueCalc="{ 
'string' }">
       <xs:simpleType>
         <xs:restriction base="xs:string">
@@ -396,7 +413,7 @@
 
   </tdml:defineSchema>
 
-  <tdml:defineSchema name="TestFacets">
+    <tdml:defineSchema name="TestFacets">
     <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" />
 
@@ -407,8 +424,47 @@
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
-    
-    <xs:element name="e3_2" dfdl:lengthKind="delimited">
+
+    <xs:element name="eHexBinary_minMaxLen7" dfdl:lengthKind="delimited" 
dfdl:encoding="iso-8859-1">
+        <xs:simpleType>
+            <xs:restriction base="xs:hexBinary">
+                <xs:minLength value="7"/>
+                <xs:maxLength value="7"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:element>
+
+    <xs:element name="eHexBinary_len7" dfdl:lengthKind="delimited" 
dfdl:encoding="iso-8859-1">
+        <xs:simpleType>
+            <xs:restriction base="xs:hexBinary">
+                <xs:length value="7"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:element>
+
+    <xs:element name="eHexBinary_len0" dfdl:lengthKind="delimited" 
dfdl:encoding="iso-8859-1">
+        <xs:simpleType>
+            <xs:restriction base="xs:hexBinary">
+                <xs:length value="0"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:element>
+
+     <xs:element name="eString_localLen2" dfdl:lengthKind="implicit">
+        <xs:simpleType>
+            <xs:restriction base="ex:stringBaseLen2">
+                <xs:length value="2"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:element>
+
+    <xs:simpleType name="stringBaseLen2">
+        <xs:restriction base="xs:string">
+            <xs:length value="2"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+      <xs:element name="e3_2" dfdl:lengthKind="delimited">
       <xs:simpleType>
         <xs:restriction base="ex:stMaxLength_2">
           <xs:maxLength value="1" />
@@ -643,7 +699,111 @@
 
                </tdml:validationErrors>
   </tdml:parserTestCase>
-  
+
+    <tdml:parserTestCase name="validation_testFacets_01"
+                         root="eHexBinary_minMaxLen7" model="TestFacets"
+                         description="validates hexBinary against 
min/maxLength facet"
+                         validation="limited">
+
+    <tdml:document>
+        <tdml:documentPart type="byte">deadbeefdafada</tdml:documentPart>
+    </tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                
<ex:eHexBinary_minMaxLen7>DEADBEEFDAFADA</ex:eHexBinary_minMaxLen7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_testFacets_02"
+                         root="eHexBinary_len7" model="TestFacets"
+                         description="validates hexBinary against length facet"
+                         validation="limited">
+
+    <tdml:document>
+        <tdml:documentPart type="byte">deadbeefdafada</tdml:documentPart>
+    </tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <ex:eHexBinary_len7>DEADBEEFDAFADA</ex:eHexBinary_len7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_testFacets_03"
+                         root="eHexBinary_len0" model="TestFacets"
+                         description="validates against length facet"
+                         validation="limited">
+
+        <tdml:document>
+            <tdml:documentPart type="byte">deadbeefdafada</tdml:documentPart>
+        </tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <ex:eHexBinary_len0>DEADBEEFDAFADA</ex:eHexBinary_len0>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+        <tdml:validationErrors>
+
+            <tdml:error>eHexBinary_len0</tdml:error>
+            <tdml:error>failed facet checks</tdml:error>
+            <tdml:error>facet length (0)</tdml:error>
+
+        </tdml:validationErrors>
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_testFacets_04"
+                         root="eString_localLen2" model="TestFacets"
+                         description="verify local length must be equal to 
base length"
+                         validation="limited">
+
+        <tdml:document>12</tdml:document>
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <eString_localLen2>12</eString_localLen2>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+    </tdml:parserTestCase>
+
+    <tdml:defineSchema name="TestFacets3">
+        <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+        <dfdl:format ref="ex:GeneralFormat" />
+        <xs:element name="eString_localLen1" dfdl:lengthKind="implicit">
+            <xs:simpleType>
+                <xs:restriction base="ex:stringBaseLen2">
+                    <xs:length value="1"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:element>
+
+        <xs:simpleType name="stringBaseLen2">
+            <xs:restriction base="xs:string">
+                <xs:length value="2"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </tdml:defineSchema>
+
+    <tdml:parserTestCase name="validation_testFacets3_01"
+                         root="eString_localLen1" model="TestFacets3"
+                         description="verify local length must be equal to 
base length"
+                         validation="limited">
+
+        <tdml:document>12</tdml:document>
+
+        <tdml:errors>
+            <tdml:error>Schema Definition Error</tdml:error>
+            <tdml:error>length-valid-restriction</tdml:error>
+            <tdml:error>value of length</tdml:error>
+            <tdml:error>must be = the value of that of the base 
type</tdml:error>
+        </tdml:errors>
+    </tdml:parserTestCase>
+
+
 <!--
     Test name: checkEnumeration_Pass_limited
        Schema: TestFacets
@@ -1921,7 +2081,139 @@
 
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="floatExclusiveValid"
+    <tdml:parserTestCase name="validation_inputValueCalc_04"
+                         root="eString_minMaxLen7" model="inputValueCalc"
+                         description="Section 17 - the value created using 
inputValueCalc is validated using minLength/maxLength facets"
+                         validation="limited">
+
+        <tdml:document></tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <eString_minMaxLen7>string</eString_minMaxLen7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+        <tdml:validationErrors>
+            <tdml:error>Validation Error</tdml:error>
+            <tdml:error>failed facet checks due to: facet minLength 
(7)</tdml:error>
+        </tdml:validationErrors>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_inputValueCalc_05"
+                         root="eString_len7" model="inputValueCalc"
+                         description="Section 17 - the value created using 
inputValueCalc is validated using length facets"
+                         validation="limited">
+
+        <tdml:document></tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <eString_len7>string</eString_len7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+        <tdml:validationErrors>
+            <tdml:error>Validation Error</tdml:error>
+            <tdml:error>failed facet checks due to: facet length 
(7)</tdml:error>
+        </tdml:validationErrors>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_inputValueCalc_06"
+                         root="eString_minMaxLen7" model="inputValueCalc"
+                         description="Section 17 - the value created using 
inputValueCalc is validated using minLength/maxLength facets"
+                         validation="on">
+
+        <tdml:document></tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <eString_minMaxLen7>string</eString_minMaxLen7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+        <tdml:validationErrors>
+            <tdml:error>Validation Error</tdml:error>
+            <tdml:error>failed facet checks due to: facet minLength 
(7)</tdml:error>
+        </tdml:validationErrors>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_inputValueCalc_07"
+                         root="eString_len7" model="inputValueCalc"
+                         description="Section 17 - the value created using 
inputValueCalc is validated using length facets"
+                         validation="on">
+
+        <tdml:document></tdml:document>
+
+        <tdml:infoset>
+            <tdml:dfdlInfoset>
+                <eString_len7>string</eString_len7>
+            </tdml:dfdlInfoset>
+        </tdml:infoset>
+
+        <tdml:validationErrors>
+            <tdml:error>Validation Error</tdml:error>
+            <tdml:error>failed facet checks due to: facet length 
(7)</tdml:error>
+        </tdml:validationErrors>
+
+    </tdml:parserTestCase>
+
+    <tdml:defineSchema name="TestFacets2">
+        <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+        <dfdl:format ref="ex:GeneralFormat" />
+        <xs:element name="eHexBinary_lenMinMaxLen7" 
dfdl:lengthKind="delimited" dfdl:encoding="ISO-8859-1">
+            <xs:simpleType>
+                <xs:restriction base="xs:hexBinary">
+                    <xs:length value="7"/>
+                    <xs:minLength value="7"/>
+                    <xs:maxLength value="7"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:element>
+    </tdml:defineSchema>
+
+    <tdml:parserTestCase name="validation_testFacets2_01"
+                         root="eHexBinary_lenMinMaxLen7" model="TestFacets2"
+                         description="checks that length cannot be used with 
min/maxLength"
+                         validation="limited">
+
+        <tdml:document>
+            <tdml:documentPart type="byte">deadbeef</tdml:documentPart>
+        </tdml:document>
+
+        <!-- this is a Xerces Error -->
+        <tdml:errors>
+            <tdml:error>Schema Definition Error</tdml:error>
+            <tdml:error>due to length-minLength-maxLength</tdml:error>
+            <tdml:error>not have a minLength facet if the current restriction 
has the minLength facet</tdml:error>
+            <tdml:error>and the current restriction or base has the length 
facet</tdml:error>
+        </tdml:errors>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="validation_testFacets2_02"
+                         root="eHexBinary_lenMinMaxLen7" model="TestFacets2"
+                         description="checks that length cannot be used with 
min/maxLength"
+                         validation="on">
+
+        <tdml:document>
+            <tdml:documentPart type="byte">deadbeef</tdml:documentPart>
+        </tdml:document>
+
+        <!-- this is a Xerces Error -->
+        <tdml:errors>
+            <tdml:error>Schema Definition Error</tdml:error>
+            <tdml:error>due to length-minLength-maxLength</tdml:error>
+            <tdml:error>not have a minLength facet if the current restriction 
has the minLength facet</tdml:error>
+            <tdml:error>and the current restriction or base has the length 
facet</tdml:error>
+        </tdml:errors>
+
+    </tdml:parserTestCase>
+
+    <tdml:parserTestCase name="floatExclusiveValid"
     root="floatExclusive" model="TestFacets"
     validation="on">
 
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberPropsUnparse.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberPropsUnparse.tdml
index f274703fd..da2cadfba 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberPropsUnparse.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberPropsUnparse.tdml
@@ -96,6 +96,12 @@
           <xs:minLength value="10" />
         </xs:restriction>
       </xs:simpleType>
+
+      <xs:simpleType name="stLen10">
+        <xs:restriction base="xs:string">
+          <xs:length value="10" />
+        </xs:restriction>
+      </xs:simpleType>
       
       <xs:simpleType name="st3to10">
         <xs:restriction base="xs:string">
@@ -117,7 +123,9 @@
       <xs:element name="e11" type="ex:st10" dfdl:lengthKind="explicit" 
dfdl:length="2" dfdl:textStringPadCharacter="#" dfdl:textPadKind="padChar" 
dfdl:textTrimKind="padChar" dfdl:textStringJustification="left" />
       
       <xs:element name="e12" type="ex:st10" dfdl:lengthKind="explicit" 
dfdl:length="{ 2 }" dfdl:textStringPadCharacter="#" dfdl:textPadKind="padChar" 
dfdl:textTrimKind="padChar" dfdl:textStringJustification="left" />
-      
+
+      <xs:element name="e12_dfdlLength2" type="ex:stLen10" 
dfdl:lengthKind="explicit" dfdl:length="{ 2 }" dfdl:textStringPadCharacter="#" 
dfdl:textPadKind="padChar" dfdl:textTrimKind="padChar" 
dfdl:textStringJustification="left" />
+
       <xs:element name="e13" dfdl:lengthKind="implicit">
         <xs:complexType>
           <xs:sequence  dfdl:separator="," >
@@ -441,6 +449,23 @@
     <tdml:document>O#</tdml:document>
   </tdml:unparserTestCase>
 
+  <tdml:unparserTestCase name="unparsePaddedString11" 
model="delimitedStringsPadding" root="e12_dfdlLength2"
+                         description="ensure length facet results in a similar 
warning to min/maxLength facets"
+   roundTrip="false">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e12_dfdlLength2 
xmlns:ex="http://example.com";>O</ex:e12_dfdlLength2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:warnings>
+      <tdml:warning>Schema Definition Warning</tdml:warning>
+      <tdml:warning>Explicit dfdl:length</tdml:warning>
+      <tdml:warning>out of range</tdml:warning>
+      <tdml:warning>facet length</tdml:warning>
+    </tdml:warnings>
+    <tdml:document>O#</tdml:document>
+  </tdml:unparserTestCase>
+
 <!--
       Test Name: unparseDelimitedPaddedString11
       Schema: delimitedStringsPadding
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestRepType.scala 
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestRepType.scala
index bf5fe5abb..bc8fe4e76 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestRepType.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestRepType.scala
@@ -94,6 +94,15 @@ class TestRepType {
   @Test def test_repType_length_facet_03(): Unit = {
     runner.runOneTest("repType_length_facet_03")
   }
+  @Test def test_repType_length_facet_04(): Unit = {
+    runner.runOneTest("repType_length_facet_04")
+  }
+  @Test def test_repType_length_facet_05(): Unit = {
+    runner.runOneTest("repType_length_facet_05")
+  }
+  @Test def test_repType_length_facet_06(): Unit = {
+    runner.runOneTest("repType_length_facet_06")
+  }
 
   @Test def test_repType_negative_01(): Unit = { 
runner.runOneTest("repType_negative_01") }
   @Test def test_repType_negative_02(): Unit = { 
runner.runOneTest("repType_negative_02") }
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section02/validation_errors/TestValidationErr.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section02/validation_errors/TestValidationErr.scala
index d1fef3f67..352be0aa7 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section02/validation_errors/TestValidationErr.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section02/validation_errors/TestValidationErr.scala
@@ -168,6 +168,41 @@ class TestValidationErr {
   @Test def test_validation_inputValueCalc_03(): Unit = {
     runner.runOneTest("validation_inputValueCalc_03")
   }
+  @Test def test_validation_inputValueCalc_04(): Unit = {
+    runner.runOneTest("validation_inputValueCalc_04")
+  }
+  @Test def test_validation_inputValueCalc_05(): Unit = {
+    runner.runOneTest("validation_inputValueCalc_05")
+  }
+  @Test def test_validation_inputValueCalc_06(): Unit = {
+    runner.runOneTest("validation_inputValueCalc_06")
+  }
+  @Test def test_validation_inputValueCalc_07(): Unit = {
+    runner.runOneTest("validation_inputValueCalc_07")
+  }
+
+  @Test def test_validation_testFacets_01(): Unit = {
+    runner.runOneTest("validation_testFacets_01")
+  }
+  @Test def test_validation_testFacets_02(): Unit = {
+    runner.runOneTest("validation_testFacets_02")
+  }
+  @Test def test_validation_testFacets_03(): Unit = {
+    runner.runOneTest("validation_testFacets_03")
+  }
+  @Test def test_validation_testFacets_04(): Unit = {
+    runner.runOneTest("validation_testFacets_04")
+  }
+  @Test def test_validation_testFacets2_01(): Unit = {
+    runner.runOneTest("validation_testFacets2_01")
+  }
+  @Test def test_validation_testFacets2_02(): Unit = {
+    runner.runOneTest("validation_testFacets2_02")
+  }
+
+  @Test def test_validation_testFacets3_01(): Unit = {
+    runner.runOneTest("validation_testFacets3_01")
+  }
 
   @Test def test_floatExclusiveValid(): Unit = { 
runner.runOneTest("floatExclusiveValid") }
   @Test def test_floatExclusiveInf(): Unit = { 
runner.runOneTest("floatExclusiveInf") }
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section13/text_number_props/TestTextNumberPropsUnparse.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section13/text_number_props/TestTextNumberPropsUnparse.scala
index 71a1bbd4e..ff83769f5 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section13/text_number_props/TestTextNumberPropsUnparse.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section13/text_number_props/TestTextNumberPropsUnparse.scala
@@ -76,6 +76,7 @@ class TestTextNumberPropsUnparse {
   }
 
   @Test def test_unparsePaddedString10(): Unit = { 
runner.runOneTest("unparsePaddedString10") }
+  @Test def test_unparsePaddedString11(): Unit = { 
runner.runOneTest("unparsePaddedString11") }
 
   @Test def test_unparsePaddedStringTruncate01(): Unit = {
     runner.runOneTest("unparsePaddedStringTruncate01")

Reply via email to