summary refs log tree commit diff stats
path: root/tests/js/tclosures.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/js/tclosures.nim')
-rw-r--r--tests/js/tclosures.nim95
1 files changed, 95 insertions, 0 deletions
diff --git a/tests/js/tclosures.nim b/tests/js/tclosures.nim
new file mode 100644
index 000000000..4f1c28de3
--- /dev/null
+++ b/tests/js/tclosures.nim
@@ -0,0 +1,95 @@
+discard """
+  action: run
+"""
+
+import random, strutils
+const consolePrefix = "jsCallbacks"
+
+asm """
+    var callback = []
+    function regCallback (fn) { callback.push (fn); }
+    function runCallbacks () {
+        var result = "\n"
+        var n = 0
+        for (var fn in callback) {
+            n += 1
+            result += "("+String (n)+")"
+            result += callback [fn] ()
+            result += "\n"
+        }
+        return result
+    }
+    function print (text) { console.log (text); }
+"""
+
+proc consoleprint (str:cstring): void {.importc: "print", nodecl.}
+proc print* (a: varargs[string, `$`]) = consoleprint "$1: $2" % [consolePrefix, join(a, " ")]
+
+type CallbackProc {.importc.} = proc () : cstring
+
+proc regCallback (fn:CallbackProc) {.importc.}
+proc runCallbacks ():cstring {.importc.}
+
+proc `*` (s:string, n:Natural) : string = s.repeat(n)
+
+proc outer (i:Natural) : (string, int) =
+    let c = $char(rand(93) + 33)
+    let n = rand(40)
+    let s = c * n
+    proc inner(): cstring = ("[$1]" % $n) & s & " <--"
+    regCallback(inner)
+    return (s, n)
+
+var expected = "\n"
+for i in 1 .. 10:
+    let (s, n) = outer(i)
+    expected &= ("($1)[$2]" % [$i, $n]) & s & " <--"
+    expected &= "\n"
+
+let results = runCallbacks()
+
+doAssert(expected == $results)
+
+block issue7048:
+  block:
+    proc foo(x: seq[int]): auto =
+      proc bar: int = x[1]
+      bar
+
+    var stuff = @[1, 2]
+    let f = foo(stuff)
+    stuff[1] = 321
+    doAssert f() == 2
+
+  block:
+    proc foo(x: tuple[things: string]; y: array[3, int]): auto =
+      proc very: auto = 
+        proc deeply: auto =
+          proc nested: (char, int) = (x.things[0], y[1])
+          nested
+        deeply
+      very()
+
+    var
+      stuff = (things: "NIM")
+      stuff2 = [32, 64, 96]
+    let f = foo(stuff, stuff2)
+    stuff.things = "VIM"
+    stuff2[1] *= 10
+    doAssert f()() == ('N', 64)
+    doAssert (stuff.things[0], stuff2[1]) == ('V', 640)
+
+  block:
+    proc foo(x: ptr string): auto =
+      proc bar(): int = len(x[])
+      bar
+    
+    var 
+      s1 = "xyz"
+      s2 = "stuff"
+      p = addr s1
+    
+    let f = foo(p)
+    p = addr s2
+    doAssert len(p[]) == 5
+    doAssert f() == 3