summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-06-11 00:32:27 +0200
committerAraq <rumpf_a@web.de>2013-06-11 00:32:27 +0200
commit38faa64b1270c22587b42095a4a28cba485e913a (patch)
tree653b608b4bcdb4e36add107b06b7c1a2a1e39e6d
parentc156f2d4938d6e79844a17ecad8c5c50b9c32354 (diff)
parent281424ddeda680aeed19d96db7724f92aa6d32c1 (diff)
downloadNim-38faa64b1270c22587b42095a4a28cba485e913a.tar.gz
Merge branch 'master' of github.com:Araq/Nimrod
-rw-r--r--.gitignore6
-rw-r--r--tests/caas/basic-recompile.txt5
-rw-r--r--tests/caas/compile-suggest.txt7
-rw-r--r--tests/caas/compile-then-def.txt8
-rw-r--r--tests/caas/def-def-compile.txt8
-rw-r--r--tests/caas/def-then-compile.txt4
-rw-r--r--tests/caas/idetools_api.nim23
-rw-r--r--tests/caas/idetools_api.txt41
-rw-r--r--tests/caas/issue_416.nim17
-rw-r--r--tests/caas/issue_416.txt14
-rw-r--r--tests/caas/issue_452.nim8
-rw-r--r--tests/caas/issue_452.txt11
-rw-r--r--tests/caas/suggest-compile.txt3
-rw-r--r--tests/caasdriver.nim158
-rw-r--r--tests/tester.nim5
15 files changed, 273 insertions, 45 deletions
diff --git a/.gitignore b/.gitignore
index 7bca71531..f05ca2016 100644
--- a/.gitignore
+++ b/.gitignore
@@ -167,4 +167,10 @@ examples/cross_calculator/android/tags
 /run.json
 /testresults.html
 /testresults.json
+/tests/caas/idetools_api
+/tests/caas/imported
+/tests/caas/issue_416
+/tests/caas/issue_452
+/tests/caas/main
+/tests/caasdriver
 /tools/nimgrep
diff --git a/tests/caas/basic-recompile.txt b/tests/caas/basic-recompile.txt
index 9c943fe88..d869944b9 100644
--- a/tests/caas/basic-recompile.txt
+++ b/tests/caas/basic-recompile.txt
@@ -2,6 +2,9 @@ main.nim
 > c
 SuccessX
 > c
-! Processing
+# The "Processing" string will be found always in proc mode since each
+# compilation command will generate it. We need to test it only in Caas mode to
+# verify the server is not recompiling again the file.
+CaasRun ! Processing
 SuccessX
 
diff --git a/tests/caas/compile-suggest.txt b/tests/caas/compile-suggest.txt
index 4e2ab9729..f90fc5aa1 100644
--- a/tests/caas/compile-suggest.txt
+++ b/tests/caas/compile-suggest.txt
@@ -1,7 +1,8 @@
 main.nim
 > c
 SuccessX
-> idetools --trackDirty:main_dirty.nim,main.nim,12,7 --suggest main.nim
-skField\tx
-skField\ty
+# Ugh, undocumented trackDirty, how is it supposed to work? Fails in proc mode.
+> idetools --trackDirty:main_dirty.nim,main.nim,12,7 --suggest
+CaasRun skField\tx
+CaasRun skField\ty
 
diff --git a/tests/caas/compile-then-def.txt b/tests/caas/compile-then-def.txt
index a5080c50d..839ca1532 100644
--- a/tests/caas/compile-then-def.txt
+++ b/tests/caas/compile-then-def.txt
@@ -1,9 +1,9 @@
 main.nim
 > c
 SuccessX
-> idetools --track:main.nim,5,18 --def main.nim
+> idetools --track:main.nim,5,18 --def
 strutils.toUpper
-SuccessX
-> idetools --track:main.nim,5,18 --def main.nim
+! SuccessX
+> idetools --track:main.nim,5,18 --def
 strutils.toUpper
-SuccessX
+! SuccessX
diff --git a/tests/caas/def-def-compile.txt b/tests/caas/def-def-compile.txt
index 64002aff1..05ea5a1aa 100644
--- a/tests/caas/def-def-compile.txt
+++ b/tests/caas/def-def-compile.txt
@@ -1,10 +1,10 @@
 main.nim
