/ test / commonTestUtils.nim
commonTestUtils.nim
  1  #            NimYAML - YAML implementation in Nim
  2  #        (c) Copyright 2015-2023 Felix Krause
  3  #
  4  #    See the file "copying.txt", included in this
  5  #    distribution, for details about the copyright.
  6  
  7  import ../yaml, ../yaml/data
  8  
  9  proc escapeNewlines(s: string): string =
 10    result = ""
 11    for c in s:
 12      case c
 13      of '\l': result.add("\\n")
 14      of '\t': result.add("\\t")
 15      of '\\': result.add("\\\\")
 16      else: result.add(c)
 17  
 18  proc printDifference(entity: string, expected, actual: Properties): bool =
 19    result = false
 20    if expected.tag != actual.tag:
 21      echo "[", entity, ".tag] expected ", $expected.tag, ", got ", $actual.tag
 22      result = true
 23    if expected.anchor != actual.anchor:
 24      echo "[", entity, ".anchor] expected ", $expected.anchor, ", got ", $actual.anchor
 25      result = true
 26  
 27  proc printDifference*(expected, actual: Event) =
 28    if expected.kind != actual.kind:
 29      echo "expected ", expected.kind, ", got ", $actual.kind
 30    else:
 31      case expected.kind
 32      of yamlScalar:
 33        if not printDifference("scalar", expected.scalarProperties, actual.scalarProperties):
 34          if expected.scalarContent != actual.scalarContent:
 35            let msg = "[scalarEvent] content mismatch!\nexpected: " &
 36                  escapeNewlines(expected.scalarContent) &
 37                  "\ngot     : " & escapeNewlines(actual.scalarContent)
 38            if expected.scalarContent.len != actual.scalarContent.len:
 39              echo msg, "\n(length does not match)"
 40            else:
 41              for i in 0..expected.scalarContent.high:
 42                if expected.scalarContent[i] != actual.scalarContent[i]:
 43                  echo msg, "\n(first different char at pos ", i, ": expected ",
 44                      cast[int](expected.scalarContent[i]), ", got ",
 45                      cast[int](actual.scalarContent[i]), ")"
 46                  break
 47          else: echo "[scalar] Unknown difference"
 48      of yamlStartMap:
 49        if not printDifference("map", expected.mapProperties, actual.mapProperties):
 50          echo "[map] Unknown difference"
 51      of yamlStartSeq:
 52        if not printDifference("seq", expected.seqProperties, actual.seqProperties):
 53          echo "[seq] Unknown difference"
 54      of yamlAlias:
 55        if expected.aliasTarget != actual.aliasTarget:
 56          echo "[alias] expected ", expected.aliasTarget, ", got ",
 57             actual.aliasTarget
 58        else: echo "[alias] Unknown difference"
 59      else: echo "Unknown difference in event kind " & $expected.kind
 60  
 61  template ensure*(input: var YamlStream,
 62                   expected: varargs[Event]) {.dirty.} =
 63    var i = 0
 64    for token in input:
 65      if i >= expected.len:
 66        echo "received more tokens than expected (next token = ", token.kind, ")"
 67        fail()
 68        break
 69      if token != expected[i]:
 70        echo "at event #" & $i & ":"
 71        printDifference(expected[i], token)
 72        fail()
 73        break
 74      i.inc()
 75  
 76  template assertStringEqual*(expected, actual: string) =
 77    if expected != actual:
 78      # if they are unequal, walk through the strings and check each
 79      # character for a better error message
 80      if expected.len != actual.len:
 81        echo "Expected and actual string's length differs.\n"
 82        echo "Expected length: ", expected.len, "\n"
 83        echo "Actual length: ", actual.len, "\n"
 84      # check length up to smaller of the two strings
 85      for i in countup(0, min(expected.high, actual.high)):
 86        if expected[i] != actual[i]:
 87          echo "string mismatch at character #", i, "(expected:\'",
 88           expected[i], "\', was \'", actual[i], "\'):\n"
 89          echo "expected:\n", expected, "\nactual:\n", actual, "\n"
 90          assert(false)
 91      # if we haven't raised an assertion error here, the problem is that
 92      # one string is longer than the other
 93      let minInd = min(expected.len, actual.len) # len instead of high to continue
 94                                                 # after shorter string
 95      if expected.high > actual.high:
 96        echo "Expected continues with: '", expected[minInd .. ^1], "'"
 97        assert false
 98      else:
 99        echo "Actual continues with: '", actual[minInd .. ^1], "'"
100        assert false