Bläddra i källkod

import mal's tests from mal repository

master
rhysd 9 år sedan
förälder
incheckning
0f0c8ea728
19 ändrade filer med 1582 tillägg och 0 borttagningar
  1. +4
    -0
      spec/crisp/mal_specs/tests/inc.mal
  2. +3
    -0
      spec/crisp/mal_specs/tests/incA.mal
  3. +10
    -0
      spec/crisp/mal_specs/tests/incB.mal
  4. +6
    -0
      spec/crisp/mal_specs/tests/incC.mal
  5. +11
    -0
      spec/crisp/mal_specs/tests/perf1.mal
  6. +13
    -0
      spec/crisp/mal_specs/tests/perf2.mal
  7. +28
    -0
      spec/crisp/mal_specs/tests/perf3.mal
  8. +14
    -0
      spec/crisp/mal_specs/tests/step0_repl.mal
  9. +136
    -0
      spec/crisp/mal_specs/tests/step1_read_print.mal
  10. +31
    -0
      spec/crisp/mal_specs/tests/step2_eval.mal
  11. +56
    -0
      spec/crisp/mal_specs/tests/step3_env.mal
  12. +388
    -0
      spec/crisp/mal_specs/tests/step4_if_fn_do.mal
  13. +30
    -0
      spec/crisp/mal_specs/tests/step5_tco.mal
  14. +72
    -0
      spec/crisp/mal_specs/tests/step6_file.mal
  15. +126
    -0
      spec/crisp/mal_specs/tests/step7_quote.mal
  16. +164
    -0
      spec/crisp/mal_specs/tests/step8_macros.mal
  17. +264
    -0
      spec/crisp/mal_specs/tests/step9_try.mal
  18. +225
    -0
      spec/crisp/mal_specs/tests/stepA_mal.mal
  19. +1
    -0
      spec/crisp/mal_specs/tests/test.txt

+ 4
- 0
spec/crisp/mal_specs/tests/inc.mal Visa fil

@ -0,0 +1,4 @@
(def! inc1 (fn* (a) (+ 1 a)))
(def! inc2 (fn* (a) (+ 2 a)))
(def! inc3 (fn* (a)
(+ 3 a)))

+ 3
- 0
spec/crisp/mal_specs/tests/incA.mal Visa fil

@ -0,0 +1,3 @@
(def! inc4 (fn* (a) (+ 4 a)))
(prn (inc4 5))

+ 10
- 0
spec/crisp/mal_specs/tests/incB.mal Visa fil

@ -0,0 +1,10 @@
;; A comment in a file
(def! inc4 (fn* (a) (+ 4 a)))
(def! inc5 (fn* (a) ;; a comment after code
(+ 5 a)))
(prn "incB.mal finished")
"incB.mal return string"
;; ending comment

+ 6
- 0
spec/crisp/mal_specs/tests/incC.mal Visa fil

@ -0,0 +1,6 @@
(def! mymap {"a"
1})
(prn "incC.mal finished")
"incC.mal return string"

+ 11
- 0
spec/crisp/mal_specs/tests/perf1.mal Visa fil

@ -0,0 +1,11 @@
(load-file "../core.mal")
(load-file "../perf.mal")
;;(prn "Start: basic macros performance test")
(time (do
(or false nil false nil false nil false nil false nil 4)
(cond false 1 nil 2 false 3 nil 4 false 5 nil 6 "else" 7)
(-> (list 1 2 3 4 5 6 7 8 9) rest rest rest rest rest rest first)))
;;(prn "Done: basic macros performance test")

+ 13
- 0
spec/crisp/mal_specs/tests/perf2.mal Visa fil

@ -0,0 +1,13 @@
(load-file "../core.mal")
(load-file "../perf.mal")
;;(prn "Start: basic math/recursion test")
(def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0)))
(def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2)))))))
(time (do
(sumdown 10)
(fib 12)))
;;(prn "Done: basic math/recursion test")

+ 28
- 0
spec/crisp/mal_specs/tests/perf3.mal Visa fil

@ -0,0 +1,28 @@
(load-file "../core.mal")
(load-file "../perf.mal")
;;(prn "Start: basic macros/atom test")
(def! atm (atom (list 0 1 2 3 4 5 6 7 8 9)))
(println "iters/s:"
(run-fn-for
(fn* []
(do
(or false nil false nil false nil false nil false nil (first @atm))
(cond false 1 nil 2 false 3 nil 4 false 5 nil 6 "else" (first @atm))
(-> (deref atm) rest rest rest rest rest rest first)
(swap! atm (fn* [a] (concat (rest a) (list (first a)))))))
10))
;;(def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0)))
;;(def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2)))))))
;;
;;(println "iters/s:"
;; (run-fn-for
;; (fn* []
;; (do
;; (sumdown 10)
;; (fib 12)))
;; 3))
;;(prn "Done: basic macros/atom test")

