summary refs log tree commit diff stats
path: root/tools/nimsuggest/tester.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2016-10-31 20:12:54 +0100
committerAraq <rumpf_a@web.de>2016-10-31 20:12:54 +0100
commit08c94ef6b5beb3afb43787b406c61b0795ce66e2 (patch)
tree66a665e6c4d427e9bd771862fcd26bf40d470460 /tools/nimsuggest/tester.nim
parent29db0d8585a0b2d3297a1e7745bfb92bf0c943b7 (diff)
downloadNim-08c94ef6b5beb3afb43787b406c61b0795ce66e2.tar.gz
nimsuggest is now part of Nim
Diffstat (limited to 'tools/nimsuggest/tester.nim')
-rw-r--r--tools/nimsuggest/tester.nim99
1 files changed, 99 insertions, 0 deletions
diff --git a/tools/nimsuggest/tester.nim b/tools/nimsuggest/tester.nim
new file mode 100644
index 000000000..70a7da5b2
--- /dev/null
+++ b/tools/nimsuggest/tester.nim
@@ -0,0 +1,99 @@
+# Tester for nimsuggest.
+# Every test file can have a #[!]# comment that is deleted from the input
+# before 'nimsuggest' is invoked to ensure this token doesn't make a
+# crucial difference for Nim's parser.
+
+import os, osproc, strutils, streams, re
+
+type
+  Test = object
+    cmd: string
+    script: seq[(string, string)]
+
+const
+  curDir = when defined(windows): "" else: "./"
+  DummyEof = "!EOF!"
+
+proc parseTest(filename: string): Test =
+  const cursorMarker = "#[!]#"
+  let nimsug = curDir & addFileExt("nimsuggest", ExeExt)
+  let dest = getTempDir() / extractFilename(filename)
+  result.cmd = nimsug & " --tester " & dest
+  result.script = @[]
+  var tmp = open(dest, fmWrite)
+  var specSection = 0
+  var markers = newSeq[string]()
+  var i = 1
+  for x in lines(filename):
+    let marker = x.find(cursorMarker)+1
+    if marker > 0:
+      markers.add filename & ";" & dest & ":" & $i & ":" & $marker
+      tmp.writeLine x.replace(cursorMarker, "")
+    else:
+      tmp.writeLine x
+    if x.contains("""""""""):
+      inc specSection
+    elif specSection == 1:
+      if x.startsWith("$nimsuggest"):
+        result.cmd = x % ["nimsuggest", nimsug, "file", filename]
+      elif x.startsWith(">"):
+        # since 'markers' here are not complete yet, we do the $substitutions
+        # afterwards
+        result.script.add((x.substr(1), ""))
+      else:
+        # expected output line:
+        let x = x % ["file", filename]
+        result.script[^1][1].add x.replace(";;", "\t") & '\L'
+    inc i
+  tmp.close()
+  # now that we know the markers, substitute them:
+  for a in mitems(result.script):
+    a[0] = a[0] % markers
+
+proc smartCompare(pattern, x: string): bool =
+  if pattern.contains('*'):
+    result = match(x, re(escapeRe(pattern).replace("\\x2A","(.*)"), {}))
+
+proc runTest(filename: string): int =
+  let s = parseTest filename
+  let cl = parseCmdLine(s.cmd)
+  var p = startProcess(command=cl[0], args=cl[1 .. ^1],
+                       options={poStdErrToStdOut, poUsePath,
+                       poInteractive, poDemon})
+  let outp = p.outputStream
+  let inp = p.inputStream
+  var report = ""
+  var a = newStringOfCap(120)
+  try:
+    # read and ignore anything nimsuggest says at startup:
+    while outp.readLine(a):
+      if a == DummyEof: break
+    for req, resp in items(s.script):
+      inp.writeLine(req)
+      inp.flush()
+      var answer = ""
+      while outp.readLine(a):
+        if a == DummyEof: break
+        answer.add a
+        answer.add '\L'
+      if resp != answer and not smartCompare(resp, answer):
+        report.add "\nTest failed: " & filename
+        report.add "\n  Expected:  " & resp
+        report.add "\n  But got:   " & answer
+  finally:
+    inp.writeLine("quit")
+    inp.flush()
+    close(p)
+  if report.len > 0:
+    echo report
+  result = report.len
+
+proc main() =
+  var failures = 0
+  for x in walkFiles("tests/t*.nim"):
+    echo "Test ", x
+    failures += runTest(expandFilename(x))
+  if failures > 0:
+    quit 1
+
+main()