summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semmagic.nim3
-rw-r--r--lib/pure/streams.nim6
-rw-r--r--lib/system.nim7
-rw-r--r--tests/caas/basic-recompile.txt7
-rw-r--r--tests/caas/imported.nim3
-rw-r--r--tests/caas/main.nim7
-rw-r--r--tests/caasdriver.nim83
-rw-r--r--tests/tester.nim8
-rw-r--r--web/news.txt2
9 files changed, 122 insertions, 4 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 31eb7a9d5..058964fc8 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -23,9 +23,10 @@ proc expectIntLit(c: PContext, n: PNode): int =
 proc semInstantiationInfo(c: PContext, n: PNode): PNode =
   result = newNodeIT(nkPar, n.info, n.typ)
   let idx = expectIntLit(c, n.sons[1])
+  let useFullPaths = expectIntLit(c, n.sons[2])
   let info = getInfoContext(idx)
   var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString))
-  filename.strVal = ToFilename(info)
+  filename.strVal = if useFullPaths != 0: info.toFullPath else: info.ToFilename
   var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
   line.intVal = ToLinenumber(info)
   result.add(filename)
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index 4a196127c..764471b78 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -106,6 +106,12 @@ proc write*(s: PStream, x: string) =
   ## terminating zero is written.
   writeData(s, cstring(x), x.len)
 
+proc writeln*(s: PStream, args: varargs[string, `$`]) =
+  ## writes one or more strings to the the stream `s` followed
+  ## by a new line. No length field or terminating zero is written.
+  for str in args: write(s, str)
+  write(s, "\n")
+
 proc read[T](s: PStream, result: var T) = 
   ## generic read procedure. Reads `result` from the stream `s`.
   if readData(s, addr(result), sizeof(T)) != sizeof(T):
diff --git a/lib/system.nim b/lib/system.nim
index 80e38ad7b..5dafd6e13 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2407,8 +2407,8 @@ proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.}
   ## converts the AST of `x` into a string representation. This is very useful
   ## for debugging.
   
-proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {.
-  magic: "InstantiationInfo", noSideEffect.}
+proc InstantiationInfo*(index = -1, fullPaths = false): tuple[
+  filename: string, line: int] {. magic: "InstantiationInfo", noSideEffect.}
   ## provides access to the compiler's instantiation stack line information.
   ##
   ## This proc is mostly useful for meta programming (eg. ``assert`` template)