+ 14
- 0
spec/crisp/mal_specs/tests/step0_repl.mal Visa fil

@ -0,0 +1,14 @@
hello world
;=>hello world
abcABC123
;=>abcABC123
;:() []{}"'*
;=>;:() []{}"'*
;;; Test long line
hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)
;=>hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)

+ 136
- 0
spec/crisp/mal_specs/tests/step1_read_print.mal Visa fil

@ -0,0 +1,136 @@
;; Testing read of nil/true/false
nil
;=>nil
true
;=>true
false
;=>false
;; Testing read of numbers
1
;=>1
7
;=>7
7
;=>7
;; Testing read of symbols
+
;=>+
abc
;=>abc
abc
;=>abc
abc5
;=>abc5
abc-def
;=>abc-def
;; Testing read of strings
"abc"
;=>"abc"
"abc"
;=>"abc"
"abc (with parens)"
;=>"abc (with parens)"
"abc\"def"
;=>"abc\"def"
;;;"abc\ndef"
;;;;=>"abc\ndef"
""
;=>""
;; Testing read of lists
(+ 1 2)
;=>(+ 1 2)
((3 4))
;=>((3 4))
(+ 1 (+ 2 3))
;=>(+ 1 (+ 2 3))
( + 1 (+ 2 3 ) )
;=>(+ 1 (+ 2 3))
(* 1 2)
;=>(* 1 2)
(** 1 2)
;=>(** 1 2)
;; Test commas as whitespace
(1 2, 3,,,,),,
;=>(1 2 3)
;; Testing read of quoting
'1
;=>(quote 1)
'(1 2 3)
;=>(quote (1 2 3))
`1
;=>(quasiquote 1)
`(1 2 3)
;=>(quasiquote (1 2 3))
~1
;=>(unquote 1)
~(1 2 3)
;=>(unquote (1 2 3))
~@(1 2 3)
;=>(splice-unquote (1 2 3))
;;
;; Testing reader errors
;;; TODO: fix these so they fail correctly
(1 2
; expected ')', got EOF
[1 2
; expected ']', got EOF
"abc
; expected '"', got EOF
;;
;; -------- Optional Functionality --------
;; Testing keywords
:kw
;=>:kw
(:kw1 :kw2 :kw3)
;=>(:kw1 :kw2 :kw3)
;; Testing read of vectors
[+ 1 2]
;=>[+ 1 2]
[[3 4]]
;=>[[3 4]]
[+ 1 [+ 2 3]]
;=>[+ 1 [+ 2 3]]
[ + 1 [+ 2 3 ] ]
;=>[+ 1 [+ 2 3]]
;; Testing read of hash maps
{"abc" 1}
;=>{"abc" 1}
{"a" {"b" 2}}
;=>{"a" {"b" 2}}
{"a" {"b" {"c" 3}}}
;=>{"a" {"b" {"c" 3}}}
{ "a" {"b" { "cde" 3 } }}
;=>{"a" {"b" {"cde" 3}}}
{ :a {:b { :cde 3 } }}
;=>{:a {:b {:cde 3}}}
;; Testing read of comments
;; whole line comment (not an exception)
1 ; comment after expression
;=>1
1; comment after expression
;=>1
;; Testing read of ^/metadata
^{"a" 1} [1 2 3]
;=>(with-meta [1 2 3] {"a" 1})
;; Testing read of @/deref
@a
;=>(deref a)

+ 31
- 0
spec/crisp/mal_specs/tests/step2_eval.mal Visa fil

@ -0,0 +1,31 @@
;; Testing evaluation of arithmetic operations
(+ 1 2)
;=>3
(+ 5 (* 2 3))
;=>11
(- (+ 5 (* 2 3)) 3)
;=>8
(/ (- (+ 5 (* 2 3)) 3) 4)
;=>2
(/ (- (+ 515 (* 222 311)) 302) 27)
;=>2565
(abc 1 2 3)
; .*\'abc\' not found.*
;;
;; -------- Optional Functionality --------
;; Testing evaluation within collection literals
[1 2 (+ 1 2)]
;=>[1 2 3]
{"a" (+ 7 8)}
;=>{"a" 15}
{:a (+ 7 8)}
;=>{:a 15}

+ 56
- 0
spec/crisp/mal_specs/tests/step3_env.mal Visa fil

@ -0,0 +1,56 @@
;; Testing REPL_ENV
(+ 1 2)
;=>3
(/ (- (+ 5 (* 2 3)) 3) 4)
;=>2
;; Testing def!
(def! x 3)
;=>3
x
;=>3
(def! x 4)
;=>4
x
;=>4
(def! y (+ 1 7))
;=>8
y
;=>8
;; Testing let*
(let* (z 9) z)
;=>9
(let* (x 9) x)
;=>9
x
;=>4
(let* (z (+ 2 3)) (+ 1 z))
;=>6
(let* (p (+ 2 3) q (+ 2 p)) (+ p q))
;=>12
;; Testing outer environment
(def! a 4)
;=>4
(let* (q 9) q)
;=>9
(let* (q 9) a)
;=>4
(let* (z 2) (let* (q 9) a))
;=>4
;;
;; -------- Optional Functionality --------
;; Testing let* with vector bindings
(let* [z 9] z)
;=>9
(let* [p (+ 2 3) q (+ 2 p)] (+ p q))
;=>12
;; Testing vector evaluation
(let* (a 5 b 6) [3 4 a [b 7] 8])
;=>[3 4 5 [6 7] 8]

+ 388
- 0
spec/crisp/mal_specs/tests/step4_if_fn_do.mal Visa fil

@ -0,0 +1,388 @@
;; -----------------------------------------------------
;; Testing list functions
(list)
;=>()
(list? (list))
;=>true
(empty? (list))
;=>true
(empty? (list 1))
;=>false
(list 1 2 3)
;=>(1 2 3)
(count (list 1 2 3))
;=>3
(count (list))
;=>0
(count nil)
;=>0
(if (> (count (list 1 2 3)) 3) "yes" "no")
;=>"no"
(if (>= (count (list 1 2 3)) 3) "yes" "no")
;=>"yes"
;; Testing if form
(if true 7 8)
;=>7
(if false 7 8)
;=>8
(if true (+ 1 7) (+ 1 8))
;=>8
(if false (+ 1 7) (+ 1 8))
;=>9
(if nil 7 8)
;=>8
(if 0 7 8)
;=>7
(if "" 7 8)
;=>7
(if (list) 7 8)
;=>7
(if (list 1 2 3) 7 8)
;=>7
(= (list) nil)
;=>false
;; Testing 1-way if form
(if false (+ 1 7))
;=>nil
(if nil 8 7)
;=>7
(if true (+ 1 7))
;=>8
;; Testing basic conditionals
(= 2 1)
;=>false
(= 1 1)
;=>true
(= 1 2)
;=>false
(= 1 (+ 1 1))
;=>false
(= 2 (+ 1 1))
;=>true
(= nil 1)
;=>false
(= nil nil)
;=>true
(> 2 1)
;=>true
(> 1 1)
;=>false
(> 1 2)
;=>false
(>= 2 1)
;=>true
(>= 1 1)
;=>true
(>= 1 2)
;=>false
(< 2 1)
;=>false
(< 1 1)
;=>false
(< 1 2)
;=>true
(<= 2 1)
;=>false
(<= 1 1)
;=>true
(<= 1 2)
;=>true
;; Testing equality
(= 1 1)
;=>true
(= 0 0)
;=>true
(= 1 0)
;=>false
(= "" "")
;=>true
(= "abc" "")
;=>false
(= "" "abc")
;=>false
(= "abc" "def")
;=>false
(= (list) (list))
;=>true
(= (list 1 2) (list 1 2))
;=>true
(= (list 1) (list))
;=>false
(= (list) (list 1))
;=>false
(= 0 (list))
;=>false
(= (list) 0)
;=>false
(= (list) "")
;=>false
(= "" (list))
;=>false
;; Testing builtin and user defined functions
(+ 1 2)
;=>3
( (fn* (a b) (+ b a)) 3 4)
;=>7
( (fn* () 4) )
;=>4
( (fn* (f x) (f x)) (fn* (a) (+ 1 a)) 7)
;=>8
;; Testing closures
( ( (fn* (a) (fn* (b) (+ a b))) 5) 7)
;=>12
(def! gen-plus5 (fn* () (fn* (b) (+ 5 b))))
(def! plus5 (gen-plus5))
(plus5 7)
;=>12
(def! gen-plusX (fn* (x) (fn* (b) (+ x b))))
(def! plus7 (gen-plusX 7))
(plus7 8)
;=>15
;; Testing variable length arguments
( (fn* (& more) (count more)) 1 2 3)
;=>3
( (fn* (& more) (count more)) 1)
;=>1
( (fn* (& more) (count more)) )
;=>0
( (fn* (a & more) (count more)) 1 2 3)
;=>2
( (fn* (a & more) (count more)) 1)
;=>0
;; Testing language defined not function
(not false)
;=>true
(not true)
;=>false
(not "a")
;=>false
(not 0)
;=>false
;; Testing do form
(do (prn "prn output1"))
; "prn output1"
;=>nil
(do (prn "prn output2") 7)
; "prn output2"
;=>7
(do (prn "prn output1") (prn "prn output2") (+ 1 2))
; "prn output1"
; "prn output2"
;=>3
(do (def! a 6) 7 (+ a 8))
;=>14
a
;=>6
;; Testing recursive sumdown function
(def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0)))
(sumdown 1)
;=>1
(sumdown 2)
;=>3
(sumdown 6)
;=>21
;; Testing recursive fibonacci function
(def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2)))))))
(fib 1)
;=>1
(fib 2)
;=>2
(fib 4)
;=>5
(fib 10)
;=>89
;; -----------------------------------------------------
;; Testing string quoting
""
;=>""
"abc"
;=>"abc"
"abc def"
;=>"abc def"
"\""
;=>"\""
;; Testing pr-str
(pr-str)
;=>""
(pr-str "")
;=>"\"\""
(pr-str "abc")
;=>"\"abc\""
(pr-str "abc def" "ghi jkl")
;=>"\"abc def\" \"ghi jkl\""
(pr-str "\"")
;=>"\"\\\"\""
(pr-str (list 1 2 "abc" "\"") "def")
;=>"(1 2 \"abc\" \"\\\"\") \"def\""
;; Testing str
(str)
;=>""
(str "")
;=>""
(str "abc")
;=>"abc"
(str "\"")
;=>"\""
(str 1 "abc" 3)
;=>"1abc3"
(str "abc def" "ghi jkl")
;=>"abc defghi jkl"
;;; TODO: get this working properly
;;;(str (list 1 2 "abc" "\"") "def")
;;;;=>"(1 2 \"abc\" \"\\\"\")def"
;; Testing prn
(prn)
;
;=>nil
(prn "")
; ""
;=>nil
(prn "abc")
; "abc"
;=>nil
(prn "abc def" "ghi jkl")
; "abc def" "ghi jkl"
(prn "\"")
; "\""
;=>nil
(prn (list 1 2 "abc" "\"") "def")
; (1 2 "abc" "\"") "def"
;=>nil
;; Testing println
(println)
;
;=>nil
(println "")
;
;=>nil
(println "abc")
; abc
;=>nil
(println "abc def" "ghi jkl")
; abc def ghi jkl
(println "\"")
; "
;=>nil
(println (list 1 2 "abc" "\"") "def")
; (1 2 abc ") def
;=>nil
;;
;; -------- Optional Functionality --------
;; Testing keywords
(= :abc :abc)
;=>true
(= :abc :def)
;=>false
(= :abc ":abc")
;=>false
;; Testing vector truthiness
(if [] 7 8)
;=>7
;; Testing vector functions
(count [1 2 3])
;=>3
(empty? [1 2 3])
;=>false
(empty? [])
;=>true
(list? [4 5 6])
;=>false
;; Testing vector equality
(= [] (list))
;=>true
(= (list 1 2) [1 2])
;=>true
(= (list 1) [])
;=>false
(= [] [1])
;=>false
(= 0 [])
;=>false
(= [] 0)
;=>false
(= [] "")
;=>false
(= "" [])
;=>false
;; Testing vector parameter lists
( (fn* [] 4) )
;=>4
( (fn* [f x] (f x)) (fn* [a] (+ 1 a)) 7)
;=>8

+ 30
- 0
spec/crisp/mal_specs/tests/step5_tco.mal Visa fil

@ -0,0 +1,30 @@
;; Testing recursive tail-call function
(def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc)))))
(sum2 10 0)
;=>55
(def! res2 nil)
;=>nil
(def! res2 (sum2 10000 0))
res2
;=>50005000
;; Test recursive non-tail call function
(def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1))))))
(sum-to 10)
;=>55
;;; no try* yet, so test completion of side-effects
(def! res1 nil)
;=>nil
;;; For implementations without their own TCO this should fail and
;;; leave res1 unchanged
(def! res1 (sum-to 10000))
res1
;=>nil

