958 lines
30 KiB
Plaintext
958 lines
30 KiB
Plaintext
// DO NOT MOVE THIS OR ADD ANYTHING ABOVE IT! IT RELIES ON LINE NUMBERS!
|
|
(function _testAssert []
|
|
(try
|
|
(assert false (+ "false " "should " "have " "been " "true"))
|
|
(catch [:String message]
|
|
(Assert.equals "src/test/cases/BasicTestCase.kiss:4:13: Assertion failed: false should have been true
|
|
From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" message)))
|
|
|
|
(assert true)
|
|
(assert ![])
|
|
(assertEquals 6 6 6))
|
|
|
|
// (load) brings in the fields and compile-time definitions of another Kiss file
|
|
(load "BasicTestCaseExtra.kiss")
|
|
|
|
(function _testLoadInline []
|
|
(let [&mut thatValue 5]
|
|
(load "BasicTestCaseExtra2.kiss")
|
|
(Assert.equals 50 thatValue)))
|
|
|
|
// (var) declares static variables
|
|
(var message "Howdy")
|
|
|
|
(function _testHaxeInsertion []
|
|
// #| ... |# parses and injects raw Haxe code.
|
|
// Order of operations will apply
|
|
(Assert.equals 23 #|5 + 6 * 3|#)
|
|
// #{ ... }# parses and injects a raw Haxe block. It is preferred over #| |#
|
|
(let [&mut a 5 &mut b 6]
|
|
#{
|
|
a += 6; b += 5;
|
|
}#
|
|
(Assert.equals 11 a)
|
|
(Assert.equals 11 b)))
|
|
|
|
|
|
// (function) declares static functions
|
|
(function myFloor [num]
|
|
// funcalls can use dot access
|
|
(Math.floor num))
|
|
|
|
// functions are resolved in the macro context
|
|
(var funResult (myFloor 7.5))
|
|
|
|
// (prop) declares instance variables
|
|
(prop myField 5)
|
|
|
|
// (method) declares instance methods
|
|
(method myMethod [] this.myField)
|
|
|
|
// [...] returns a Kiss array (they have special features and convert implicitly)
|
|
(var myArray [1 2 3])
|
|
|
|
// Array access is via nth
|
|
(var myArrayLast (nth myArray -1))
|
|
|
|
// (collect) turns iterators to arrays
|
|
(function _testCollect []
|
|
(Assert.equals "[0,1,2]" (Std.string (collect (range 3)))))
|
|
|
|
(var mySum (+ 1 2 3))
|
|
|
|
(function _testSubtraction []
|
|
(Assert.equals -2 (- 5 4 3))
|
|
(Assert.equals -2 (- 2)))
|
|
|
|
(function _testMultiplication []
|
|
(Assert.equals 60 (* 2 5 6))
|
|
(Assert.equals 5522401584 (* 84 289 89 71 36))
|
|
(Assert.equals "heyheyhey" (* "hey" 3)))
|
|
|
|
// All math operations return floats, none truncate by default
|
|
(var myQuotient (/ 6 3 2 2))
|
|
|
|
(var myRemainder (% 10 6))
|
|
|
|
(var myPower (^ 2 8))
|
|
|
|
(var &mut myNum 6)
|
|
(var myInc ++myNum)
|
|
|
|
(var myMin (min 9 3 7 1))
|
|
(var myMax (max 9 3 7 1))
|
|
|
|
(function _testLessThan []
|
|
(Assert.isTrue (< 1 2 3 4))
|
|
(Assert.isFalse (< 1 1 3 4))
|
|
(Assert.isFalse (< 1 12 12)))
|
|
|
|
(function _testLesserEqual []
|
|
(Assert.isTrue (<= 1 2 3 4))
|
|
(Assert.isTrue (<= 1 1 3 4))
|
|
(Assert.isFalse (<= 1 12 11)))
|
|
|
|
(function _testGreaterThan []
|
|
(Assert.isTrue (> 4 3 2 1))
|
|
(Assert.isFalse (> 4 4 2 1))
|
|
(Assert.isFalse (> 9 3 3)))
|
|
|
|
(function _testGreaterEqual []
|
|
(Assert.isTrue (>= 4 3 2 1))
|
|
(Assert.isTrue (>= 4 4 2 1))
|
|
(Assert.isFalse (>= 9 4 5)))
|
|
|
|
(function _testEqual []
|
|
(Assert.isTrue (= 1 1 1 1))
|
|
(Assert.isFalse (= 1 2 1 1))
|
|
(Assert.isTrue (= "hey" "hey" "hey"))
|
|
(Assert.isFalse (= "hey" "you" "hey"))
|
|
(Assert.isTrue (= true true true))
|
|
(Assert.isFalse (= true false true))
|
|
(Assert.isTrue (= false false false)))
|
|
|
|
(function _testIf []
|
|
(Assert.equals true (if 1 true false))
|
|
(Assert.equals true (if 0 true false))
|
|
(Assert.equals true (if -1 true false))
|
|
(Assert.equals false (if null true false))
|
|
(Assert.equals true (if true true false))
|
|
(Assert.equals false (if false true false))
|
|
(Assert.equals true (if "string" true false))
|
|
(Assert.equals false (if "" true false))
|
|
(Assert.equals false (if [] true false))
|
|
(Assert.equals true (if [1] true false))
|
|
(Assert.equals 5 (if true 5))
|
|
(Assert.equals null (if false 5)))
|
|
|
|
(var :Int myInt 8)
|
|
|
|
(function myTryCatch [:Any e]
|
|
(try
|
|
(throw e)
|
|
(catch [:String error] 5)
|
|
(catch [:Int error] 6)
|
|
(catch [error] 7)))
|
|
|
|
(function myTypeCheck []
|
|
(the Int 5))
|
|
|
|
(function _testConcat []
|
|
(Assert.equals (.toString [1 2 3 4]) (.toString (concat [1] [2 3] [4]))))
|
|
|
|
(function _testGroups []
|
|
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (groups [1 2 3 4] 2)))
|
|
(Assert.equals (.toString [[1 2 3] [4]]) (.toString (groups [1 2 3 4] 3 Keep)))
|
|
(try (begin (groups [1 2 3 4] 3 Throw) (Assert.fail))
|
|
(catch [error] (Assert.pass))))
|
|
|
|
(function _testZip []
|
|
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (zipThrow [1 3] [2 4])))
|
|
(Assert.equals (.toString [[1 2] [3 null]]) (.toString (zipKeep [1 3] [2])))
|
|
(Assert.equals (.toString [[1 2] [null 4]]) (.toString (zipKeep [1 null] [2 4])))
|
|
(try (begin (zipThrow [1 3] [2]) (Assert.fail))
|
|
(catch [error] (Assert.pass)))
|
|
(try (begin (zipThrow [1] [2 4]) (Assert.fail))
|
|
(catch [error] (Assert.pass)))
|
|
(Assert.equals (.toString [[1 2 3] [2 null 3]]) (.toString (zipKeep [1 2] [2] [3 3])))
|
|
(Assert.equals (.toString [[1 2]]) (.toString (zipDrop [1 2 3 4] [2])))
|
|
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (apply zipThrow [[1 3] [2 4]]))))
|
|
|
|
(function _testEnumerate []
|
|
(Assert.equals (.toString [[0 1] [1 2]]) (.toString (enumerate [1 2])))
|
|
(Assert.equals (.toString [[1 1] [2 2]]) (.toString (enumerate [1 2] 1))))
|
|
|
|
(function _testLet []
|
|
(let [a 5
|
|
b 6
|
|
:String c "stuff"]
|
|
(Assert.equals 5 a)
|
|
(Assert.equals 6 b)
|
|
(Assert.equals "stuff" c))
|
|
(let [&mut a "str1"]
|
|
(Assert.equals "str1" a)
|
|
(set a "str2")
|
|
(Assert.equals "str2" a)))
|
|
|
|
(var myConstructedString (new String "sup"))
|
|
|
|
(function _testCond []
|
|
(Assert.equals "this one"
|
|
(cond
|
|
((= 5 6) "not this")
|
|
((= 8 9) "not this either")
|
|
((= 1 1) "this one")
|
|
(true "not the default")))
|
|
(Assert.equals "the default"
|
|
(cond
|
|
((= 5 6) "not this")
|
|
((= 8 9) "not this either")
|
|
((= 2 1) "not the third one")
|
|
(true "the default")))
|
|
(Assert.equals "this"
|
|
(cond
|
|
((= 5 5) "this")
|
|
(true "default")))
|
|
(Assert.equals null
|
|
(cond
|
|
(false "not this"))))
|
|
|
|
(function _testOr []
|
|
(Assert.equals 5 (or null 5))
|
|
// If the last value is falsy it can still be returned without breaking
|
|
// the expected behavior of or -- which also allows for the (or <optional arg> <default value>)
|
|
// idiom for empty arrays and strings
|
|
(Assert.equals (Std.string []) (Std.string (or null [])))
|
|
(Assert.equals "" (or null [] "")))
|
|
|
|
(function _testAnd []
|
|
(Assert.equals 6 (and 5 6))
|
|
(Assert.isFalse ?(and false 5 6))
|
|
(Assert.isFalse ?(and 5 false 6)))
|
|
|
|
(function mySetLocal []
|
|
(localVar &mut loc "one thing")
|
|
(set loc "another thing")
|
|
loc)
|
|
|
|
(var myNot1 (not 5))
|
|
(var myNot2 !5)
|
|
|
|
(var myFilteredList (begin
|
|
(localVar l [-1 -2 5 -3 6])
|
|
(l.filter (lambda [v] (< 0 v)))))
|
|
|
|
(var myWhen1 (when true 5 6))
|
|
|
|
(var myListOfTen [1 2 3 4 5 6 7 8 9 10])
|
|
|
|
(function _testQuickNths []
|
|
(Assert.equals 1 (first myListOfTen))
|
|
(Assert.equals 2 (second myListOfTen))
|
|
(Assert.equals 3 (third myListOfTen))
|
|
(Assert.equals 4 (fourth myListOfTen))
|
|
(Assert.equals 5 (fifth myListOfTen))
|
|
(Assert.equals 6 (sixth myListOfTen))
|
|
(Assert.equals 7 (seventh myListOfTen))
|
|
(Assert.equals 8 (eighth myListOfTen))
|
|
(Assert.equals 9 (ninth myListOfTen))
|
|
(Assert.equals 10 (tenth myListOfTen))
|
|
(Assert.equals 10 (last myListOfTen)))
|
|
|
|
(function _testListDestructuring []
|
|
(localVar [a b c d &mut e f g h i j] myListOfTen)
|
|
(Assert.equals 1 a)
|
|
(Assert.equals 2 b)
|
|
(Assert.equals 3 c)
|
|
(Assert.equals 4 d)
|
|
(Assert.equals 5 e)
|
|
(set e 6)
|
|
(Assert.equals 6 e)
|
|
(Assert.equals 6 f)
|
|
(Assert.equals 7 g)
|
|
(Assert.equals 8 h)
|
|
(Assert.equals 9 i)
|
|
(Assert.equals 10 j)
|
|
|
|
(let [[a b c &mut d e f g h i j] myListOfTen]
|
|
(Assert.equals 1 a)
|
|
(Assert.equals 2 b)
|
|
(Assert.equals 3 c)
|
|
(Assert.equals 4 d)
|
|
(set d 6)
|
|
(Assert.equals 6 d)
|
|
(Assert.equals 5 e)
|
|
(Assert.equals 6 f)
|
|
(Assert.equals 7 g)
|
|
(Assert.equals 8 h)
|
|
(Assert.equals 9 i)
|
|
(Assert.equals 10 j)))
|
|
|
|
|
|
(var myMetaList [myListOfTen myListOfTen myListOfTen])
|
|
|
|
(function _testDoFor []
|
|
(localVar &mut c 0)
|
|
(doFor v myListOfTen
|
|
(Assert.equals (+ c 1) v)
|
|
(set c v))
|
|
(doFor [a b c d e f g h i j] myMetaList
|
|
(Assert.equals 1 a)
|
|
(Assert.equals 2 b)
|
|
(Assert.equals 3 c)
|
|
(Assert.equals 4 d)
|
|
(Assert.equals 5 e)
|
|
(Assert.equals 6 f)
|
|
(Assert.equals 7 g)
|
|
(Assert.equals 8 h)
|
|
(Assert.equals 9 i)
|
|
(Assert.equals 10 j)))
|
|
|
|
(function _testFor []
|
|
(localVar incrementedList (for v myListOfTen (+ 1 v)))
|
|
(let [[a b c d e f g h i j] incrementedList]
|
|
(Assert.equals 2 a)
|
|
(Assert.equals 3 b)
|
|
(Assert.equals 4 c)
|
|
(Assert.equals 5 d)
|
|
(Assert.equals 6 e)
|
|
(Assert.equals 7 f)
|
|
(Assert.equals 8 g)
|
|
(Assert.equals 9 h)
|
|
(Assert.equals 10 i)
|
|
(Assert.equals 11 j))
|
|
(localVar smallerMetaList (for [a b c d e f g h i j] myMetaList [a e i]))
|
|
(doFor [a e i] smallerMetaList
|
|
(Assert.equals 1 a)
|
|
(Assert.equals 5 e)
|
|
(Assert.equals 10 i)))
|
|
|
|
(function myOptionalFunc [a &opt b c]
|
|
(Assert.equals 5 a)
|
|
(Assert.equals null b)
|
|
(Assert.equals 6 (or c 6))) // (or [optionalVar] [defaultValue]) is the convention for default values
|
|
|
|
(function myRestSum [firstOne &rest :List<Int> others]
|
|
(localVar &mut sum firstOne)
|
|
(doFor nextOne others (set sum (+ sum nextOne)))
|
|
sum)
|
|
|
|
(var myRest1 (myRestSum 5))
|
|
(var myRest2 (myRestSum 1 1 1 1 1))
|
|
(var myRest3 (myRestSum 1 2 2))
|
|
|
|
(function myCombinedOptRest [firstOne &opt secondOne &rest :List<String> thirdAndMore]
|
|
(localVar &mut concatString (+ firstOne (or secondOne "boop")))
|
|
(doFor str thirdAndMore (set concatString (+ concatString str)))
|
|
concatString)
|
|
|
|
(var myCombined1 (myCombinedOptRest "a" "b" "c" "d"))
|
|
(var myCombined2 (myCombinedOptRest "a"))
|
|
(var myCombined3 (myCombinedOptRest "a" "b"))
|
|
|
|
(function _testFieldExps []
|
|
(Assert.equals "hey" (.trim " hey "))
|
|
(Assert.equals "e" (.charAt (.trim " hey ") 1)))
|
|
|
|
(function _testBreakContinue []
|
|
(let [[a b c]
|
|
(for val [1 2 3 4 5 6 7 8]
|
|
(if (> val 6)
|
|
(break)
|
|
(if !(= 0 (% val 2))
|
|
(continue)
|
|
val)))]
|
|
(Assert.equals 2 a)
|
|
(Assert.equals 4 b)
|
|
(Assert.equals 6 c)))
|
|
|
|
(function _testApply []
|
|
(Assert.equals 6 (apply + [1 2 3])))
|
|
|
|
(function applyWithMethod [obj]
|
|
(apply .multiply obj [6]))
|
|
|
|
(function _testAnonymousObject []
|
|
(let [obj
|
|
(object
|
|
a "string A"
|
|
b 5)]
|
|
(Assert.equals "string A" obj.a)
|
|
(Assert.equals 5 obj.b)))
|
|
|
|
(function toOption [:Dynamic value]
|
|
(if value (Some value) None))
|
|
|
|
(function _testCase []
|
|
// otherwise branch must come last
|
|
(assertThrowsAtCompileTime (case null (otherwise "thing") (v "OtherThing")))
|
|
// Even if it is in (never otherwise) form
|
|
(assertThrowsAtCompileTime (case null (never otherwise) (v "OtherThing")))
|
|
// null must be matched
|
|
(assertThrowsAtCompileTime (case null (v "thing")))
|
|
(case (toOption [])
|
|
(None (Assert.pass))
|
|
(never otherwise))
|
|
(case (toOption "hey")
|
|
(never None)
|
|
((Some "hey") (Assert.pass))
|
|
(never otherwise))
|
|
(Assert.equals 5 (case (toOption 0)
|
|
(otherwise 5)))
|
|
// Test case with guards and multiple values
|
|
(case 5
|
|
((or 5 6) (Assert.pass))
|
|
(otherwise (Assert.fail)))
|
|
(case [2 3]
|
|
((or [_ 3] [1 1]) (Assert.pass))
|
|
(otherwise (Assert.fail)))
|
|
(case 5
|
|
((when false (or 5 6)) (Assert.fail))
|
|
((when true (or 7 8 9)) (Assert.fail))
|
|
(otherwise (Assert.pass)))
|
|
(case 5
|
|
((unless true (or 5 6)) (Assert.fail))
|
|
((unless false (or 7 8 9)) (Assert.fail))
|
|
(otherwise (Assert.pass)))
|
|
// In Haxe,
|
|
// `switch (Some(true)) { case Some(true | false): "a"; default: "b"; }`
|
|
// returns "a", so nested use of `or` in case patterns should also be valid:
|
|
(case (Some true)
|
|
((Some (or true false))
|
|
(Assert.pass))
|
|
(otherwise (Assert.fail)))
|
|
(case (Some 5)
|
|
((Some (or 6 5 4))
|
|
(Assert.pass))
|
|
(otherwise (Assert.fail)))
|
|
// In Haxe, name = Pattern can be used in switch/case to match values: https://haxe.org/manual/lf-pattern-matching-variable-capture.html
|
|
// In Kiss, the syntax for this is (as name pattern)
|
|
(case (Some (Some 5))
|
|
((Some (as inner (Some v)))
|
|
(Assert.equals 5 v)
|
|
(Assert.isTrue (Type.enumEq (Some 5) inner)))
|
|
(otherwise (Assert.fail)))
|
|
|
|
// Otherwise blocks should allow multiple expressions, too:
|
|
(case 5
|
|
(otherwise
|
|
6 5)))
|
|
|
|
(function _testMaps []
|
|
(localVar :Map<String,String> myMap [=>"hey" "you"
|
|
=>"found" "me"])
|
|
(Assert.equals "you" (dictGet myMap "hey"))
|
|
(Assert.equals "me" (dictGet myMap "found"))
|
|
(doFor =>key value myMap
|
|
(assertLet [(Some _) (indexOf ["hey" "found"] key)] 0)
|
|
(assertLet [(Some _) (indexOf ["you" "me"] value)] 0))
|
|
|
|
// Map destructuring:
|
|
(let [[=>"hey" v1 =>"found" v2] myMap]
|
|
(Assert.equals "you" v1)
|
|
(Assert.equals "me" v2)))
|
|
|
|
(function _testRange []
|
|
// With just one arg, it's the max:
|
|
(localVar &mut :kiss.List<Int> myList (for i (range 5) i))
|
|
(Assert.equals 4 (nth myList -1))
|
|
// with two args, they are min and max:
|
|
(set myList (for i (range 3 5) i))
|
|
(Assert.equals 3 (first myList))
|
|
(Assert.equals 4 (last myList))
|
|
// With three args, they are min, max, and step:
|
|
(set myList (for i (range 7 17 2) i))
|
|
(Assert.equals 7 (first myList))
|
|
(Assert.equals 9 (second myList))
|
|
(Assert.equals 15 (last myList)))
|
|
|
|
(function _testRest []
|
|
(Assert.equals (.toString [2 3 4]) (.toString (rest [1 2 3 4]))))
|
|
|
|
(function doSomething [:Int->Int func]
|
|
(func 5))
|
|
|
|
(function itsAMonster [:Null<Map<String,Map<String,Array<String>>>> monsterArg] "but it still compiles")
|
|
|
|
(function _testTypeParsing []
|
|
// Do stuff with functions that take complex type parameters, mostly just to check if it compiles
|
|
(Assert.equals 5 (doSomething (lambda [i] i)))
|
|
(Assert.equals 7 (doSomething (lambda [i] (+ i 2))))
|
|
// Pass null to the really crazy one because I'm lazy:
|
|
(Assert.equals "but it still compiles" (itsAMonster null)))
|
|
|
|
(defMacro defconstfunc [name const] `(function ,name [] ,const))
|
|
|
|
(defconstfunc func5 5)
|
|
(defconstfunc funcHello "hello")
|
|
|
|
(function _testDefmacro []
|
|
(Assert.equals 5 (func5))
|
|
(Assert.equals "hello" (funcHello)))
|
|
|
|
(var &mut welcomeCount 0)
|
|
(defMacro macroWithLogic [name]
|
|
(localVar message1 (ReaderExp.StrExp "Welcome "))
|
|
(localVar message2 (ReaderExp.StrExp " (Guest #"))
|
|
(localVar message3 (ReaderExp.StrExp ")"))
|
|
|
|
`(begin (set welcomeCount (+ welcomeCount 1))
|
|
(+ ,message1 ,name ,message2 (Std.string welcomeCount) ,message3)))
|
|
|
|
(function _testDefmacroWithLogic []
|
|
(Assert.equals "Welcome Stevo (Guest #1)" (macroWithLogic "Stevo"))
|
|
(Assert.equals "Welcome Bob (Guest #2)" (macroWithLogic "Bob")))
|
|
|
|
// Make sure built-in call aliases don't override user-defined variables
|
|
(function _testCallAlias []
|
|
(let [map [=>"hey" "you"]]
|
|
(Assert.equals "you" (dictGet map "hey"))))
|
|
|
|
(function _testAssignArith []
|
|
(localVar &mut num 5)
|
|
(+= num 5 6)
|
|
(Assert.equals 16 num)
|
|
(%= num 5)
|
|
(Assert.equals 1 num)
|
|
(^= num 3)
|
|
(Assert.equals 1 num)
|
|
(*= num 25 2)
|
|
(Assert.equals 50 num)
|
|
(/= num 25 2)
|
|
(Assert.equals 1 num)
|
|
(-= num 5 6)
|
|
(Assert.equals -10 num))
|
|
|
|
// these declarations have to come before the ifLets to get the type detection correct for issue 64
|
|
(var :String realStringVar "something")
|
|
(var :String nullStringVar null)
|
|
|
|
(function issue64withArgs [:String realStringArg :String nullStringArg]
|
|
(unlessLet [something realStringArg]
|
|
(Assert.fail))
|
|
(whenLet [something nullStringArg]
|
|
(Assert.fail)))
|
|
|
|
(function _testPatternLets []
|
|
(let [some5 (Some 5)
|
|
some6 (Some 6)
|
|
none None
|
|
:Null<Option<Any>> oops null]
|
|
(ifLet [(Some a) some5
|
|
(Some b) some6]
|
|
(Assert.equals 11 (+ a b))
|
|
(Assert.fail))
|
|
(ifLet [(Some a) none]
|
|
(Assert.fail))
|
|
(whenLet [(Some a) oops]
|
|
(print "something went wrong!")
|
|
(Assert.fail))
|
|
(unlessLet [(Some (or 5 6)) some5]
|
|
(print "something else went wrong!")
|
|
(Assert.fail))
|
|
|
|
// Don't double evaluate the expression:
|
|
(let [&mut v 1]
|
|
(unlessLet [2 (begin (+= v 1) v)]
|
|
(Assert.fail))
|
|
(Assert.equals 2 v))
|
|
|
|
(assertThrows (assertLet [(Some thing) none] thing))
|
|
(Assert.equals 5 (assertLet [(Some thing) some5] thing)))
|
|
|
|
// Issue #64 regression tests:
|
|
(whenLet [something null]
|
|
(Assert.fail))
|
|
(let [:String realString "something"
|
|
:String nullString null]
|
|
(unlessLet [something realString]
|
|
(Assert.fail))
|
|
(whenLet [something nullString]
|
|
(Assert.fail)))
|
|
(unlessLet [something realStringVar]
|
|
(Assert.fail))
|
|
(whenLet [something nullStringVar]
|
|
(Assert.fail))
|
|
(issue64withArgs "something" null))
|
|
|
|
(function _testRawString []
|
|
(Assert.equals "\\" #"\"#)
|
|
(Assert.equals "\"#" ##""#"##))
|
|
|
|
(function _testKissStrings []
|
|
(Assert.equals #{ "\\\t\r\n\"$"; }# "\\\t\r\n\"\$")
|
|
(let [str "it's"
|
|
num 3
|
|
l1 ["a" "b" "c"]
|
|
l2 [1 2 3]]
|
|
// string interpolation:
|
|
(Assert.equals "it's 3asy as [a,b,c] [1,2,3]" "$str ${num}asy as $l1 $l2")))
|
|
|
|
(function _testArrowLambdas []
|
|
(let [withArgs
|
|
->[arg1 arg2] (+ arg1 arg2)
|
|
withArg
|
|
->arg (* 2 arg)
|
|
withoutArgs
|
|
->{
|
|
(+ 5)
|
|
6}
|
|
&mut num 5
|
|
void
|
|
->:Void [] (set num 6)]
|
|
(Assert.equals 11 (withArgs 5 6))
|
|
(Assert.equals 12 (withArg 6))
|
|
(Assert.equals 6 (withoutArgs))
|
|
(void)
|
|
(Assert.equals 6 num)))
|
|
|
|
(var &mut voidRan false)
|
|
(function :Void myVoid [] (set voidRan true))
|
|
(function _testVoid []
|
|
(myVoid)
|
|
(Assert.isTrue voidRan))
|
|
|
|
(function _testLetThrow []
|
|
(try
|
|
{
|
|
(letThrow
|
|
(throw "the error we want")
|
|
(catch [e] (Assert.fail)))
|
|
(Assert.fail)}
|
|
(catch [:String e]
|
|
(Assert.equals "the error we want" e))))
|
|
|
|
// Test dot-access on identifiers aliases
|
|
(var objWithField (object field 5))
|
|
(var float 0.5) // This should still read as a float, not a dot access on a variable called 0
|
|
(defAlias &ident owf objWithField)
|
|
(function _testDotAccessOnAlias []
|
|
(Assert.equals 5 owf.field))
|
|
|
|
(function _testClamp []
|
|
(let [&mut bigValue 12
|
|
&mut smallValue 3]
|
|
(Assert.equals 10 (clamp bigValue 5 10))
|
|
(Assert.equals 10 bigValue)
|
|
(Assert.equals 5 (clamp smallValue 5 10))
|
|
(Assert.equals 5 smallValue)))
|
|
|
|
(function _testCountingLambda []
|
|
(let [fullSyntax
|
|
(countingLambda a [] a)
|
|
arrowSyntax
|
|
-+>b {b}]
|
|
(Assert.equals 1 (fullSyntax))
|
|
(Assert.equals 2 (fullSyntax))
|
|
(Assert.equals 1 (arrowSyntax))
|
|
(Assert.equals 2 (arrowSyntax))))
|
|
|
|
(function _testExpComment []
|
|
(Assert.equals 15 (+ **6 5 **(- 5 11) 5 (+ 5 **(20 9)))))
|
|
|
|
(var staticValue 9)
|
|
(prop value 2)
|
|
(method _testEval []
|
|
(Assert.equals 9 (eval 'staticValue))
|
|
(Assert.equals 2 (eval 'value))
|
|
(Assert.equals 11 (eval '(+ staticValue value))))
|
|
|
|
(function _testEvalStatic []
|
|
(Assert.equals 9 (eval 'staticValue))
|
|
(assertThrows (eval 'value)))
|
|
|
|
(function _testCaseOnNull []
|
|
(Assert.equals 5 (case null (v 10) (null 5)))
|
|
(Assert.equals 5 (case null (v 10) (null 5) (otherwise 6)))
|
|
(Assert.equals 5 (case null (v 10) (otherwise 5))))
|
|
|
|
(function _testContains []
|
|
(assert (contains "abc" "b"))
|
|
(assert !(contains "abc" "z"))
|
|
(assert (contains [1 2 3] 1))
|
|
(assert !(contains [1 2 3] 5))
|
|
(Assert.pass))
|
|
|
|
(function _testIntersect []
|
|
(let [intersection2d
|
|
(for i (intersect (.split "abc" "") (.split "xyz" "")) (i.join ""))
|
|
intersection3d
|
|
(for i (intersect (.split "abc" "") (.split "xyz" "") (.split "123" "")) (i.join ""))]
|
|
(assert (contains intersection2d "ax"))
|
|
(assert (contains intersection2d "ay"))
|
|
(assert (contains intersection2d "az"))
|
|
(assert (contains intersection2d "bx"))
|
|
(assert (contains intersection2d "by"))
|
|
(assert (contains intersection2d "bz"))
|
|
(assert (contains intersection2d "cx"))
|
|
(assert (contains intersection2d "cy"))
|
|
(assert (contains intersection2d "cz"))
|
|
(assert (contains intersection3d "ax1"))
|
|
(assert (contains intersection3d "ax3"))
|
|
(assert (contains intersection3d "bx3"))
|
|
(assert (contains intersection3d "cy1"))
|
|
(assert (contains intersection3d "cy3"))
|
|
)
|
|
(Assert.pass))
|
|
|
|
(function _testWhileLet []
|
|
(let [&mut idx 0
|
|
lines ["a" "b" "c"]
|
|
stream (Stream.fromString "a\nb\nc")]
|
|
(whileLet [(Some line) (stream.takeLine)]
|
|
(Assert.equals (nth lines idx) line)
|
|
(+= idx 1)))
|
|
(let [lines ["a" "b" "c"]
|
|
options [(Some "a") (Some "b") (Some "c") None]
|
|
collected
|
|
(collectWhileLet [(Some line) (options.shift)]
|
|
line)]
|
|
(doFor i (range collected.length)
|
|
(Assert.equals (nth lines i) (nth collected i)))))
|
|
|
|
(function _testTrace []
|
|
(Assert.equals 5 (trace 5 "num"))
|
|
(Assert.equals 5 ~5))
|
|
|
|
// The test here is that this was inserted by insertUTestCase :)
|
|
(function _testInsertUTestCase []
|
|
(Assert.pass))
|
|
|
|
(function _testQuickFractions []
|
|
(Assert.equals 0.5 (fHalf 1))
|
|
(Assert.equals 0 (iHalf 1)))
|
|
|
|
(function _testWhenLetGuards []
|
|
// Guards should be allowed in whenLet patterns
|
|
(whenLet [(when true 5) 5]
|
|
(Assert.pass)))
|
|
|
|
(function _testImportAndUsingInBuildMacro []
|
|
(assertThrowsAtCompileTime (import pack.Type))
|
|
(assertThrowsAtCompileTime (importAs pack.Type Alias))
|
|
(assertThrowsAtCompileTime (importAll pack))
|
|
(assertThrowsAtCompileTime (using pack.Type))
|
|
(Assert.pass))
|
|
|
|
(function _testPureKissClasses []
|
|
(PureKissClass.test)
|
|
(Assert.pass))
|
|
|
|
(function _testArraysToVariadic []
|
|
(let [a [5 6 7]]
|
|
(assertThrows (+ a))
|
|
(assertThrows (- a))
|
|
(assertThrows (* a))
|
|
(assertThrows (/ a))
|
|
(assertThrows (min a))
|
|
(assertThrows (max a))
|
|
(assertThrows (= a))
|
|
(assertThrows (< a))
|
|
(assertThrows (<= a))
|
|
(assertThrows (> a))
|
|
(assertThrows (>= a))
|
|
|
|
)
|
|
(Assert.pass))
|
|
|
|
(function _hasThreadSupport []
|
|
(#if target.threaded
|
|
true
|
|
false))
|
|
|
|
(var &mut _staticProp 5)
|
|
(var :Int staticProp (property get set))
|
|
(function set_staticProp [v] (set _staticProp v))
|
|
(function get_staticProp [] _staticProp)
|
|
|
|
(var :(Int,Int)->Bool lambdaTest ->[a b] true)
|
|
(var :()->Void lambdaTest2 ->[] (return))
|
|
(function _testLambdaTypeAnnotations []
|
|
(Assert.isTrue (lambdaTest 5 6))
|
|
(lambdaTest2))
|
|
|
|
(defMacro __testCaseMacroError1 []
|
|
(case ["thing" 2] `5))
|
|
|
|
(defMacro __testCaseMacroError2 []
|
|
(case 5
|
|
((Some v) `false)
|
|
(otherwise `false)))
|
|
|
|
(defMacro __testCaseMacroError3 []
|
|
(case 5
|
|
([not this] `false)
|
|
(otherwise `false)))
|
|
|
|
(defMacro __testCaseMacroError4 [s]
|
|
(case (symbolNameValue s)
|
|
("rightSymbol" `true)
|
|
(otherwise `false)))
|
|
|
|
(defMacro __testCaseMacroError5 [n]
|
|
(case (eval n)
|
|
(5 `true)
|
|
(otherwise `false)))
|
|
|
|
(function _testCaseMacroError []
|
|
(assertThrowsAtCompileTime
|
|
(__testCaseMacroError1))
|
|
(assertThrowsAtCompileTime
|
|
(__testCaseMacroError2))
|
|
(assertThrowsAtCompileTime
|
|
(__testCaseMacroError3))
|
|
(Assert.isTrue (__testCaseMacroError4 rightSymbol))
|
|
(Assert.isFalse (__testCaseMacroError4 wrongSymbol))
|
|
(Assert.isTrue (__testCaseMacroError5 5))
|
|
(Assert.isFalse (__testCaseMacroError5 6)))
|
|
|
|
(function _testHaxeProperties []
|
|
(Assert.equals 5 staticProp)
|
|
(Assert.equals 9 (set staticProp 9))
|
|
(Assert.equals 9 staticProp)
|
|
(Assert.equals 9 _staticProp))
|
|
|
|
(function _testWithFunctions []
|
|
(withFunctions
|
|
[
|
|
(a [val] (+ val 1))
|
|
(b [val] (+ val 2))
|
|
]
|
|
(localFunction c [val] (+ (a val) (b val)))
|
|
(Assert.equals 5 (c 1))))
|
|
|
|
(function _testWithTempSet []
|
|
(let [&mut v 5
|
|
&mut v2 3]
|
|
(assertEquals 5 v)
|
|
(assertEquals 3 v2)
|
|
(withTempSet [v 6]
|
|
(assertEquals 6 v)
|
|
(assertEquals 3 v2))
|
|
(assertEquals 5 v)
|
|
(assertEquals 3 v2)
|
|
(withTempSet [v 7 v2 9]
|
|
(assertEquals 7 v)
|
|
(assertEquals 9 v2))
|
|
(assertEquals 5 v)
|
|
(assertEquals 3 v2))
|
|
(Assert.pass))
|
|
|
|
(var &mut savedPrints [])
|
|
(function savePrint []
|
|
(set savedPrints [])
|
|
->:Void [:String s] (savedPrints.push s))
|
|
|
|
(prop anotherNullToPrint null)
|
|
(var anotherStaticNullToPrint null)
|
|
|
|
(method _testPrintMacrosInstance []
|
|
(withTempSet [Prelude.printStr (savePrint)]
|
|
(printAllNulls)
|
|
(Assert.isTrue (savedPrints.contains "anotherNullToPrint: null"))
|
|
(Assert.isTrue (savedPrints.contains "anotherStaticNullToPrint: null"))
|
|
(Assert.isTrue (savedPrints.contains "nullDefinedInHaxe: null"))
|
|
(Assert.isTrue (savedPrints.contains "staticNullDefinedInHaxe: null"))
|
|
|
|
// TODO This statement prints a warning at compile-time, which won't
|
|
// appear in savedPrints, so it's harder to test...
|
|
(prop tp "bad")
|
|
|
|
(let [u null]
|
|
// TODO this statement should print a warning at compile-time (#112)
|
|
(localVar v "bad")
|
|
|
|
(set savedPrints [])
|
|
(printLocalNulls)
|
|
(Assert.isFalse (savedPrints.contains "anotherNullToPrint: null"))
|
|
(Assert.isFalse (savedPrints.contains "anotherStaticNullToPrint: null"))
|
|
(Assert.isTrue (savedPrints.contains "u: null")))))
|
|
|
|
(function _testPrintMacrosStatic []
|
|
(withTempSet [Prelude.printStr (savePrint)]
|
|
(printAllNulls)
|
|
(Assert.isTrue (savedPrints.contains "anotherStaticNullToPrint: null"))
|
|
(Assert.isTrue (savedPrints.contains "staticNullDefinedInHaxe: null"))
|
|
|
|
// TODO This statement prints a warning at compile-time, which won't
|
|
// appear in savedPrints, so it's harder to test...
|
|
(var ts "bad")
|
|
|
|
(let [u null]
|
|
// TODO this statement should print a warning at compile-time (#112)
|
|
(localVar v "bad")
|
|
|
|
(set savedPrints [])
|
|
(printLocalNulls)
|
|
(Assert.isFalse (savedPrints.contains "anotherStaticNullToPrint: null"))
|
|
(Assert.isTrue (savedPrints.contains "u: null")))
|
|
|
|
// Test for loop capture variables
|
|
(set savedPrints [])
|
|
(doFor a (for _ (range 5) null)
|
|
(printLocalNulls))
|
|
(Assert.isTrue (savedPrints.contains "a: null"))
|
|
(Assert.equals 5 savedPrints.length)
|
|
|
|
(set savedPrints [])
|
|
(let [:Map<String,String> m (for a (range 5) =>"$a" "a")]
|
|
(doFor =>k v m
|
|
(set k null)
|
|
(printLocalNulls)))
|
|
(Assert.isTrue (savedPrints.contains "k: null"))
|
|
(Assert.equals 5 savedPrints.length)
|
|
|
|
(set savedPrints [])
|
|
(let [:Map<Int,String> m (for a (range 5) =>a null)]
|
|
(doFor =>k v m
|
|
(printLocalNulls)))
|
|
(Assert.isTrue (savedPrints.contains "v: null"))
|
|
(Assert.equals 5 savedPrints.length)
|
|
|
|
(set savedPrints [])
|
|
(doFor [a b c] (for _ (range 5) [1 null 5])
|
|
(printLocalNulls))
|
|
(Assert.isTrue (savedPrints.contains "b: null"))
|
|
(Assert.equals 5 savedPrints.length)
|
|
|
|
(set savedPrints [])
|
|
(doFor :String s (for _ (range 5) null)
|
|
(printLocalNulls))
|
|
(Assert.isTrue (savedPrints.contains "s: null"))
|
|
(Assert.equals 5 savedPrints.length)
|
|
|
|
// Test case extraction locals:
|
|
(set savedPrints [])
|
|
(case None
|
|
(None (printLocalNulls) /* Won't print */)
|
|
(otherwise))
|
|
(case (Some null)
|
|
((Some v) (printLocalNulls))
|
|
(otherwise))
|
|
(Assert.isTrue (savedPrints.contains "v: null"))
|
|
(Assert.equals 1 savedPrints.length)
|
|
|
|
(set savedPrints [])
|
|
(case (Some (Some (Some [1 2 null])))
|
|
((Some (Some (Some [a b c])))
|
|
(printLocalNulls))
|
|
(otherwise))
|
|
(Assert.isTrue (savedPrints.contains "c: null"))))
|
|
|
|
(function :Void _testTypeCase []
|
|
(typeCase ["a"]
|
|
([:String a]
|
|
(Assert.equals "a" a)))
|
|
(typeCase ["a" 1]
|
|
(never [:String a :String one])
|
|
([:String a :Int one]
|
|
(Assert.equals "a1" "${a}${one}")))
|
|
(typeCase ["a" 5 5.5 true]
|
|
([:String a :Int five :Float fivePointFive :Bool tt]
|
|
(Assert.equals "a55.5true" "${a}${five}${fivePointFive}${tt}"))
|
|
(never otherwise)))
|
|
|
|
|
|
|
|
|
|
(function _testQuickPrintOnSetVar []
|
|
(let [&mut v 5]
|
|
(set (trace v) 7)
|
|
(set (print v) 8)
|
|
(set (Prelude.print v) 9)
|
|
(set ~v 6)
|
|
(Assert.equals v 6)))
|
|
|
|
(defAlias &ident otherNameForObj obj)
|
|
(function _testSafeAccess []
|
|
(let [:Dynamic obj null]
|
|
(obj?.doThing)
|
|
(otherNameForObj?.doThing)
|
|
(?.doThing obj)
|
|
(?.doThing otherNameForObj))
|
|
(Assert.pass))
|
|
|
|
(function _testSplitByAll []
|
|
(Assert.equals
|
|
(Std.string ["Thing" "<" "Generic" ">" "->" "Thing"])
|
|
(Std.string (Prelude.splitByAll "Thing<Generic>->Thing" [">" "<" "->"])))) |