Transpiled version (37645L) is out of date.
1 | !include once #1034831 // Gazelle 22 Function Include for Testing |
2 | |
3 | set flag PingV3. |
4 | |
5 | scope test_leftArrowScript |
6 | |
7 | sclass #ClassA {} |
8 | sclass #ClassB extends ClassA {} |
9 | sclass #ClassC extends ClassB {} |
10 | |
11 | sclass #StaticField { |
12 | sS theField; |
13 | } |
14 | |
15 | sclass #StaticFieldSubClass extends StaticField { |
16 | } |
17 | |
18 | interface #StaticFieldInInterface { |
19 | sS daField = "yo"; |
20 | } |
21 | |
22 | sclass #StaticFieldInterfaceImplementor is StaticFieldInInterface { |
23 | } |
24 | |
25 | sclass #InheritanceDispatchTest { |
26 | static S f(ClassA a) { ret "a"; } |
27 | static S f(ClassB a) { ret "b"; } |
28 | } |
29 | |
30 | sclass #Tester { |
31 | O value = "123"; |
32 | sO myStaticField = "ok"; |
33 | } |
34 | |
35 | sclass #Sub1 { |
36 | sclass X { static int value = 1; } |
37 | } |
38 | |
39 | sclass #Sub2 { |
40 | sclass X { static int value = 2; } |
41 | } |
42 | |
43 | interface #DefaultMethodInterface { |
44 | default S x() { ret "y"; } |
45 | } |
46 | |
47 | sclass #DefaultMethodTest is DefaultMethodInterface { |
48 | } |
49 | |
50 | svoid test_leftArrowScript() { |
51 | test_leftArrowScript_pinging(); |
52 | |
53 | embedded S countLoop(int n) { |
54 | ret [[ i <- 0; while lessThan i ]] + n + [[ { i <- plus i 1 }; i ]]; |
55 | } |
56 | |
57 | S ifThenElseScript = [[ |
58 | if lessThan a b { joinWithSpace "It's" "less" } |
59 | else if greaterThan a b { joinWithSpace "It's" "greater" } |
60 | else { joinWithSpace "They're" "equal" } |
61 | ]]; |
62 | |
63 | testFunctionValues(script -> leftArrowVerbose((S) script), |
64 | // int primitive |
65 | |
66 | [[ 5 ]], 5, |
67 | [[ -5 ]], -5, |
68 | |
69 | // function definition & call |
70 | [[ |
71 | def double x { |
72 | Math multiplyExact x 2 |
73 | } |
74 | |
75 | double 10 |
76 | ]], 20, |
77 | |
78 | // new object with constructor arguments |
79 | [[ new Pair "hello" "world" ]], pair("hello", "world"), |
80 | |
81 | // double constant |
82 | [[ str 1.5e2 ]], "150.0", |
83 | |
84 | // float constant |
85 | [[ 1.5e2f ]], 150f, |
86 | [[ 1.5e2F ]], 150f, |
87 | |
88 | // long constant |
89 | [[ 0L ]], 0L, |
90 | |
91 | // hex constant |
92 | [[ 0x80 ]], 0x80, |
93 | |
94 | // binary constant |
95 | [[ 0B101 ]], 0B101, |
96 | |
97 | // character constant |
98 | [[ '\t' ]], '\t', |
99 | |
100 | // [not implemented, too complicated] |
101 | // last = result of last statement |
102 | // [[ plus 1 2; Math addExact 5 last ]], 8, |
103 | |
104 | // get static field |
105 | [[ Color black ]], Color.black, |
106 | |
107 | // get instance field, |
108 | [[ tester <- new test_leftArrowScript_Tester; tester value ]], "123", |
109 | |
110 | // while loop |
111 | countLoop(5), 5, |
112 | |
113 | // if statement |
114 | [[ if lessThan 0 1 { "ok" } ]], "ok", |
115 | [[ if lessThan 1 0 { "ok" } ]], null, |
116 | |
117 | // for each |
118 | [[ l <- ll 2 3 |
119 | sum <- 0 |
120 | for number in l { sum <- plus sum number } |
121 | sum |
122 | ]], 5, |
123 | |
124 | // for each is also map() |
125 | [[ for i in ll 2 3 { plus i 1 } |
126 | ]], ll(3, 4), |
127 | |
128 | // for each as nested expression |
129 | [[ joinWithSpace (for i in ll 2 3 { i }) ]], "2 3", |
130 | |
131 | // for i to n |
132 | [[ for i to 2 { i } |
133 | ]], ll(0, 1), |
134 | |
135 | // for with byte array |
136 | [[ for b in litbytearray (toByte 5) (toByte 7) { b } ]], ll((byte) 5, (byte) 7), |
137 | |
138 | // for with double array |
139 | [[ for b in litdoublearray 5.0 7.0 { b } ]], ll(5.0, 7.0), |
140 | |
141 | // for with char array |
142 | [[ for c in chars "AB" { c } ]], ll('A', 'B'), |
143 | |
144 | // for with typed variable |
145 | [[ for c: char in chars "AB" { c } ]], ll('A', 'B'), |
146 | |
147 | // some bug |
148 | [[ |
149 | img <- newImage 10 10 |
150 | r <- randomRect img 10 10 |
151 | ]], rect(0, 0, 10, 10), |
152 | |
153 | // another bug |
154 | [[ |
155 | a <- 1 |
156 | b <- a |
157 | a |
158 | ]], 1, |
159 | |
160 | // null bug |
161 | [[ |
162 | a <- 1 |
163 | a <- null |
164 | a |
165 | ]], null, |
166 | |
167 | // return at the end |
168 | [[ |
169 | return 17 |
170 | ]], 17, |
171 | |
172 | // two returns (first wins) |
173 | [[ |
174 | return 13 |
175 | return 22 |
176 | ]], 13, |
177 | |
178 | // same with "ret" for "return" |
179 | [[ |
180 | ret 13 |
181 | ret 22 |
182 | ]], 13, |
183 | |
184 | // conditional return |
185 | |
186 | [[ |
187 | if true { return "so true" } |
188 | return "oops" |
189 | ]], "so true", |
190 | |
191 | [[ |
192 | if false { return "not true" } |
193 | return "but this" |
194 | ]], "but this", |
195 | |
196 | // if-then-else |
197 | |
198 | [[ a <- 1; b <- 2; ]] + ifThenElseScript, "It's less", |
199 | [[ a <- 6; b <- 2; ]] + ifThenElseScript, "It's greater", |
200 | [[ a <- 5.0; b <- 5.0; ]] + ifThenElseScript, "They're equal", |
201 | |
202 | // if-then-else with "then" keyword but without curly braces |
203 | [[ if true then "ok" else "not ok" ]], "ok", |
204 | [[ if false then "ok" else "not ok" ]], "not ok", |
205 | |
206 | // nested expressions |
207 | |
208 | [[ plus (plus 1 2) 4 ]], 7, |
209 | [[ (plus 5 6) toString ]], "11", |
210 | |
211 | // nested expressions over 2 lines (it's ok to split an expression |
212 | // over multiple lines if you at least parenthesis is still open) |
213 | |
214 | [[ (plus 1 |
215 | (plus 2 3)) ]], 6, |
216 | |
217 | // another case for nested expressions |
218 | [[ str (Color black) ]], str(Color.black), |
219 | |
220 | // bug with nested for + new + linebreak + for (phew) |
221 | [[ (for y in ll 1 { |
222 | new Pair 1 2 |
223 | for x in null {} |
224 | }); 0 ]], 0, |
225 | |
226 | // param declares a variable |
227 | [[ param x; x ]], null, |
228 | |
229 | // same with type |
230 | [[ param x : int; x ]], null, |
231 | |
232 | // return with assignment |
233 | [[ return x <- 1 ]], 1, |
234 | |
235 | // for pair |
236 | [[ for pair a b in ll (pair 1 2) (pair 3 4) { |
237 | plus a b |
238 | } ]], ll(3, 7), |
239 | |
240 | // for key, value (map) |
241 | [[ for a, b in litorderedmap 1 2 3 4 { |
242 | plus a b |
243 | } ]], ll(3, 7), |
244 | |
245 | // for index, value (list) |
246 | [[ for index i, a in ll "a" "b" { |
247 | concatStrings i a |
248 | } ]], ll("0a", "1b"), |
249 | |
250 | // automatically convert int to long for method call |
251 | [[ longPlus 1 2 ]], 3L, |
252 | |
253 | // same for constructors |
254 | [[ new Ratio 1 ]], Ratio(1), |
255 | |
256 | // call a function from another function |
257 | [[ def f1 { 1 } |
258 | def f2 { plus (f1) 2 } |
259 | f2 ]], 3, |
260 | |
261 | // return out of for loop |
262 | [[ for x in iota 2 { return x } ]], 1, |
263 | |
264 | // continue loop |
265 | [[ for x in iota 2 { |
266 | if eq x 1 { continue } |
267 | return "ok" |
268 | } ]], "ok", |
269 | |
270 | // break loop (TODO) |
271 | /*[[ for x in iota 2 { |
272 | if eq x 1 { break } |
273 | return "what" |
274 | } |
275 | "ok" |
276 | ]], "ok",*/ |
277 | |
278 | // new without new |
279 | [[ Pair (neg 1) (neg 2) ]], pair(-1, -2), |
280 | |
281 | // variable doesn't come into scope until it's initialized |
282 | [[ neg <- neg 1; neg ]], -1, |
283 | |
284 | // repeat x { ... } construct |
285 | [[ x <- 0 |
286 | repeat plus 1 2 { x <- plus x 1 } |
287 | x ]], 3, |
288 | |
289 | // update outer variable from function |
290 | [[ x <- 0 |
291 | def incIt { outer x <- plus x 1 } |
292 | incIt |
293 | x ]], 1, |
294 | |
295 | // return directly followed by } |
296 | [[ if true { return } ]], null, |
297 | |
298 | // return from lambda (exits only the lambda, just like in Java) |
299 | [[ repF 2 (IF0 -> { return 1; null }) ]], ll(1, 1), |
300 | |
301 | // "temp" (like in JavaX) |
302 | [[ list <- new ArrayList |
303 | { |
304 | temp tempAdd list 5 |
305 | assertContains list 5 |
306 | } |
307 | list |
308 | ]], ll(), |
309 | |
310 | // "temp" test 2 (assure it handles exceptions properly) |
311 | [[ list <- new ArrayList |
312 | pcallF (Runnable -> { |
313 | temp tempAdd list 5 |
314 | fail |
315 | }) |
316 | list |
317 | ]], ll(), |
318 | |
319 | // "temp" combined with variable declaration |
320 | [[ list <- new ArrayList |
321 | { |
322 | temp x <- tempAdd list 5 |
323 | assertInstanceOf x AutoCloseable |
324 | assertContains list 5 |
325 | } |
326 | list |
327 | ]], ll(), |
328 | |
329 | // reference to functionContainer class itself |
330 | [[ main ]], mc(), |
331 | |
332 | // referencing class with full package name |
333 | [[ java.util.Arrays sort (newFloatArray 1) ]], null, |
334 | |
335 | [[ new java.util.ArrayList ]], ll(), |
336 | |
337 | // call method on literal |
338 | [[ "" length ]], 0, |
339 | |
340 | // L or List to make a new list |
341 | [[ new List ]], ll(), |
342 | [[ new L ]], ll(), |
343 | |
344 | // Map to make a new HashMap |
345 | [[ new Map ]], new Map, |
346 | |
347 | // new with a variable containing a class |
348 | [[ c <- ArrayList; new c ]], ll(), |
349 | |
350 | [[ new Var<S>, getClass ]], Var.class, |
351 | |
352 | shortName(InheritanceDispatchTest) + " f (new " + shortName(ClassC) + ")", "b", |
353 | |
354 | [[ |
355 | sleepSeconds 0 |
356 | sleepSeconds 0 |
357 | ]], null, |
358 | |
359 | // variable declaration with type |
360 | |
361 | [[ a : S <- "s"; a ]], "s", |
362 | |
363 | // try/finally |
364 | |
365 | [[ |
366 | a <- 0 |
367 | try { |
368 | try { a <- plus a 1 } finally { a <- plus a 2 } |
369 | try { fail } finally { a <- plus a 3 } |
370 | } catch e {} |
371 | a |
372 | ]], 6, |
373 | |
374 | // try is also an expression |
375 | |
376 | [[ |
377 | list { |
378 | try { fail } catch {} |
379 | try { fail } catch { "oops" } |
380 | try { "a" } catch {} |
381 | } |
382 | ]], ll(null, "oops", "a"), |
383 | |
384 | // function definition with explicit parameter type |
385 | [[ |
386 | def f x: int { |
387 | plus x 1 |
388 | } |
389 | f 5 |
390 | ]], 6, |
391 | |
392 | // same with parameter in parentheses |
393 | [[ |
394 | def f (x: int) { |
395 | plus x 1 |
396 | } |
397 | f 5 |
398 | ]], 6, |
399 | |
400 | // param with nested parameterized type |
401 | [[ |
402 | param x : L<Pair<Int, Int>> |
403 | ]], null, |
404 | |
405 | // +id shortcut |
406 | [[ x <- 5; ll +x ]], ll(x := 5), |
407 | |
408 | // unclosed multi-line string |
409 | "splitAtSpace [[a b", ll("a", "b"), |
410 | "splitAtSpace [=[c d", ll("c", "d"), |
411 | |
412 | // list { } |
413 | [[ list { |
414 | plus 1 2 |
415 | minus 8 4 |
416 | } ]], ll(3, 4), |
417 | |
418 | // same in one line with semicolons |
419 | [[ list { plus 1 2; minus 8 4 } ]], ll(3, 4), |
420 | |
421 | // parsing bug |
422 | [[ for x in ll |
423 | 1 { x } ]], ll(1), |
424 | |
425 | // will return |
426 | [[ data <- new Var |
427 | will return data get |
428 | data set 1 ]], 1, |
429 | |
430 | // recursive script-defined function |
431 | [[ def myFactorial n { |
432 | if n lessThan 2 |
433 | { 1 } |
434 | else { myFactorial (n minus 1), mul n } |
435 | } |
436 | myFactorial 5 |
437 | ]], 120, |
438 | |
439 | // for each closes the iterator if it's closeable |
440 | [[ |
441 | iterator <- new TestCloseableIterableIterator |
442 | closed <- new Flag |
443 | iterator onClosing closed |
444 | for i in iterator {} |
445 | closed isUp |
446 | ]], true, |
447 | |
448 | // same test with exception in loop |
449 | [[ |
450 | iterator <- new TestCloseableIterableIterator |
451 | closed <- new Flag |
452 | iterator onClosing closed |
453 | try { |
454 | for i in iterator { fail } |
455 | } catch e {} |
456 | closed isUp |
457 | ]], true, |
458 | |
459 | // make sure my own classes are found before Java SDK classes |
460 | [[ new Timestamp 1000, unixDate ]], |
461 | 1000L, |
462 | |
463 | // TO FIX |
464 | // TODO [[ max 1000L 100 ]], 1000L, |
465 | |
466 | // couldn't fix this quickly (have ~ binding stronger) |
467 | //[[ map <- litmap "a" 1 "b" 2; plus map~a map~b ]], 3, |
468 | |
469 | // question mark syntax for calling methods on null targets |
470 | [[ a <- null; a intValue? ]], null, |
471 | [[ a <- 5L; a intValue? ]], 5, |
472 | |
473 | // long constants without L |
474 | [[ 1234567812345678 ]], 1234567812345678, |
475 | |
476 | // Duration is a standard import |
477 | [[ d: Duration <- daysToDuration 1 ]], |
478 | daysToDuration(1), |
479 | |
480 | // first called with subtype array |
481 | [[ fileName < first < toTypedArray File < ll < newFile "hello" ]], |
482 | "hello", |
483 | |
484 | [[ |
485 | o <- new O |
486 | assertFalse < Thread holdsLock o |
487 | synchronized o { |
488 | assertTrue < Thread holdsLock o |
489 | } |
490 | assertFalse < Thread holdsLock o |
491 | null |
492 | ]], null, |
493 | |
494 | // , +abc syntax (= , abc abc) |
495 | [[ a <- "1"; b <- "2"; new Pair, +a, +b ]], |
496 | pair("1", "2"), |
497 | |
498 | // call default method |
499 | jreplace([[ new DefaultMethodTest, x ]], |
500 | "DefaultMethodTest", shortName(DefaultMethodTest)), |
501 | "y", |
502 | |
503 | // add simple tests here |
504 | ); |
505 | |
506 | // get reference to current var context with _context |
507 | |
508 | new GazelleV_LeftArrowScriptParser parser; |
509 | enableScaffolding(parser); |
510 | parser.allowTheWorld(); |
511 | new FlexibleVarContext ctx; |
512 | assertSame(ctx, parser.parse("_context").get(ctx)); |
513 | |
514 | test_leftArrowScriptParseErrors(); |
515 | |
516 | test_leftArrowScript_lambdas(); |
517 | |
518 | test_leftArrowScript_binaryOperators(); |
519 | |
520 | test_leftArrowScriptCompileErrors(); |
521 | |
522 | // get static field in functionContainer |
523 | |
524 | parser = new GazelleV_LeftArrowScriptParser; |
525 | parser.allowTheWorld(Tester, mc()); |
526 | assertEqualsVerbose("ok", parser.parse("myStaticField")!); |
527 | assertEqualsVerbose("ko", parser.parse("reversed myStaticField")!); |
528 | assertEqualsVerbose(2, parser.parse("myStaticField length")!); |
529 | |
530 | test_leftArrowScript_classDefs(); |
531 | |
532 | test_leftArrowScript_forIterator(); |
533 | |
534 | var exception = leftArrowVerbose([[ |
535 | try { throw new RuntimeException } catch e { e } |
536 | ]]); |
537 | assertEqualsVerbose(exception.getClass(), RuntimeException.class); |
538 | |
539 | // trying to get non-existant field/method on object |
540 | assertFailVerbose(-> leftArrowVerbose([[ "" lengthX ]])); |
541 | |
542 | // make sure fields local to function are not visible outside |
543 | assertFailVerbose(-> leftArrowParse([[ def x { y <- 1 } y ]])); |
544 | |
545 | test_leftArrowScript_comma(); |
546 | test_leftArrowScript_antiComma(); |
547 | |
548 | // test priority of class resolution |
549 | parser = new GazelleV_LeftArrowScriptParser; |
550 | enableScaffolding(parser); |
551 | parser.allowTheWorld(Sub1.class, Sub2.class); |
552 | assertEqualsVerbose(1, parser.parse("X value")!); |
553 | parser = new GazelleV_LeftArrowScriptParser; |
554 | enableScaffolding(parser); |
555 | parser.allowTheWorld(Sub2.class, Sub1.class); |
556 | assertEqualsVerbose(2, parser.parse("X value")!); |
557 | |
558 | test_leftArrowScript_returnValueNotNeededOptimization(); |
559 | |
560 | // test addClassAlias |
561 | |
562 | parser = new GazelleV_LeftArrowScriptParser; |
563 | parser.allowTheWorld(); |
564 | parser.addClassAlias("Paar", "Pair"); |
565 | assertEqualsVerbose(pair(1, 2), parser.parse("new Paar 1 2")!); |
566 | |
567 | // test that params are stored in parsed script |
568 | |
569 | var script = leftArrowParseVerbose("param x : int"); |
570 | assertEqualsVerbose(1, l(script.params)); |
571 | assertEqualsVerbose("x", firstKey(script.params)); |
572 | assertEqualsVerbose(int.class, firstValue(script.params).javaClass()); |
573 | |
574 | // +id shortcut doesn't work with a space |
575 | assertFailVerbose(-> leftArrowParseVerbose([[ x <- 5; ll + x ]])); |
576 | |
577 | test_leftArrowScript_magicSwitch(); |
578 | |
579 | test_leftArrowScript_tilde(); |
580 | |
581 | test_leftArrowScript_then(); |
582 | |
583 | assertInstanceOf IF0(leftArrowVerbose([[ abcd <- IF0 {}; abcd ]])); |
584 | |
585 | // Test def ... returning a FunctionDef |
586 | O o = leftArrow([[def bla { null } ]]); |
587 | assertEqualsVerbose("bla", ((GazelleV_LeftArrowScript.FunctionDef) o).name); |
588 | |
589 | o = leftArrow([[a <- def bla { null }; a]]); |
590 | assertEqualsVerbose("bla", ((GazelleV_LeftArrowScript.FunctionDef) o).name); |
591 | |
592 | test_leftArrowScript_pcall(); |
593 | |
594 | test_leftArrowScript_ifdef(); |
595 | |
596 | //test_leftArrowScript_var(); |
597 | |
598 | // assignment to static field |
599 | leftArrowVerbose(replace( |
600 | [[ StaticField theField <- "hello" |
601 | ]], "StaticField", className(StaticField))); |
602 | assertEqualsVerbose("hello", StaticField.theField); |
603 | |
604 | // get static field from subclass |
605 | assertEqualsVerbose("hello", leftArrowVerbose(replace( |
606 | [[ StaticFieldSubClass theField ]], |
607 | "StaticFieldSubClass", className(StaticFieldSubClass)))); |
608 | |
609 | // get static field from implemented interface |
610 | assertEqualsVerbose("yo", leftArrowVerbose(replace( |
611 | [[ StaticFieldInterfaceImplementor daField ]], |
612 | "StaticFieldInterfaceImplementor", className(StaticFieldInterfaceImplementor)))); |
613 | |
614 | test_leftArrowScript_scriptError(); |
615 | |
616 | test_leftArrowScript_objectScope(); |
617 | |
618 | test_leftArrowScript_doWhile(); |
619 | |
620 | // add tests here |
621 | |
622 | print("All left-arrow script tests OK!"); |
623 | } |
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: | 675 / 2816 |
Version history: | 195 change(s) |
Referenced in: | [show references] |