+ 72
- 0
spec/crisp/mal_specs/tests/step6_file.mal Visa fil

@ -0,0 +1,72 @@
;;; TODO: really a step5 test
;;
;; Testing that (do (do)) not broken by TCO
(do (do 1 2))
;=>2
;;
;; Testing read-string, eval and slurp
(read-string "(1 2 (3 4) nil)")
;=>(1 2 (3 4) nil)
(read-string "(+ 2 3)")
;=>(+ 2 3)
(read-string "7 ;; comment")
;=>7
;;; Differing output, but make sure no fatal error
(read-string ";; comment")
(eval (read-string "(+ 2 3)"))
;=>5
;;; TODO: fix newline matching so that this works
;;;(slurp "../tests/test.txt")
;;;;=>"A line of text\n"
;; Testing load-file
(load-file "../tests/inc.mal")
(inc1 7)
;=>8
(inc2 7)
;=>9
(inc3 9)
;=>12
;;
;; Testing that *ARGV* exists and is an empty list
(list? *ARGV*)
;=>true
*ARGV*
;=>()
;;
;; -------- Optional Functionality --------
;; Testing comments in a file
(load-file "../tests/incB.mal")
; "incB.mal finished"
;=>"incB.mal return string"
(inc4 7)
;=>11
(inc5 7)
;=>12
;; Testing map literal across multiple lines in a file
(load-file "../tests/incC.mal")
mymap
;=>{"a" 1}
;;; TODO: really a step5 test
;; Testing that vector params not broken by TCO
(def! g (fn* [] 78))
(g)
;=>78
(def! g (fn* [a] (+ a 78)))
(g 3)
;=>81

