Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

623
LINES

< > BotCompany Repo | #1033988 // test_leftArrowScript - all tests for Left-Arrow-Script

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (37645L) is out of date.

!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();
  
  // 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/196
Text MD5: 7b0fa11abea8b354f43ef0429d1ceff1
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-09-22 17:59:12
Source code size: 15716 bytes / 623 lines
Pitched / IR pitched: No / No
Views / Downloads: 667 / 2806
Version history: 195 change(s)
Referenced in: #1006654 - Standard functions list 2 (LIVE, continuation of #761)
#1033976 - GazelleV_LeftArrowScriptParser
#1034238 - test_leftArrowScript_forEach
#1034264 - test_leftArrowScript_pinging
#1034291 - GazelleV_LeftArrowScriptParser backup before type inference
#1034324 - test_compiledLeftArrowScript - test left-arrow script compiled to byte code. only a few cases so far (OK)