-> idetools --track:main.nim,5,18 --def main.nim
+> idetools --track:main.nim,5,18 --def
 strutils.toUpper
-SuccessX
-> idetools --track:main.nim,5,18 --def main.nim
+! SuccessX
+> idetools --track:main.nim,5,18 --def
 strutils.toUpper
-SuccessX
+! SuccessX
 > c
 SuccessX
 
diff --git a/tests/caas/def-then-compile.txt b/tests/caas/def-then-compile.txt
index efa4dcbb3..7e755cff2 100644
--- a/tests/caas/def-then-compile.txt
+++ b/tests/caas/def-then-compile.txt
@@ -1,7 +1,7 @@
 main.nim
-> idetools --track:main.nim,5,18 --def main.nim
+> idetools --track:main.nim,5,18 --def
 strutils.toUpper
-SuccessX
+! SuccessX
 > c
 SuccessX
 
diff --git a/tests/caas/idetools_api.nim b/tests/caas/idetools_api.nim
new file mode 100644
index 000000000..930d26429
--- /dev/null
+++ b/tests/caas/idetools_api.nim
@@ -0,0 +1,23 @@
+import unicode, sequtils
+
+proc test_enums() =
+  var o: Tfile
+  if o.open("files " & "test.txt", fmWrite):
+    o.write("test")
+    o.close()
+
+proc test_iterators(filename = "tests.nim") =
+  let
+    input = readFile(filename)
+    letters = toSeq(runes(string(input)))
+  for letter in letters: echo int(letter)
+
+const SOME_SEQUENCE = @[1, 2]
+type
+  bad_string = distinct string
+  TPerson = object of TObject
+    name*: bad_string
+    age: int
+
+proc adder(a, b: int): int =
+  result = a + b
diff --git a/tests/caas/idetools_api.txt b/tests/caas/idetools_api.txt
new file mode 100644
index 000000000..eaa91cd5f
--- /dev/null
+++ b/tests/caas/idetools_api.txt
@@ -0,0 +1,41 @@
+idetools_api.nim
+> c
+SuccessX
+> idetools --track:idetools_api.nim,4,11 --def
+def\tskType\tsystem.TFile\tTFile
+> idetools --track:idetools_api.nim,5,7 --def
+def\tskProc\tsystem.Open\tproc \(var TFile, string, TFileMode, int\): bool
+> idetools --track:idetools_api.nim,5,21 --def
+def\tskProc\tsystem.\&\tproc \(string, string\): string\{.noSideEffect.\}
+> idetools --track:idetools_api.nim,5,38 --def
+def\tskEnumField\tsystem.TFileMode.fmWrite\tTFileMode
+> idetools --track:idetools_api.nim,7,6 --def
+def\tskProc\tsystem.Close\tproc \(TFile\)
+> idetools --track:idetools_api.nim,12,23 --def
+def\tskIterator\tunicode.runes\titerator \(string\): TRune
+> idetools --track:idetools_api.nim,12,15 --def
+def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr
+> idetools --track:idetools_api.nim,15,7 --def
+
+# ProcRun mode will fail the next line, because the type is returned empty.
+def\tskConst\tidetools_api.SOME_SEQUENCE\tseq\[int\]\t
+> idetools --track:idetools_api.nim,15,23 --def
+def\tskProc\tsystem.@\tproc \(array\[IDX, T\]\): seq\[T\]\{.noSideEffect.\}
+> idetools --track:idetools_api.nim,17,3 --def
+
+# ProcRun mode will fail the next line, because the type is returned empty.
+def\tskType\tidetools_api.bad_string\tbad_string\t
+> idetools --track:idetools_api.nim,11,24 --def
+def\tskParam\tidetools_api.test_iterators.filename\tstring
+> idetools --track:idetools_api.nim,6,5 --def
+def\tskVar\tidetools_api.test_enums.o\tTFile
+> idetools --track:idetools_api.nim,12,34 --def
+def\tskLet\tidetools_api.test_iterators.input\tTaintedString
+> idetools --track:idetools_api.nim,13,35 --def
+def\tskForVar\tidetools_api.test_iterators.letter\tTRune
+> idetools --track:idetools_api.nim,23,3 --def
+def\tskResult\tidetools_api.adder.result\tint
+> idetools --track:idetools_api.nim,19,6 --def
+
+# ProcRun mode will fail the next line, because the type is returned empty.
+def\tskField\tidetools_api.TPerson.name\tbad_string\t
diff --git a/tests/caas/issue_416.nim b/tests/caas/issue_416.nim
new file mode 100644
index 000000000..d52f611d6
--- /dev/null
+++ b/tests/caas/issue_416.nim
@@ -0,0 +1,17 @@
+import unicode, sequtils
+
+proc test() =
+  let input = readFile("weird.nim")
+  for letter in runes(string(input)):
+    echo int(letter)
+
+when 1 > 0:
+  proc failtest() =
+    let
+      input = readFile("weird.nim")
+      letters = toSeq(runes(string(input)))
+    for letter in letters:
+      echo int(letter)
+
+when isMainModule:
+  test()
diff --git a/tests/caas/issue_416.txt b/tests/caas/issue_416.txt
new file mode 100644
index 000000000..7f81c2b2c
--- /dev/null
+++ b/tests/caas/issue_416.txt
@@ -0,0 +1,14 @@
+issue_416.nim
+> c
+SuccessX
+> idetools --track:issue_416.nim,12,28 --def
+def\tskType\tsystem.string\tstring
+> idetools --track:issue_416.nim,12,35 --def
+def\tskLet\tissue_416.failtest.input\tTaintedString
+
+# The following fail because they seem shifted one colum to the right.
+> idetools --track:issue_416.nim,12,16 --def
+def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr
+> idetools --track:issue_416.nim,12,22 --def
+def\tskIterator\tunicode.runes\titerator \(string\): TRune
+
diff --git a/tests/caas/issue_452.nim b/tests/caas/issue_452.nim
new file mode 100644
index 000000000..46cff6241
--- /dev/null
+++ b/tests/caas/issue_452.nim
@@ -0,0 +1,8 @@
+const
+  VERSION_STR1* = "0.5.0" ## Idetools shifts this one column.
+  VERSION_STR2 = "0.5.0" ## This one is ok.
+  VERSION_STR3* = "0.5.0" ## Bad.
+  VERSION_STR4 = "0.5.0" ## Ok.
+
+proc forward1*(): string = result = ""
+proc forward2(): string = result = ""
diff --git a/tests/caas/issue_452.txt b/tests/caas/issue_452.txt
new file mode 100644
index 000000000..5db60516c
--- /dev/null
+++ b/tests/caas/issue_452.txt
@@ -0,0 +1,11 @@
+issue_452.nim
+> c
+SuccessX
+> idetools --track:issue_452.nim,2,2 --def
+def\tskConst\tissue_452.VERSION_STR1\tstring
+> idetools --track:issue_452.nim,3,2 --def
+def\tskConst\tissue_452.VERSION_STR2\tstring
+> idetools --track:issue_452.nim,7,5 --def
+def\tskProc\tissue_452.forward1\tproc \(\): string\t
+> idetools --track:issue_452.nim,8,5 --def
+def\tskProc\tissue_452.forward2\tproc \(\): string\t
diff --git a/tests/caas/suggest-compile.txt b/tests/caas/suggest-compile.txt
index 49d0dc431..a74d4dc21 100644
--- a/tests/caas/suggest-compile.txt
+++ b/tests/caas/suggest-compile.txt
@@ -1,5 +1,6 @@
 main.nim