+ 126
- 0
spec/crisp/mal_specs/tests/step7_quote.mal Visa fil

@ -0,0 +1,126 @@
;; Testing cons function
(cons 1 (list))
;=>(1)
(cons 1 (list 2))
;=>(1 2)
(cons 1 (list 2 3))
;=>(1 2 3)
(cons (list 1) (list 2 3))
;=>((1) 2 3)
;; Testing concat function
(concat)
;=>()
(concat (list 1 2))
;=>(1 2)
(concat (list 1 2) (list 3 4))
;=>(1 2 3 4)
(concat (list 1 2) (list 3 4) (list 5 6))
;=>(1 2 3 4 5 6)
(concat (concat))
;=>()
;; Testing regular quote
(quote 7)
;=>7
'7
;=>7
(quote (1 2 3))
;=>(1 2 3)
'(1 2 3)
;=>(1 2 3)
(quote (1 2 (3 4)))
;=>(1 2 (3 4))
'(1 2 (3 4))
;=>(1 2 (3 4))
;; Testing simple quasiquote
(quasiquote 7)
;=>7
`7
;=>7
(quasiquote (1 2 3))
;=>(1 2 3)
`(1 2 3)
;=>(1 2 3)
(quasiquote (1 2 (3 4)))
;=>(1 2 (3 4))
`(1 2 (3 4))
;=>(1 2 (3 4))
;; Testing unquote
`~7
;=>7
(def! a 8)
;=>8
`a
;=>a
`~a
;=>8
`(1 a 3)
;=>(1 a 3)
`(1 ~a 3)
;=>(1 8 3)
(def! b '(1 "b" "d"))
;=>(1 "b" "d")
`(1 b 3)
;=>(1 b 3)
`(1 ~b 3)
;=>(1 (1 "b" "d") 3)
;; Testing splice-unquote
(def! c '(1 "b" "d"))
;=>(1 "b" "d")
`(1 c 3)
;=>(1 c 3)
`(1 ~@c 3)
;=>(1 1 "b" "d" 3)
;; Testing symbol equality
(= 'abc 'abc)
;=>true
(= 'abc 'abcd)
;=>false
(= 'abc "abc")
;=>false
(= "abc" 'abc)
;=>false
;;;;; Test quine
;;; TODO: needs expect line length fix
;;;((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q)))))))
;;;=>((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q)))))))
;;
;; -------- Optional Functionality --------
;; Testing cons, concat, first, rest with vectors
(cons [1] [2 3])
;=>([1] 2 3)
(cons 1 [2 3])
;=>(1 2 3)
(concat [1 2] (list 3 4) [5 6])
;=>(1 2 3 4 5 6)
;; Testing unquote with vectors
(def! a 8)
;=>8
`[1 a 3]
;=>(1 a 3)
;;; TODO: fix this
;;;;=>[1 a 3]
;; Testing splice-unquote with vectors
(def! c '(1 "b" "d"))
;=>(1 "b" "d")
`[1 ~@c 3]
;=>(1 1 "b" "d" 3)
;;; TODO: fix this
;;;;=>[1 1 "b" "d" 3]

