1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-05 00:06:16 +00:00
janet/test/suite0.dst
2018-03-11 16:30:38 -04:00

301 lines
9.1 KiB
Plaintext

# Copyright (c) 2017 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
(print "\nRunning Suite 0 tests...\n")
(var num-tests-passed 0)
(var num-tests-run 0)
(def assert (fn [x e]
(varset! num-tests-run (+ 1 num-tests-run))
(if x
(do
(print " \e[32m✔\e[0m " e)
(varset! num-tests-passed (+ 1 num-tests-passed))
x)
(do
(print " \e[31m✘\e[0m " e)
x))))
(assert (= 10 (+ 1 2 3 4)) "addition")
(assert (= -8 (- 1 2 3 4)) "subtraction")
(assert (= 24 (* 1 2 3 4)) "multiplication")
(assert (= 4 (<< 1 2)) "left shift")
(assert (= 1 (>> 4 2)) "right shift")
(assert (< 1 2 3 4 5 6) "less than integers")
(assert (< 1.0 2.0 3.0 4.0 5.0 6.0) "less than reals")
(assert (> 6 5 4 3 2 1) "greater than integers")
(assert (> 6.0 5.0 4.0 3.0 2.0 1.0) "greater than reals")
(assert (<= 1 2 3 3 4 5 6) "less than or equal to integers")
(assert (<= 1.0 2.0 3.0 3.0 4.0 5.0 6.0) "less than or equal to reals")
(assert (>= 6 5 4 4 3 2 1) "greater than or equal to integers")
(assert (>= 6.0 5.0 4.0 4.0 3.0 2.0 1.0) "greater than or equal to reals")
(assert (order< nil false true
(fiber (fn [x] x))
1 1.0 "hi"
(quote hello)
(array 1 2 3)
(tuple 1 2 3)
(table "a" "b" "c" "d")
(struct 1 2 3 4)
(buffer "hi")
(fn [x] (+ x x))
+) "type ordering")
(assert (= (string (buffer "123" "456")) (string @"123456")) "buffer literal")
(assert (= (get {} 1) nil) "get nil from empty struct")
(assert (= (get @{} 1) nil) "get nil from empty table")
(assert (= (get {:boop :bap} :boop) :bap) "get non nil from struct")
(assert (= (get @{:boop :bap} :boop) :bap) "get non nil from table")
(assert (put @{} :boop :bap) "can add to empty table")
(assert (put @{1 3} :boop :bap) "can add to non-empty table")
(assert (not false) "false literal")
(assert true "true literal")
(assert (not nil) "nil literal")
(assert (= 7 (| 3 4)) "bit or")
(assert (= 0 (& 3 4)) "bit and")
# Set global variables to prevent some possible compiler optimizations that defeat point of the test
(var zero 0)
(var one 1)
(var two 2)
(var three 3)
(var plus +)
(assert (= 22 (plus one (plus 1 2 two) (plus 8 (plus zero 1) 4 three))) "nested function calls")
# Mcarthy's 91 function
(var f91 nil)
(varset! f91 (fn [n] (if (> n 100) (- n 10) (f91 (f91 (+ n 11))))))
(assert (= 91 (f91 10)), "f91(10) = 91")
(assert (= 91 (f91 11)), "f91(11) = 91")
(assert (= 91 (f91 20)), "f91(20) = 91")
(assert (= 91 (f91 31)), "f91(31) = 91")
(assert (= 91 (f91 100)), "f91(100) = 91")
(assert (= 91 (f91 101)), "f91(101) = 91")
(assert (= 92 (f91 102)), "f91(102) = 92")
(assert (= 93 (f91 103)), "f91(103) = 93")
(assert (= 94 (f91 104)), "f91(104) = 94")
# Fibonacci
(def fib (do (var fib nil) (varset! fib (fn [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))))))
(def fib2 (fn fib2 [n] (if (< n 2) n (+ (fib2 (- n 1)) (fib2 (- n 2))))))
(assert (= (fib 0) (fib2 0) 0) "fib(0)")
(assert (= (fib 1) (fib2 1) 1) "fib(1)")
(assert (= (fib 2) (fib2 2) 1) "fib(2)")
(assert (= (fib 3) (fib2 3) 2) "fib(3)")
(assert (= (fib 4) (fib2 4) 3) "fib(4)")
(assert (= (fib 5) (fib2 5) 5) "fib(5)")
(assert (= (fib 6) (fib2 6) 8) "fib(6)")
(assert (= (fib 7) (fib2 7) 13) "fib(7)")
(assert (= (fib 8) (fib2 8) 21) "fib(8)")
(assert (= (fib 9) (fib2 9) 34) "fib(9)")
(assert (= (fib 10) (fib2 10) 55) "fib(10)")
# Closure in non function scope
(def outerfun (fn [x y]
(def c (do
(def someval (+ 10 y))
(def ctemp (if x (fn [] someval) (fn [] y)))
ctemp
))
(+ 1 2 3 4 5 6 7)
c))
(assert (= ((outerfun 1 2)) 12) "inner closure 1")
(assert (= ((outerfun nil 2)) 2) "inner closure 2")
(assert (= ((outerfun false 3)) 3) "inner closure 3")
(assert (= '(1 2 3) (quote (1 2 3)) (tuple 1 2 3)) "quote shorthand")
((fn []
(var accum 1)
(var count 0)
(while (< count 16)
(varset! accum (<< accum 1))
(varset! count (+ 1 count)))
(assert (= accum 65536) "loop in closure")))
(var accum 1)
(var count 0)
(while (< count 16)
(varset! accum (<< accum 1))
(varset! count (+ 1 count)))
(assert (= accum 65536) "loop globally")
(assert (= (struct 1 2 3 4 5 6 7 8) (struct 7 8 5 6 3 4 1 2)) "struct order does not matter 1")
(assert (= (struct
:apple 1
6 :bork
'(1 2 3) 5)
(struct
6 :bork
'(1 2 3) 5
:apple 1)) "struct order does not matter 2")
# Symbol function
(assert (= (symbol "abc" 1 2 3) 'abc123) "symbol function")
# Fiber tests
(def afiber (fiber (fn [x]
(error (string "hello, " x)))))
(def afiber-result (resume afiber "world!"))
(assert (= afiber-result "hello, world!") "fiber error result")
(assert (= (fiber-status afiber) :error) "fiber error status")
# yield tests
(def t (fiber (fn [] (yield 1) (yield 2) 3)))
(assert (= 1 (resume t)) "initial transfer to new fiber")
(assert (= 2 (resume t)) "second transfer to fiber")
(assert (= 3 (resume t)) "return from fiber")
(assert (= (fiber-status t) :dead) "finished fiber is dead")
# Var arg tests
(def vargf (fn [more] (apply + more)))
(assert (= 0 (vargf [])) "var arg no arguments")
(assert (= 1 (vargf [1])) "var arg no packed arguments")
(assert (= 3 (vargf [1 2])) "var arg tuple size 1")
(assert (= 10 (vargf [1 2 3 4])) "var arg tuple size 3")
(assert (= 110 (vargf [1 2 3 4 10 10 10 10 10 10 10 10 10 10])) "var arg large tuple")
# Higher order functions
(def compose (fn [f g] (fn [& xs] (f (apply g xs)))))
(def -+ (compose - +))
(def +- (compose + -))
(assert (= (-+ 1 2 3 4) -10) "compose - +")
(assert (= (+- 1 2 3 4) -8) "compose + -")
(assert (= ((compose -+ +-) 1 2 3 4) 8) "compose -+ +-")
(assert (= ((compose +- -+) 1 2 3 4) 10) "compose +- -+")
# UTF-8
#🐙🐙🐙🐙
(def 🦊 :fox)
(def 🐮 :cow)
(assert (= (string "🐼" 🦊 🐮) "🐼:fox:cow") "emojis 🙉 :)")
(assert (not= 🦊 :🦊) "utf8 strings are not symbols and vice versa")
# Symbols with @ symbol
(def @ 1)
(assert (= @ 1) "@ symbol")
(def @@ 2)
(assert (= @@ 2) "@@ symbol")
(def @hey 3)
(assert (= @hey 3) "@hey symbol")
# Merge sort
# Imperative merge sort merge
(def merge (fn [xs ys]
(def ret [])
(def xlen (length xs))
(def ylen (length ys))
(var i 0)
(var j 0)
# Main merge
(while (if (< i xlen) (< j ylen))
(def xi (get xs i))
(def yj (get ys j))
(if (< xi yj)
(do (array-push ret xi) (varset! i (+ i 1)))
(do (array-push ret yj) (varset! j (+ j 1)))))
# Push rest of xs
(while (< i xlen)
(def xi (get xs i))
(array-push ret xi)
(varset! i (+ i 1)))
# Push rest of ys
(while (< j ylen)
(def yj (get ys j))
(array-push ret yj)
(varset! j (+ j 1)))
ret))
(assert (apply <= (merge [1 3 5] [2 4 6])) "merge sort merge 1")
(assert (apply <= (merge [1 2 3] [4 5 6])) "merge sort merge 2")
(assert (apply <= (merge [1 3 5] [2 4 6 6 6 9])) "merge sort merge 3")
(assert (apply <= (merge '(1 3 5) [2 4 6 6 6 9])) "merge sort merge 4")
# Gensym tests
(assert (not= (gensym) (gensym)) "two gensyms not equal")
(assert (not= (gensym 'abc) (gensym 'abc)) "two gensyms with arg not equal")
((fn []
(def syms (table))
(var count 0)
(while (< count 128)
(put syms (gensym 'beep) true)
(varset! count (+ 1 count)))
(assert (= (length syms) 128) "many symbols")))
# Let
(assert (= (let [a 1 b 2] (+ a b)) 3), "simple let")
(assert (= (let [[a b] [1 2]] (+ a b)) 3), "destructured let")
(assert (= (let [[a [c d] b] [1 (tuple 4 3) 2]] (+ a b c d)) 10), "double destructured let")
# Macros
(def defmacro macro (fn [name & more]
(tuple 'def name 'macro (tuple-prepend (tuple-prepend more name) 'fn))))
(defmacro defn
[name & more]
(tuple
'def
name
(tuple-prepend (tuple-prepend more name) 'fn)))
(defmacro when [cond & body] (tuple 'if cond (tuple-prepend body 'do)))
(defn dub [x] (+ x x))
(assert (= 2 (dub 1)) "defn macro")
(do
(defn trip [x] (+ x x x))
(assert (= 3 (trip 1)) "defn macro triple"))
(do
(var i 0)
(when true
(varset! i (+ i 1))
(varset! i (+ i 1))
(varset! i (+ i 1))
(varset! i (+ i 1))
(varset! i (+ i 1))
(varset! i (+ i 1)))
(assert (= i 6) "when macro"))
# report
(print "\n" num-tests-passed " of " num-tests-run " tests passed\n")
(if (not= num-tests-passed num-tests-run) (exit 1))