@@ -2438,6 +2438,9 @@ proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {.
   ##     testException(EInvalidIndex, tester(1))
   ##     # --> Test failure at example.nim:20 with 'tester(1)'
 
+template CurrentSourcePath*: string = InstantiationInfo(-1, true).filename
+  ## returns the full file-system path of the current source
+
 proc raiseAssert*(msg: string) {.noinline.} =
   raise newException(EAssertionFailed, msg)
 
diff --git a/tests/caas/basic-recompile.txt b/tests/caas/basic-recompile.txt
new file mode 100644
index 000000000..9c943fe88
--- /dev/null
+++ b/tests/caas/basic-recompile.txt
@@ -0,0 +1,7 @@
+main.nim
+> c
+SuccessX
+> c
+! Processing
+SuccessX
+
diff --git a/tests/caas/imported.nim b/tests/caas/imported.nim
new file mode 100644
index 000000000..a4bc5c0e6
--- /dev/null
+++ b/tests/caas/imported.nim
@@ -0,0 +1,3 @@
+proc `+++`*(a,b: string): string =
+  return a & "  " & b
+
diff --git a/tests/caas/main.nim b/tests/caas/main.nim
new file mode 100644
index 000000000..fafeff93b
--- /dev/null
+++ b/tests/caas/main.nim
@@ -0,0 +1,7 @@
+import imported, strutils
+
+proc main =
+  var t1 = "text"
+  var t2 = t1.toUpper
+  echo(t1 +++ t2)
+
diff --git a/tests/caasdriver.nim b/tests/caasdriver.nim
new file mode 100644
index 000000000..ee2e5b571
--- /dev/null
+++ b/tests/caasdriver.nim
@@ -0,0 +1,83 @@
+import osproc, streams, os, strutils, re
+
+type
+  TNimrodSession* = object
+    nim: PProcess
+
+proc dirname(path: string): string = path.splitPath()[0]
+
+const
+  TesterDir = CurrentSourcePath.dirname
+  NimrodBin = TesterDir / "../bin/nimrod"
+
+proc startNimrodSession*(project: string): TNimrodSession =
+  result.nim = startProcess(NimrodBin,
+    workingDir = project.dirname,
+    args = ["serve", "--server.type:stdin", project])
+
+proc doCommand*(session: var TNimrodSession, command: string): string =
+  session.nim.inputStream.write(command & "\n")
+  session.nim.inputStream.flush
+  
+  result = ""
+  
+  while true:
+    var line = TaintedString("")
+    if session.nim.outputStream.readLine(line):
+      if line.string == "": break
+      result.add(line.string & "\n")
+
+proc close(session: var TNimrodSession) {.destructor.} =
+  session.nim.close
+
+proc doScenario(script: string, output: PStream): bool =
+  result = true
+
+  var f = open(script)
+  var project = TaintedString("")
+  
+  if f.readLine(project):
+    var
+      s = startNimrodSession(script.dirname / project.string)
+      tline = TaintedString("")
+      lastOutput = ""
+      ln = 1
+
+    while f.readLine(tline):
+      var line = tline.string
+      inc ln
+      if line.strip.len == 0: continue
+
+      if line.startsWith(">"):
+        lastOutput = s.doCommand(line.substr(1).strip)
+        output.writeln line, "\n", lastOutput
+      else:
+        var expectMatch = true
+        var pattern = line
+        if line.startsWith("!"):
+          pattern = line.substr(1).strip
+          expectMatch = false
+
+        var actualMatch = lastOutput.find(re(pattern)) != -1
+
+        if expectMatch == actualMatch:
+          output.writeln "SUCCESS ", line
+        else:
+          output.writeln "FAILURE ", line
+          result = false
+
+iterator caasTestsRunner*(filter = ""): tuple[test, output: string,
+                                              status: bool] =
+  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)
+
+when isMainModule:
+  var filter = ""
+  if paramCount() > 0: filter = paramStr(1)
+  
+  for t, o, r in caasTestsRunner(filter):
+    echo t, "\n", o
+    
diff --git a/tests/tester.nim b/tests/tester.nim
index 2b60151a8..8c8e31fe8 100644
--- a/tests/tester.nim
+++ b/tests/tester.nim
@@ -11,7 +11,7 @@
 
 import
   parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
-  marshal, cgi, parseopt
+  marshal, cgi, parseopt, caasdriver
 
 const
   cmdTemplate = r"nimrod cc --hints:on $# $#"
@@ -38,6 +38,7 @@ type
     reExeNotFound,
     reIgnored,          # test is ignored
     reSuccess           # test was successful
+
   TTarget = enum
     targetC, targetCpp, targetObjC, targetJS
 
@@ -363,6 +364,10 @@ proc outputJSON(reject, compile, run: TResults) =
   var s = pretty(doc)
   writeFile(jsonFile, s)
 
+proc runCaasTests(r: var TResults) =
+  for test, output, status in caasTestsRunner():
+    r.addResult(test, "", output, if status: reSuccess else: reOutputsDiffer)
+
 proc main() =
   os.putenv "NIMTEST_NO_COLOR", "1"
   os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES"
@@ -404,6 +409,7 @@ proc main() =
     writeResults(runJson, r)
   of "special":
     runSpecialTests(r, p.cmdLineRest.string)
+    runCaasTests(r)
     writeResults(runJson, r)
   of "rodfiles":
     runRodFiles(r, p.cmdLineRest.string)
diff --git a/web/news.txt b/web/news.txt
index 667b8a210..26c681d95 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -29,6 +29,8 @@ Library Additions
 - Added ``system.unsafeNew`` to support hacky variable length objects.
 - ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they
   used to only support tuples.
+- Added ``system.CurrentSourcePath`` returning the full file-system path of
+  the current source file
 
 
 Changes affecting backwards compatibility