-> idetools --trackDirty:main_dirty.nim,main.nim,12,7 --suggest main.nim
+# Ugh, undocumented trackDirty, how is it supposed to work? Fails in proc mode.
+> idetools --trackDirty:main_dirty.nim,main.nim,12,7 --suggest
 skField\tx
 skField\ty
 > c
diff --git a/tests/caasdriver.nim b/tests/caasdriver.nim
index 3f3d3671e..87360ed34 100644
--- a/tests/caasdriver.nim
+++ b/tests/caasdriver.nim
@@ -1,26 +1,75 @@
 import osproc, streams, os, strutils, re
 
+## Compiler as a service tester.
+##
+## This test cases uses the txt files in the caas/ subdirectory.
+##
+## Each of the text files inside encodes a session with the compiler:
+##
+## The first line indicates the main project file.
+##
+## Lines starting with '>' indicate a command to be sent to the compiler and
+## the lines following a command include checks for expected or forbidden
+## output (! for forbidden).
+##
+## If a line starts with '#' it will be ignored completely, so you can use that
+## for comments.
+##
+## All the tests are run both in ProcRun (each command creates a separate
+## process) and CaasRun (first command starts up a server and it is reused for
+## the rest) modes. Since some cases are specific to either ProcRun or CaasRun
+## modes, you can prefix a line with the mode and the line will be processed
+## only in that mode.
+##
+## The rest of the line is treated as a regular expression, so be careful
+## escaping metacharacters like parenthesis.
+##
+## You can optionally pass parameters at the command line to modify the
+## behaviour of the test suite. By default only tests which fail will be echoed
+## to stdout. If you want to see all the output pass the word "verbose" as a
+## parameter.
+##
+## If you don't want to run all the test case files, you can pass any substring
+## as a parameter. Only files matching the passed substring will be run. The
+## filtering doesn't use any globbing metacharacters, it's a plain match.
+##
+## Example to run only "*-compile*.txt" tests in verbose mode:
+##
+##   ./caasdriver verbose -compile
+
+
 type
