;;; ;;; 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 ;>>> deferrable=True ;; ;; ------- Deferrable Functionality ---------- ;; ------- (Needed for self-hosting) ------- ;; ;; ;; 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 (swap! e assoc "foo" (list)) (get @e "foo") ;=>() (swap! e assoc "bar" '(1 2 3)) (get @e "bar") ;=>(1 2 3) ;; Testing for presence of optional functions (do (list time-ms string? number? seq conj meta with-meta fn?) nil) ;=>nil ;; ------------------------------------------------------------------ ;>>> soft=True ;>>> optional=True ;; ;; ------- Optional Functionality -------------- ;; ------- (Not 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 string? function (string? "") ;=>true (string? 'abc) ;=>false (string? "abc") ;=>true (string? :abc) ;=>false (string? (keyword "abc")) ;=>false (string? 234) ;=>false (string? nil) ;=>false ;; Testing number? function (number? 123) ;=>true (number? -1) ;=>true (number? nil) ;=>false (number? false) ;=>false (number? "123") ;=>false (def! add1 (fn* (x) (+ x 1))) ;; Testing fn? function (fn? +) ;=>true (fn? add1) ;=>true (fn? cond) ;=>false (fn? "+") ;=>false (fn? :+) ;=>false (fn? ^{"ismacro" true} (fn* () 0)) ;=>true ;; Testing macro? function (macro? cond) ;=>true (macro? +) ;=>false (macro? add1) ;=>false (macro? "+") ;=>false (macro? :+) ;=>false (macro? {}) ;=>false ;; ;; 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 seq function (seq "abc") ;=>("a" "b" "c") (apply str (seq "this is a test")) ;=>"this is a test" (seq '(2 3 4)) ;=>(2 3 4) (seq [2 3 4]) ;=>(2 3 4) (seq "") ;=>nil (seq '()) ;=>nil (seq []) ;=>nil (seq nil) ;=>nil ;; ;; 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" (with-meta [] "abc") ;=>[] (meta (with-meta (list 1 2 3) {"a" 1})) ;=>{"a" 1} (list? (with-meta (list 1 2 3) {"a" 1})) ;=>true (with-meta (list) {"a" 1}) ;=>() (empty? (with-meta (list) {"a" 1})) ;=>true (meta (with-meta {"abc" 123} {"a" 1})) ;=>{"a" 1} (map? (with-meta {"abc" 123} {"a" 1})) ;=>true (with-meta {} {"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 ;; Loading sumdown from computations.mal (load-file "../tests/computations.mal") ;=>nil ;; ;; Testing time-ms function (def! start-time (time-ms)) (= start-time 0) ;=>false (sumdown 10) ; Waste some time ;=>55 (> (time-ms) start-time) ;=>true ;; ;; Test that defining a macro does not mutate an existing function. (def! f (fn* [x] (number? x))) (defmacro! m f) (f (+ 1 1)) ;=>true (m (+ 1 1)) ;=>false