+ 164
- 0
spec/crisp/mal_specs/tests/step8_macros.mal Visa fil

@ -0,0 +1,164 @@
;; Testing non-macro function
(not (= 1 1))
;=>false
;;; This should fail if it is a macro
(not (= 1 2))
;=>true
;; Testing trivial macros
(defmacro! one (fn* () 1))
(one)
;=>1
(defmacro! two (fn* () 2))
(two)
;=>2
;; Testing unless macros
(defmacro! unless (fn* (pred a b) `(if ~pred ~b ~a)))
(unless false 7 8)
;=>7
(unless true 7 8)
;=>8
(defmacro! unless2 (fn* (pred a b) `(if (not ~pred) ~a ~b)))
(unless2 false 7 8)
;=>7
(unless2 true 7 8)
;=>8
;; Testing macroexpand
(macroexpand (unless2 2 3 4))
;=>(if (not 2) 3 4)
;; Testing nth, first and rest functions
(nth '(1) 0)
;=>1
(nth '(1 2) 1)
;=>2
(def! x "x")
(def! x (nth '(1 2) 2))
x
;=>"x"
(first '())
;=>nil
(first '(6))
;=>6
(first '(7 8 9))
;=>7
(rest '())
;=>()
(rest '(6))
;=>()
(rest '(7 8 9))
;=>(8 9)
;; Testing or macro
(or)
;=>nil
(or 1)
;=>1
(or 1 2 3 4)
;=>1
(or false 2)
;=>2
(or false nil 3)
;=>3
(or false nil false false nil 4)
;=>4
(or false nil 3 false nil 4)
;=>3
(or (or false 4))
;=>4
;; Testing cond macro
(cond)
;=>nil
(cond true 7)
;=>7
(cond true 7 true 8)
;=>7
(cond false 7 true 8)
;=>8
(cond false 7 false 8 "else" 9)
;=>9
(cond false 7 (= 2 2) 8 "else" 9)
;=>8
(cond false 7 false 8 false 9)
;=>nil
;;
;; Loading core.mal
(load-file "../core.mal")
;; Testing and macro
(and)
;=>true
(and 1)
;=>1
(and 1 2)
;=>2
(and 1 2 3)
;=>3
(and 1 2 3 4)
;=>4
(and 1 2 3 4 false)
;=>false
(and 1 2 3 4 false 5)
;=>false
;; Testing -> macro
(-> 7)
;=>7
(-> (list 7 8 9) first)
;=>7
(-> (list 7 8 9) (first))
;=>7
(-> (list 7 8 9) first (+ 7))
;=>14
(-> (list 7 8 9) rest (rest) first (+ 7))
;=>16
;; Testing EVAL in let*
(let* (x (or nil "yes")) x)
;=>"yes"
;;
;; -------- Optional Functionality --------
;; Testing nth, first, rest with vectors
(nth [1] 0)
;=>1
(nth [1 2] 1)
;=>2
(def! x "x")
(def! x (nth [1 2] 2))
x
;=>"x"
(first [])
;=>nil
(first [10])
;=>10
(first [10 11 12])
;=>10
(rest [])
;=>()
(rest [10])
;=>()
(rest [10 11 12])
;=>(11 12)
;; Testing EVAL in vector let*
(let* [x (or nil "yes")] x)
;=>"yes"

+ 264
- 0
spec/crisp/mal_specs/tests/step9_try.mal Visa fil

@ -0,0 +1,264 @@
;;
;; Testing try*/catch*
(try* 123 (catch* e 456))
;=>123
(try* (abc 1 2) (catch* exc (prn "exc is:" exc)))
; "exc is:" "'abc' not found"
;=>nil
;;;TODO: fix so long lines don't trigger ANSI escape codes ;;;(try*
;;;(try* (throw ["data" "foo"]) (catch* exc (do (prn "exc is:" exc) 7))) ;;;;
;;;; "exc is:" ["data" "foo"] ;;;;=>7
;;;;=>7
(try* (throw (list 1 2 3)) (catch* exc (do (prn "err:" exc) 7)))
; "err:" (1 2 3)
;=>7
(try* (throw "my exception") (catch* exc (do (prn "exc:" exc) 7)))
; "exc:" "my exception"
;=>7
;;; Test that throw is a function:
(try* (map throw (list 7)) (catch* exc exc))
;=>7
;;
;; Testing builtin functions
(symbol? 'abc)
;=>true
(symbol? "abc")
;=>false
(nil? nil)
;=>true
(nil? true)
;=>false
(true? true)
;=>true
(true? false)
;=>false
(true? true?)
;=>false
(false? false)
;=>true
(false? true)
;=>false
;; Testing apply function with core functions
(apply + (list 2 3))
;=>5
(apply + 4 (list 5))
;=>9
(apply prn (list 1 2 "3" (list)))
; 1 2 "3" ()
(apply prn 1 2 (list "3" (list)))
; 1 2 "3" ()
;; Testing apply function with user functions
(apply (fn* (a b) (+ a b)) (list 2 3))
;=>5
(apply (fn* (a b) (+ a b)) 4 (list 5))
;=>9
;; Testing map function
(def! nums (list 1 2 3))
(def! double (fn* (a) (* 2 a)))
(double 3)
;=>6
(map double nums)
;=>(2 4 6)
(map (fn* (x) (symbol? x)) (list 1 (symbol "two") "three"))
;=>(false true false)
;;
;; ------- Optional Functionality ----------
;; ------- (Needed for self-hosting) -------
;; Testing symbol and keyword functions
(symbol? :abc)
;=>false
(symbol? 'abc)
;=>true
(symbol? "abc")
;=>false
(symbol? (symbol "abc"))
;=>true
(keyword? :abc)
;=>true
(keyword? 'abc)
;=>false
(keyword? "abc")
;=>false
(keyword? (keyword "abc"))
;=>true
(symbol "abc")
;=>abc
;;;TODO: all implementations should suppport this too
;;;(keyword :abc)
;;;;=>:abc
(keyword "abc")
;=>:abc
;; Testing sequential? function
(sequential? (list 1 2 3))
;=>true
(sequential? [15])
;=>true
(sequential? sequential?)
;=>false
(sequential? nil)
;=>false
(sequential? "abc")
;=>false
;; Testing apply function with core functions and arguments in vector
(apply + 4 [5])
;=>9
(apply prn 1 2 ["3" 4])
; 1 2 "3" 4
;=>nil
;; Testing apply function with user functions and arguments in vector
(apply (fn* (a b) (+ a b)) [2 3])
;=>5
(apply (fn* (a b) (+ a b)) 4 [5])
;=>9
;; Testing map function with vectors
(map (fn* (a) (* 2 a)) [1 2 3])
;=>(2 4 6)
;; Testing vector functions
(vector? [10 11])
;=>true
(vector? '(12 13))
;=>false
(vector 3 4 5)
;=>[3 4 5]
(map? {})
;=>true
(map? '())
;=>false
(map? [])
;=>false
(map? 'abc)
;=>false
(map? :abc)
;=>false
;;
;; Testing hash-maps
(hash-map "a" 1)
;=>{"a" 1}
{"a" 1}
;=>{"a" 1}
(assoc {} "a" 1)
;=>{"a" 1}
(get (assoc (assoc {"a" 1 } "b" 2) "c" 3) "a")
;=>1
(def! hm1 (hash-map))
;=>{}
(map? hm1)
;=>true
(map? 1)
;=>false
(map? "abc")
;=>false
(get nil "a")
;=>nil
(get hm1 "a")
;=>nil
(contains? hm1 "a")
;=>false
(def! hm2 (assoc hm1 "a" 1))
;=>{"a" 1}
(get hm1 "a")
;=>nil
(contains? hm1 "a")
;=>false
(get hm2 "a")
;=>1
(contains? hm2 "a")
;=>true
;;; TODO: fix. Clojure returns nil but this breaks mal impl
(keys hm1)
;=>()
(keys hm2)
;=>("a")
;;; TODO: fix. Clojure returns nil but this breaks mal impl
(vals hm1)
;=>()
(vals hm2)
;=>(1)
(count (keys (assoc hm2 "b" 2 "c" 3)))
;=>3
(def! hm3 (assoc hm2 "b" 2))
(count (keys hm3))
;=>2
(count (vals hm3))
;=>2
(dissoc hm3 "a")
;=>{"b" 2}
(dissoc hm3 "a" "b")
;=>{}
(dissoc hm3 "a" "b" "c")
;=>{}
(count (keys hm3))
;=>2
;; Testing keywords as hash-map keys
(get {:abc 123} :abc)
;=>123
(contains? {:abc 123} :abc)
;=>true
(contains? {:abcd 123} :abc)
;=>false
(assoc {} :bcd 234)
;=>{:bcd 234}
(dissoc {:cde 345 :fgh 456} :cde)
;=>{:fgh 456}
(keyword? (nth (keys {:abc 123 :def 456}) 0))
;=>true
;;; TODO: support : in strings in make impl
;;;(keyword? (nth (keys {":abc" 123 ":def" 456}) 0))
;;;;=>false
(keyword? (nth (vals {"a" :abc "b" :def}) 0))
;=>true

+ 225
- 0
spec/crisp/mal_specs/tests/stepA_mal.mal Visa fil

@ -0,0 +1,225 @@
;;;
;;; See IMPL/tests/stepA_mal.mal for implementation specific
;;; interop tests.
;;;
;;
;; Testing readline
(readline "mal-user> ")
"hello"
;=>"\"hello\""
;;
;; Testing *host-language*
;;; each impl is different, but this should return false
;;; rather than throwing an exception
(= "something bogus" *host-language*)
;=>false
;;
;; ------- Optional Functionality ----------
;; ------- (Needed for self-hosting) -------
;;
;; Testing metadata on functions
;;
;; Testing metadata on mal functions
(meta (fn* (a) a))
;=>nil
(meta (with-meta (fn* (a) a) {"b" 1}))
;=>{"b" 1}
(meta (with-meta (fn* (a) a) "abc"))
;=>"abc"
(def! l-wm (with-meta (fn* (a) a) {"b" 2}))
(meta l-wm)
;=>{"b" 2}
(meta (with-meta l-wm {"new_meta" 123}))
;=>{"new_meta" 123}
(meta l-wm)
;=>{"b" 2}
(def! f-wm (with-meta (fn* [a] (+ 1 a)) {"abc" 1}))
(meta f-wm)
;=>{"abc" 1}
(meta (with-meta f-wm {"new_meta" 123}))
;=>{"new_meta" 123}
(meta f-wm)
;=>{"abc" 1}
(def! f-wm2 ^{"abc" 1} (fn* [a] (+ 1 a)))
(meta f-wm2)
;=>{"abc" 1}
;; Meta of native functions should return nil (not fail)
(meta +)
;=>nil
;;
;; Make sure closures and metadata co-exist
(def! gen-plusX (fn* (x) (with-meta (fn* (b) (+ x b)) {"meta" 1})))
(def! plus7 (gen-plusX 7))
(def! plus8 (gen-plusX 8))
(plus7 8)
;=>15
(meta plus7)
;=>{"meta" 1}
(meta plus8)
;=>{"meta" 1}
(meta (with-meta plus7 {"meta" 2}))
;=>{"meta" 2}
(meta plus8)
;=>{"meta" 1}
;;
;; Testing atoms
(def! inc3 (fn* (a) (+ 3 a)))
(def! a (atom 2))
;=>(atom 2)
;;;(type a)
;;;;=>"atom"
(deref a)
;=>2
@a
;=>2
(reset! a 3)
;=>3
@a
;=>3
(swap! a inc3)
;=>6
@a
;=>6
(swap! a (fn* (a) a))
;=>6
(swap! a (fn* (a) (* 2 a)))
;=>12
(swap! a (fn* (a b) (* a b)) 10)
;=>120
(swap! a + 3)
;=>123
;; Testing swap!/closure interaction
(def! inc-it (fn* (a) (+ 1 a)))
(def! atm (atom 7))
(def! f (fn* [] (swap! atm inc-it)))
(f)
;=>8
(f)
;=>9
;; Testing hash-map evaluation and atoms (i.e. an env)
(def! e (atom {"+" +}))
(swap! e assoc "-" -)
( (get @e "+") 7 8)
;=>15
( (get @e "-") 11 8)
;=>3
;;
;; ------- Optional Functionality --------------
;; ------- (Not needed for self-hosting) -------
;;
;; Testing conj function
(conj (list) 1)
;=>(1)
(conj (list 1) 2)
;=>(2 1)
(conj (list 2 3) 4)
;=>(4 2 3)
(conj (list 2 3) 4 5 6)
;=>(6 5 4 2 3)
(conj (list 1) (list 2 3))
;=>((2 3) 1)
(conj [] 1)
;=>[1]
(conj [1] 2)
;=>[1 2]
(conj [2 3] 4)
;=>[2 3 4]
(conj [2 3] 4 5 6)
;=>[2 3 4 5 6]
(conj [1] [2 3])
;=>[1 [2 3]]
;;
;; Testing metadata on collections
(meta [1 2 3])
;=>nil
(with-meta [1 2 3] {"a" 1})
;=>[1 2 3]
(meta (with-meta [1 2 3] {"a" 1}))
;=>{"a" 1}
(vector? (with-meta [1 2 3] {"a" 1}))
;=>true
(meta (with-meta [1 2 3] "abc"))
;=>"abc"
(meta (with-meta (list 1 2 3) {"a" 1}))
;=>{"a" 1}
(list? (with-meta (list 1 2 3) {"a" 1}))
;=>true
(meta (with-meta {"abc" 123} {"a" 1}))
;=>{"a" 1}
(map? (with-meta {"abc" 123} {"a" 1}))
;=>true
;;; Not actually supported by Clojure
;;;(meta (with-meta (atom 7) {"a" 1}))
;;;;=>{"a" 1}
(def! l-wm (with-meta [4 5 6] {"b" 2}))
;=>[4 5 6]
(meta l-wm)
;=>{"b" 2}
(meta (with-meta l-wm {"new_meta" 123}))
;=>{"new_meta" 123}
(meta l-wm)
;=>{"b" 2}
;;
;; Testing metadata on builtin functions
(meta +)
;=>nil
(def! f-wm3 ^{"def" 2} +)
(meta f-wm3)
;=>{"def" 2}
(meta +)
;=>nil

+ 1
- 0
spec/crisp/mal_specs/tests/test.txt Visa fil

@ -0,0 +1 @@
A line of text

Laddar…
Avbryt
Spara