+  TRunMode = enum
+    ProcRun, CaasRun
+
   TNimrodSession* = object
-    nim: PProcess
+    nim: PProcess # Holds the open process for CaasRun sessions, nil otherwise.
+    mode: TRunMode # Stores the type of run mode the session was started with.
+    lastOutput: string # Preserves the last output, needed for ProcRun mode.
+    filename: string # Appended to each command starting with '>'.
 
-proc dirname(path: string): string = path.splitPath()[0]
+const modes = [CaasRun, ProcRun]
 
 var
   TesterDir = getAppDir()
   NimrodBin = TesterDir / "../bin/nimrod"
 
-proc startNimrodSession*(project: string): TNimrodSession =
-  result.nim = startProcess(NimrodBin,
-    workingDir = project.dirname,
-    args = ["serve", "--server.type:stdin", project])
+proc startNimrodSession(project: string, mode: TRunMode): TNimrodSession =
+  let (dir, name) = project.SplitPath
+  result.mode = mode
+  result.lastOutput = ""
+  result.filename = name
+  if mode == CaasRun:
+    result.nim = startProcess(NimrodBin, workingDir = dir,
+      args = ["serve", "--server.type:stdin", name])
 
-proc doCommand*(session: var TNimrodSession, command: string): string =
+proc doCaasCommand(session: var TNimrodSession, command: string): string =
+  assert session.mode == CaasRun
   session.nim.inputStream.write(command & "\n")
   session.nim.inputStream.flush
-  
+
   result = ""
-  
+
   while true:
     var line = TaintedString("")
     if session.nim.outputStream.readLine(line):
@@ -30,30 +79,66 @@ proc doCommand*(session: var TNimrodSession, command: string): string =
       result = "FAILED TO EXECUTE: " & command & "\n" & result
       break
 
+proc doProcCommand(session: var TNimrodSession, command: string): string =
+  assert session.mode == ProcRun
+  except: result = "FAILED TO EXECUTE: " & command & "\n" & result
+  var
+    process = startProcess(NimrodBin, args = command.split)
+    stream = outputStream(process)
+    line = TaintedString("")
+
+  result = ""
+  while stream.readLine(line):
+    if result.len > 0: result &= "\n"
+    result &= line.string
+
+  process.close()
+
+proc doCommand(session: var TNimrodSession, command: string) =
+  if session.mode == CaasRun:
+    session.lastOutput = doCaasCommand(session,
+                                       command & " " & session.filename)
+  else:
+    session.lastOutput = doProcCommand(session,
+                                       command & " " & session.filename)
+
 proc close(session: var TNimrodSession) {.destructor.} =
