summary refs log tree commit diff stats
path: root/tools/nimsuggest/tester.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-02-19 21:29:41 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-02-19 21:29:41 +0100
commit2adb4ce9eb7e8da0b6d219f6e501520f1c9f7743 (patch)
tree7d42ff8c2c4f8954c5dc11e8fdf66b58d1f56dd2 /tools/nimsuggest/tester.nim
parentba29ca0c63e50a06baf5935235b85e4ddc28fc96 (diff)
downloadNim-2adb4ce9eb7e8da0b6d219f6e501520f1c9f7743.tar.gz
nimsuggest supports EPC protocol again; tester can test the EPC protocol
Diffstat (limited to 'tools/nimsuggest/tester.nim')
-rw-r--r--tools/nimsuggest/tester.nim120
1 files changed, 118 insertions, 2 deletions
diff --git a/tools/nimsuggest/tester.nim b/tools/nimsuggest/tester.nim
index 156d3ddb9..a773b1b36 100644
--- a/tools/nimsuggest/tester.nim
+++ b/tools/nimsuggest/tester.nim
@@ -3,7 +3,7 @@
 # before 'nimsuggest' is invoked to ensure this token doesn't make a
 # crucial difference for Nim's parser.
 
-import os, osproc, strutils, streams, re
+import os, osproc, strutils, streams, re, sexp, net
 
 type
   Test = object
@@ -133,6 +133,119 @@ proc smartCompare(pattern, x: string): bool =
   if pattern.contains('*'):
     result = match(x, re(escapeRe(pattern).replace("\\x2A","(.*)"), {}))
 
+proc sendEpcStr(socket: Socket; cmd: string) =
+  let s = cmd.find(' ')
+  doAssert s > 0
+  let cmd = "(call 567 " & cmd.substr(0, s) & escapeJson(cmd.substr(s+1)) & ")"
+  socket.send toHex(cmd.len, 6)
+  socket.send cmd
+
+proc recvEpc(socket: Socket): string =
+  var L = newStringOfCap(6)
+  if socket.recv(L, 6) != 6:
+    raise newException(ValueError, "recv A failed")
+  let x = parseHexInt(L)
+  result = newString(x)
+  if socket.recv(result, x) != x:
+    raise newException(ValueError, "recv B failed")
+
+proc sexpToAnswer(s: SexpNode): string =
+  result = ""
+  doAssert s.kind == SList
+  doAssert s.len >= 3
+  let m = s[2]
+  if m.kind != SList:
+    echo s
+  doAssert m.kind == SList
+  for a in m:
+    doAssert a.kind == SList
+    var first = true
+    #s.section,
+    #s.symkind,
+    #s.qualifiedPath.map(newSString),
+    #s.filePath,
+    #s.forth,
+    #s.line,
+    #s.column,
+    #s.doc
+    if a.len >= 8:
+      let section = a[0].getStr
+      let symk = a[1].getStr
+      let qp = a[2]
+      let file = a[3].getStr
+      let typ = a[4].getStr
+      let line = a[5].getNum
+      let col = a[6].getNum
+      let doc = a[7].getStr.escapeJson
+      result.add section
+      result.add '\t'
+      result.add symk
+      result.add '\t'
+      var i = 0
+      for aa in qp:
+        if i > 0: result.add '.'
+        result.add aa.getStr
+        inc i
+      result.add '\t'
+      result.add typ
+      result.add '\t'
+      result.add file
+      result.add '\t'
+      result.add line
+      result.add '\t'
+      result.add col
+      result.add '\t'
+      result.add doc
+      result.add '\t'
+      # for now Nim EPC does not return the quality
+      result.add "100"
+    result.add '\L'
+
+proc runEpcTest(filename: string): int =
+  let s = parseTest filename
+  for cmd in s.startup:
+    if not runCmd(cmd, s.dest):
+      quit "invalid command: " & cmd
+  let epccmd = s.cmd.replace("--tester", "--epc --v2")
+  let cl = parseCmdLine(epccmd)
+  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 the port number:
+    if outp.readLine(a):
+      let port = parseInt(a)
+      var socket = newSocket()
+      socket.connect("localhost", Port(port))
+      for req, resp in items(s.script):
+        if not runCmd(req, s.dest):
+          socket.sendEpcStr(req)
+          var answer = sexpToAnswer(parseSexp(socket.recvEpc()))
+          if resp != answer and not smartCompare(resp, answer):
+            report.add "\nTest failed: " & filename
+            var hasDiff = false
+            for i in 0..min(resp.len-1, answer.len-1):
+              if resp[i] != answer[i]:
+                report.add "\n  Expected:  " & resp.substr(i)
+                report.add "\n  But got:   " & answer.substr(i)
+                hasDiff = true
+                break
+            if not hasDiff:
+              report.add "\n  Expected:  " & resp
+              report.add "\n  But got:   " & answer
+    else:
+      raise newException(ValueError, "cannot read port number")
+  finally:
+    close(p)
+  if report.len > 0:
+    echo "==== EPC ========================================"
+    echo report
+  result = report.len
+
 proc runTest(filename: string): int =
   let s = parseTest filename
   for cmd in s.startup:
@@ -176,6 +289,7 @@ proc runTest(filename: string): int =
     inp.flush()
     close(p)
   if report.len > 0:
+    echo "==== STDIN ======================================"
     echo report
   result = report.len
 
@@ -183,7 +297,9 @@ proc main() =
   var failures = 0
   for x in walkFiles(getAppDir() / "tests/t*.nim"):
     echo "Test ", x
-    failures += runTest(expandFilename(x))
+    let xx = expandFilename x
+    failures += runTest(xx)
+    failures += runEpcTest(xx)
   if failures > 0:
     quit 1