Uses 679K of libraries. Click here for Pure Java version (38688L/196K).
!include once #1034831 // Gazelle 22 Function Include for Testing set flag PingV3. scope test_leftArrowScript sclass #ClassA {} sclass #ClassB extends ClassA {} sclass #ClassC extends ClassB {} sclass #StaticField { sS theField; } sclass #StaticFieldSubClass extends StaticField { } interface #StaticFieldInInterface { sS daField = "yo"; } sclass #StaticFieldInterfaceImplementor is StaticFieldInInterface { } sclass #InheritanceDispatchTest { static S f(ClassA a) { ret "a"; } static S f(ClassB a) { ret "b"; } } sclass #Tester { O value = "123"; sO myStaticField = "ok"; } sclass #Sub1 { sclass X { static int value = 1; } } sclass #Sub2 { sclass X { static int value = 2; } } interface #DefaultMethodInterface { default S x() { ret "y"; } } sclass #DefaultMethodTest is DefaultMethodInterface { } svoid test_leftArrowScript() { test_leftArrowScript_pinging(); embedded S countLoop(int n) { ret [[ i <- 0; while lessThan i ]] + n + [[ { i <- plus i 1 }; i ]]; } S ifThenElseScript = [[ if lessThan a b { joinWithSpace "It's" "less" } else if greaterThan a b { joinWithSpace "It's" "greater" } else { joinWithSpace "They're" "equal" } ]]; testFunctionValues(script -> leftArrowVerbose((S) script), // int primitive [[ 5 ]], 5, [[ -5 ]], -5, // function definition & call [[ def double x { Math multiplyExact x 2 } double 10 ]], 20, // new object with constructor arguments [[ new Pair "hello" "world" ]], pair("hello", "world"), // double constant [[ str 1.5e2 ]], "150.0", // float constant [[ 1.5e2f ]], 150f, [[ 1.5e2F ]], 150f, // long constant [[ 0L ]], 0L, // hex constant [[ 0x80 ]], 0x80, // binary constant [[ 0B101 ]], 0B101, // character constant [[ '\t' ]], '\t', // [not implemented, too complicated] // last = result of last statement // [[ plus 1 2; Math addExact 5 last ]], 8, // get static field [[ Color black ]], Color.black, // get instance field, [[ tester <- new test_leftArrowScript_Tester; tester value ]], "123", // while loop countLoop(5), 5, // if statement [[ if lessThan 0 1 { "ok" } ]], "ok", [[ if lessThan 1 0 { "ok" } ]], null, // for each [[ l <- ll 2 3 sum <- 0 for number in l { sum <- plus sum number } sum ]], 5, // for each is also map() [[ for i in ll 2 3 { plus i 1 } ]], ll(3, 4), // for each as nested expression [[ joinWithSpace (for i in ll 2 3 { i }) ]], "2 3", // for i to n [[ for i to 2 { i } ]], ll(0, 1), // for with byte array [[ for b in litbytearray (toByte 5) (toByte 7) { b } ]], ll((byte) 5, (byte) 7), // for with double array [[ for b in litdoublearray 5.0 7.0 { b } ]], ll(5.0, 7.0), // for with char array [[ for c in chars "AB" { c } ]], ll('A', 'B'), // for with typed variable [[ for c: char in chars "AB" { c } ]], ll('A', 'B'), // some bug [[ img <- newImage 10 10 r <- randomRect img 10 10 ]], rect(0, 0, 10, 10), // another bug [[ a <- 1 b <- a a ]], 1, // null bug [[ a <- 1 a <- null a ]], null, // return at the end [[ return 17 ]], 17, // two returns (first wins) [[ return 13 return 22 ]], 13, // same with "ret" for "return" [[ ret 13 ret 22 ]], 13, // conditional return [[ if true { return "so true" } return "oops" ]], "so true", [[ if false { return "not true" } return "but this" ]], "but this", // if-then-else [[ a <- 1; b <- 2; ]] + ifThenElseScript, "It's less", [[ a <- 6; b <- 2; ]] + ifThenElseScript, "It's greater", [[ a <- 5.0; b <- 5.0; ]] + ifThenElseScript, "They're equal", // if-then-else with "then" keyword but without curly braces [[ if true then "ok" else "not ok" ]], "ok", [[ if false then "ok" else "not ok" ]], "not ok", // nested expressions [[ plus (plus 1 2) 4 ]], 7, [[ (plus 5 6) toString ]], "11", // nested expressions over 2 lines (it's ok to split an expression // over multiple lines if you at least parenthesis is still open) [[ (plus 1 (plus 2 3)) ]], 6, // another case for nested expressions [[ str (Color black) ]], str(Color.black), // bug with nested for + new + linebreak + for (phew) [[ (for y in ll 1 { new Pair 1 2 for x in null {} }); 0 ]], 0, // param declares a variable [[ param x; x ]], null, // same with type [[ param x : int; x ]], null, // return with assignment [[ return x <- 1 ]], 1, // for pair [[ for pair a b in ll (pair 1 2) (pair 3 4) { plus a b } ]], ll(3, 7), // for key, value (map) [[ for a, b in litorderedmap 1 2 3 4 { plus a b } ]], ll(3, 7), // for index, value (list) [[ for index i, a in ll "a" "b" { concatStrings i a } ]], ll("0a", "1b"), // automatically convert int to long for method call [[ longPlus 1 2 ]], 3L, // same for constructors [[ new Ratio 1 ]], Ratio(1), // call a function from another function [[ def f1 { 1 } def f2 { plus (f1) 2 } f2 ]], 3, // return out of for loop [[ for x in iota 2 { return x } ]], 1, // continue loop [[ for x in iota 2 { if eq x 1 { continue } return "ok" } ]], "ok", // break loop (TODO) /*[[ for x in iota 2 { if eq x 1 { break } return "what" } "ok" ]], "ok",*/ // new without new [[ Pair (neg 1) (neg 2) ]], pair(-1, -2), // variable doesn't come into scope until it's initialized [[ neg <- neg 1; neg ]], -1, // repeat x { ... } construct [[ x <- 0 repeat plus 1 2 { x <- plus x 1 } x ]], 3, // update outer variable from function [[ x <- 0 def incIt { outer x <- plus x 1 } incIt x ]], 1, // return directly followed by } [[ if true { return } ]], null, // return from lambda (exits only the lambda, just like in Java) [[ repF 2 (IF0 -> { return 1; null }) ]], ll(1, 1), // "temp" (like in JavaX) [[ list <- new ArrayList { temp tempAdd list 5 assertContains list 5 } list ]], ll(), // "temp" test 2 (assure it handles exceptions properly) [[ list <- new ArrayList pcallF (Runnable -> { temp tempAdd list 5 fail }) list ]], ll(), // "temp" combined with variable declaration [[ list <- new ArrayList { temp x <- tempAdd list 5 assertInstanceOf x AutoCloseable assertContains list 5 } list ]], ll(), // reference to functionContainer class itself [[ main ]], mc(), // referencing class with full package name [[ java.util.Arrays sort (newFloatArray 1) ]], null, [[ new java.util.ArrayList ]], ll(), // call method on literal [[ "" length ]], 0, // L or List to make a new list [[ new List ]], ll(), [[ new L ]], ll(), // Map to make a new HashMap [[ new Map ]], new Map, // new with a variable containing a class [[ c <- ArrayList; new c ]], ll(), [[ new Var<S>, getClass ]], Var.class, shortName(InheritanceDispatchTest) + " f (new " + shortName(ClassC) + ")", "b", [[ sleepSeconds 0 sleepSeconds 0 ]], null, // variable declaration with type [[ a : S <- "s"; a ]], "s", // try/finally [[ a <- 0 try { try { a <- plus a 1 } finally { a <- plus a 2 } try { fail } finally { a <- plus a 3 } } catch e {} a ]], 6, // try is also an expression [[ list { try { fail } catch {} try { fail } catch { "oops" } try { "a" } catch {} } ]], ll(null, "oops", "a"), // function definition with explicit parameter type [[ def f x: int { plus x 1 } f 5 ]], 6, // same with parameter in parentheses [[ def f (x: int) { plus x 1 } f 5 ]], 6, // param with nested parameterized type [[ param x : L<Pair<Int, Int>> ]], null, // +id shortcut [[ x <- 5; ll +x ]], ll(x := 5), // unclosed multi-line string "splitAtSpace [[a b", ll("a", "b"), "splitAtSpace [=[c d", ll("c", "d"), // list { } [[ list { plus 1 2 minus 8 4 } ]], ll(3, 4), // same in one line with semicolons [[ list { plus 1 2; minus 8 4 } ]], ll(3, 4), // parsing bug [[ for x in ll 1 { x } ]], ll(1), // will return [[ data <- new Var will return data get data set 1 ]], 1, // recursive script-defined function [[ def myFactorial n { if n lessThan 2 { 1 } else { myFactorial (n minus 1), mul n } } myFactorial 5 ]], 120, // for each closes the iterator if it's closeable [[ iterator <- new TestCloseableIterableIterator closed <- new Flag iterator onClosing closed for i in iterator {} closed isUp ]], true, // same test with exception in loop [[ iterator <- new TestCloseableIterableIterator closed <- new Flag iterator onClosing closed try { for i in iterator { fail } } catch e {} closed isUp ]], true, // make sure my own classes are found before Java SDK classes [[ new Timestamp 1000, unixDate ]], 1000L, // TO FIX // TODO [[ max 1000L 100 ]], 1000L, // couldn't fix this quickly (have ~ binding stronger) //[[ map <- litmap "a" 1 "b" 2; plus map~a map~b ]], 3, // question mark syntax for calling methods on null targets [[ a <- null; a intValue? ]], null, [[ a <- 5L; a intValue? ]], 5, // long constants without L [[ 1234567812345678 ]], 1234567812345678, // Duration is a standard import [[ d: Duration <- daysToDuration 1 ]], daysToDuration(1), // first called with subtype array [[ fileName < first < toTypedArray File < ll < newFile "hello" ]], "hello", [[ o <- new O assertFalse < Thread holdsLock o synchronized o { assertTrue < Thread holdsLock o } assertFalse < Thread holdsLock o null ]], null, // , +abc syntax (= , abc abc) [[ a <- "1"; b <- "2"; new Pair, +a, +b ]], pair("1", "2"), // call default method jreplace([[ new DefaultMethodTest, x ]], "DefaultMethodTest", shortName(DefaultMethodTest)), "y", // add simple tests here ); // get reference to current var context with _context new GazelleV_LeftArrowScriptParser parser; enableScaffolding(parser); parser.allowTheWorld(); new FlexibleVarContext ctx; assertSame(ctx, parser.parse("_context").get(ctx)); test_leftArrowScriptParseErrors(); test_leftArrowScript_lambdas(); test_leftArrowScript_binaryOperators(); test_leftArrowScriptCompileErrors(); // get static field in functionContainer parser = new GazelleV_LeftArrowScriptParser; parser.allowTheWorld(Tester, mc()); assertEqualsVerbose("ok", parser.parse("myStaticField")!); assertEqualsVerbose("ko", parser.parse("reversed myStaticField")!); assertEqualsVerbose(2, parser.parse("myStaticField length")!); test_leftArrowScript_classDefs(); test_leftArrowScript_forIterator(); var exception = leftArrowVerbose([[ try { throw new RuntimeException } catch e { e } ]]); assertEqualsVerbose(exception.getClass(), RuntimeException.class); // trying to get non-existant field/method on object assertFailVerbose(-> leftArrowVerbose([[ "" lengthX ]])); // make sure fields local to function are not visible outside assertFailVerbose(-> leftArrowParse([[ def x { y <- 1 } y ]])); test_leftArrowScript_comma(); test_leftArrowScript_antiComma(); // test priority of class resolution parser = new GazelleV_LeftArrowScriptParser; enableScaffolding(parser); parser.allowTheWorld(Sub1.class, Sub2.class); assertEqualsVerbose(1, parser.parse("X value")!); parser = new GazelleV_LeftArrowScriptParser; enableScaffolding(parser); parser.allowTheWorld(Sub2.class, Sub1.class); assertEqualsVerbose(2, parser.parse("X value")!); test_leftArrowScript_returnValueNotNeededOptimization(); // test addClassAlias parser = new GazelleV_LeftArrowScriptParser; parser.allowTheWorld(); parser.addClassAlias("Paar", "Pair"); assertEqualsVerbose(pair(1, 2), parser.parse("new Paar 1 2")!); // test that params are stored in parsed script var script = leftArrowParseVerbose("param x : int"); assertEqualsVerbose(1, l(script.params)); assertEqualsVerbose("x", firstKey(script.params)); assertEqualsVerbose(int.class, firstValue(script.params).javaClass()); // +id shortcut doesn't work with a space assertFailVerbose(-> leftArrowParseVerbose([[ x <- 5; ll + x ]])); test_leftArrowScript_magicSwitch(); test_leftArrowScript_tilde(); test_leftArrowScript_then(); assertInstanceOf IF0(leftArrowVerbose([[ abcd <- IF0 {}; abcd ]])); // Test def ... returning a FunctionDef O o = leftArrow([[def bla { null } ]]); assertEqualsVerbose("bla", ((GazelleV_LeftArrowScript.FunctionDef) o).name); o = leftArrow([[a <- def bla { null }; a]]); assertEqualsVerbose("bla", ((GazelleV_LeftArrowScript.FunctionDef) o).name); test_leftArrowScript_pcall(); test_leftArrowScript_ifdef(); //test_leftArrowScript_var(); // assignment to static field leftArrowVerbose(replace( [[ StaticField theField <- "hello" ]], "StaticField", className(StaticField))); assertEqualsVerbose("hello", StaticField.theField); // get static field from subclass assertEqualsVerbose("hello", leftArrowVerbose(replace( [[ StaticFieldSubClass theField ]], "StaticFieldSubClass", className(StaticFieldSubClass)))); // get static field from implemented interface assertEqualsVerbose("yo", leftArrowVerbose(replace( [[ StaticFieldInterfaceImplementor daField ]], "StaticFieldInterfaceImplementor", className(StaticFieldInterfaceImplementor)))); test_leftArrowScript_scriptError(); test_leftArrowScript_objectScope(); test_leftArrowScript_doWhile(); // Test that string literals are interned assertSame(intern("abc"), leftArrowVerbose([["abc"]]); // add tests here print("All left-arrow script tests OK!"); }
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, ekrmjmnbrukm, elmgxqgtpvxh, gjtlkbvenryc, mowyntqkapby, mqqgnosmbjvj, wnsclhtenguj
No comments. add comment
Snippet ID: | #1033988 |
Snippet name: | test_leftArrowScript - all tests for Left-Arrow-Script |
Eternal ID of this version: | #1033988/197 |
Text MD5: | a31c9913452d4453a70764307f870612 |
Transpilation MD5: | 69e7041e9984cddce702cc07b6b79729 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2024-07-14 10:59:06 |
Source code size: | 15823 bytes / 626 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 788 / 2975 |
Version history: | 196 change(s) |
Referenced in: | [show references] |