-  session.nim.close
+  if session.mode == CaasRun:
+    session.nim.close
 
-proc doScenario(script: string, output: PStream): bool =
+proc doScenario(script: string, output: PStream, mode: TRunMode): bool =
   result = true
 
   var f = open(script)
   var project = TaintedString("")
-  
+
   if f.readLine(project):
     var
-      s = startNimrodSession(script.dirname / project.string)
+      s = startNimrodSession(script.parentDir / project.string, mode)
       tline = TaintedString("")
-      lastOutput = ""
       ln = 1
 
     while f.readLine(tline):
       var line = tline.string
       inc ln
+
+      # Filter lines by run mode, removing the prefix if the mode is current.
+      for testMode in modes:
+        if line.startsWith($testMode):
+          if testMode != mode:
+            line = ""
+          else:
+            line = line[len($testMode)..len(line) - 1].strip
+          break
+
       if line.strip.len == 0: continue
 
-      if line.startsWith(">"):
-        lastOutput = s.doCommand(line.substr(1).strip)
-        output.writeln line, "\n", lastOutput
+      if line.startsWith("#"):
+        output.writeln line
+        continue
+      elif line.startsWith(">"):
+        s.doCommand(line.substr(1).strip)
+        output.writeln line, "\n", s.lastOutput
       else:
         var expectMatch = true
         var pattern = line
@@ -61,7 +146,8 @@ proc doScenario(script: string, output: PStream): bool =
           pattern = line.substr(1).strip
           expectMatch = false
 
-        var actualMatch = lastOutput.find(re(pattern)) != -1
+        let actualMatch =
+          s.lastOutput.find(re(pattern, flags = {reStudy})) != -1
 
         if expectMatch == actualMatch:
           output.writeln "SUCCESS ", line
@@ -70,17 +156,33 @@ proc doScenario(script: string, output: PStream): bool =
           result = false
 
 iterator caasTestsRunner*(filter = ""): tuple[test, output: string,
-                                              status: bool] =
+                                              status: bool, mode: TRunMode] =
   for scenario in os.walkFiles(TesterDir / "caas/*.txt"):
     if filter.len > 0 and find(scenario, filter) == -1: continue
-    var outStream = newStringStream()
-    let r = doScenario(scenario, outStream)
-    yield (scenario, outStream.data, r)
+    for mode in modes:
+      var outStream = newStringStream()
+      let r = doScenario(scenario, outStream, mode)
+      yield (scenario, outStream.data, r, mode)
 
 when isMainModule:
-  var filter = ""
-  if paramCount() > 0: filter = paramStr(1)
-  
-  for t, o, r in caasTestsRunner(filter):
-    echo t, "\n", o
-    
+  var
+    filter = ""
+    failures = 0
+    verbose = false
+
+  for i in 0..ParamCount() - 1:
+    let param = string(paramStr(i + 1))
+    case param
+    of "verbose": verbose = true
+    else: filter = param
+
+  if verbose and len(filter) > 0:
+    echo "Running only test cases matching filter '$1'" % [filter]
+
+  for test, output, result, mode in caasTestsRunner(filter):
+    if not result or verbose:
+      echo test, "\n", output, "-> ", $mode, ":", $result, "\n-----"
+    if not result:
+      failures += 1
+
+  quit(failures)
diff --git a/tests/tester.nim b/tests/tester.nim
index 8c8e31fe8..e10b89761 100644
--- a/tests/tester.nim
+++ b/tests/tester.nim
@@ -365,8 +365,9 @@ proc outputJSON(reject, compile, run: TResults) =
   writeFile(jsonFile, s)
 
 proc runCaasTests(r: var TResults) =
-  for test, output, status in caasTestsRunner():
-    r.addResult(test, "", output, if status: reSuccess else: reOutputsDiffer)
+  for test, output, status, mode in caasTestsRunner():
+    r.addResult(test, "", output & "-> " & $mode,
+                if status: reSuccess else: reOutputsDiffer)
 
 proc main() =
   os.putenv "NIMTEST_NO_COLOR", "1"