aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/inputs/syntax.yue4
-rw-r--r--spec/inputs/test/advanced_macro_spec.yue36
-rw-r--r--spec/inputs/test/close_attribute_spec.yue5
-rw-r--r--spec/inputs/test/const_attribute_spec.yue20
-rw-r--r--spec/inputs/test/do_statement_spec.yue22
-rw-r--r--spec/inputs/test/functions_advanced_spec.yue22
-rw-r--r--spec/inputs/test/implicit_object_spec.yue4
-rw-r--r--spec/inputs/test/in_expression_spec.yue17
-rw-r--r--spec/inputs/test/multiline_args_spec.yue52
-rw-r--r--spec/inputs/test/named_varargs_spec.yue9
-rw-r--r--spec/inputs/test/operator_advanced_spec.yue6
-rw-r--r--spec/inputs/test/param_destructure_spec.yue20
-rw-r--r--spec/inputs/test/reverse_index_spec.yue4
-rw-r--r--spec/inputs/test/slicing_spec.yue22
-rw-r--r--spec/inputs/test/stub_spec.yue3
-rw-r--r--spec/inputs/test/table_append_spec.yue8
-rw-r--r--spec/inputs/test/table_comprehension_spec.yue2
-rw-r--r--spec/inputs/test/tables_advanced_spec.yue13
-rw-r--r--spec/inputs/test/varargs_assignment_spec.yue2
-rw-r--r--spec/inputs/test/whitespace_spec.yue17
-rw-r--r--spec/inputs/test/with_statement_spec.yue22
-rw-r--r--spec/inputs/test/yaml_string_spec.yue44
-rw-r--r--spec/inputs/unicode/syntax.yue4
-rw-r--r--spec/outputs/test/advanced_macro_spec.lua92
-rw-r--r--spec/outputs/test/close_attribute_spec.lua226
-rw-r--r--spec/outputs/test/const_attribute_spec.lua131
-rw-r--r--spec/outputs/test/do_statement_spec.lua238
-rw-r--r--spec/outputs/test/functions_advanced_spec.lua259
-rw-r--r--spec/outputs/test/implicit_object_spec.lua243
-rw-r--r--spec/outputs/test/in_expression_spec.lua180
-rw-r--r--spec/outputs/test/multiline_args_spec.lua219
-rw-r--r--spec/outputs/test/named_varargs_spec.lua16
-rw-r--r--spec/outputs/test/operator_advanced_spec.lua210
-rw-r--r--spec/outputs/test/param_destructure_spec.lua369
-rw-r--r--spec/outputs/test/reverse_index_spec.lua4
-rw-r--r--spec/outputs/test/slicing_spec.lua324
-rw-r--r--spec/outputs/test/stub_spec.lua148
-rw-r--r--spec/outputs/test/table_append_spec.lua15
-rw-r--r--spec/outputs/test/table_comprehension_spec.lua297
-rw-r--r--spec/outputs/test/tables_advanced_spec.lua260
-rw-r--r--spec/outputs/test/varargs_assignment_spec.lua6
-rw-r--r--spec/outputs/test/whitespace_spec.lua159
-rw-r--r--spec/outputs/test/with_statement_spec.lua279
-rw-r--r--spec/outputs/test/yaml_string_spec.lua42
-rw-r--r--spec/outputs/unicode/string.lua14
-rw-r--r--spec/outputs/unicode/syntax.lua2
46 files changed, 3760 insertions, 331 deletions
diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue
index a63f629..ccf8b01 100644
--- a/spec/inputs/syntax.yue
+++ b/spec/inputs/syntax.yue
@@ -84,11 +84,11 @@ _ = here(we)"go"[12123]
84 84
85split"abc xyz 123"\map"#"\printAll! 85split"abc xyz 123"\map"#"\printAll!
86 86
87_ = f""[a] 87_ = f("")[a]
88_ = f""\b! 88_ = f""\b!
89_ = f"".c! 89_ = f"".c!
90 90
91f ""[a] 91f ("")[a]
92f ""\b! 92f ""\b!
93f "".c! 93f "".c!
94 94
diff --git a/spec/inputs/test/advanced_macro_spec.yue b/spec/inputs/test/advanced_macro_spec.yue
index 3d7b10a..d88807f 100644
--- a/spec/inputs/test/advanced_macro_spec.yue
+++ b/spec/inputs/test/advanced_macro_spec.yue
@@ -15,7 +15,10 @@ describe "advanced macro", ->
15 assert.same result, "hello world" 15 assert.same result, "hello world"
16 16
17 it "should work with conditional compilation", -> 17 it "should work with conditional compilation", ->
18 global debugMode = true
19 $ -> global debugMode = true
18 macro config = (debugging) -> 20 macro config = (debugging) ->
21 assert debugMode?
19 global debugMode = debugging == "true" 22 global debugMode = debugging == "true"
20 "" 23 ""
21 24
@@ -23,7 +26,7 @@ describe "advanced macro", ->
23 assert.is_true debugMode 26 assert.is_true debugMode
24 27
25 $config false 28 $config false
26 assert.is_false debugMode 29 assert.is_true debugMode
27 30
28 it "should support macro generating conditional code", -> 31 it "should support macro generating conditional code", ->
29 macro asserts = (cond) -> 32 macro asserts = (cond) ->
@@ -39,20 +42,24 @@ describe "advanced macro", ->
39 :code 42 :code
40 type: "lua" 43 type: "lua"
41 } 44 }
42 45 macro_test_var = 42
43 $luaCode "local macro_test_var = 42" 46 $luaCode [[local macro_test_var = 99]]
44 assert.same macro_test_var, 42 47 assert.same macro_test_var, 42
45 48
46 it "should support multi-line raw lua", -> 49 it "should support multi-line raw lua", ->
47 macro lua = (code) -> { 50 macro lua = (code) -> {
48 :code 51 :code
49 type: "lua" 52 type: "text"
53 locals: ["multiline_var1",]
50 } 54 }
51 55
56 multiline_var = "test"
52 $lua[==[ 57 $lua[==[
53 local multiline_var = "test" 58 multiline_var = "test work"
59 local multiline_var1 = "test1"
54 ]==] 60 ]==]
55 assert.same multiline_var, "test" 61 assert.same multiline_var, "test work"
62 assert.same multiline_var1, "test1"
56 63
57 it "should export macro from module", -> 64 it "should export macro from module", ->
58 -- This test demonstrates macro export syntax 65 -- This test demonstrates macro export syntax
@@ -116,10 +123,14 @@ describe "advanced macro", ->
116 assert.same result, "Red" 123 assert.same result, "Red"
117 124
118 it "should handle complex macro logic", -> 125 it "should handle complex macro logic", ->
119 macro smart_print = (items) -> 126 my_print = (...) -> ...
120 "print(#{table.concat [item for item in *items], ', ')})" 127 macro smart_print = (...items) ->
128 "my_print(#{table.concat [item for item in *items], ', '})"
121 129
122 $smart_print {"hello", "world", 123} 130 a, b, c = $smart_print "hello", "world", 123
131 assert.same a, "hello"
132 assert.same b, "world"
133 assert.same c, 123
123 134
124 it "should work with table manipulation", -> 135 it "should work with table manipulation", ->
125 macro create_table = (...) -> 136 macro create_table = (...) ->
@@ -130,12 +141,7 @@ describe "advanced macro", ->
130 assert.same result, {"1", "2", "3"} 141 assert.same result, {"1", "2", "3"}
131 142
132 it "should support string concatenation in macro", -> 143 it "should support string concatenation in macro", ->
133 macro concat = (...) -> 144 macro concat = (...) -> table.concat {...}, " .. "
134 args = {...}
135 res = {}
136 for arg in *args
137 table.insert res, tostring arg
138 "'" .. table.concat(res, " .. ") .. "'"
139 145
140 result = $concat "hello", "world" 146 result = $concat "hello", "world"
141 assert.same result, "helloworld" 147 assert.same result, "helloworld"
diff --git a/spec/inputs/test/close_attribute_spec.yue b/spec/inputs/test/close_attribute_spec.yue
index 2354df7..ebda27e 100644
--- a/spec/inputs/test/close_attribute_spec.yue
+++ b/spec/inputs/test/close_attribute_spec.yue
@@ -43,7 +43,7 @@ describe "close attribute", ->
43 closed = false 43 closed = false
44 obj = 44 obj =
45 value: 10 45 value: 10
46 close_method: <close>: => 46 <close>: =>
47 closed = true 47 closed = true
48 48
49 do 49 do
@@ -82,9 +82,8 @@ describe "close attribute", ->
82 82
83 it "should work with table destructuring", -> 83 it "should work with table destructuring", ->
84 closed = false 84 closed = false
85 tb = {close: <close>: -> closed = true}
86 do 85 do
87 {:close} = tb 86 close tb = {<close>: -> closed = true}
88 assert.is_true closed 87 assert.is_true closed
89 88
90 it "should handle close with return value", -> 89 it "should handle close with return value", ->
diff --git a/spec/inputs/test/const_attribute_spec.yue b/spec/inputs/test/const_attribute_spec.yue
index e3cc638..24ced21 100644
--- a/spec/inputs/test/const_attribute_spec.yue
+++ b/spec/inputs/test/const_attribute_spec.yue
@@ -13,7 +13,7 @@ describe "const attribute", ->
13 assert.same name, "test" 13 assert.same name, "test"
14 14
15 it "should support const with destructuring", -> 15 it "should support const with destructuring", ->
16 tb = {a: 1, b: 2, c: 3, d: 4} 16 tb = {a: 1, b: 2, 3, 4}
17 const {:a, :b, c, d} = tb 17 const {:a, :b, c, d} = tb
18 assert.same a, 1 18 assert.same a, 1
19 assert.same b, 2 19 assert.same b, 2
@@ -46,7 +46,7 @@ describe "const attribute", ->
46 46
47 it "should handle const functions", -> 47 it "should handle const functions", ->
48 const add = (a, b) -> a + b 48 const add = (a, b) -> a + b
49 assert.same add 5, 10, 15 49 assert.same add(5, 10), 15
50 50
51 it "should work with const tables", -> 51 it "should work with const tables", ->
52 const config = { 52 const config = {
@@ -74,28 +74,12 @@ describe "const attribute", ->
74 const calculated = 10 + 20 74 const calculated = 10 + 20
75 assert.same calculated, 30 75 assert.same calculated, 30
76 76
77 it "should support const with prefixed return", ->
78 getDefault: const "default" ->
79 return nil
80
81 result = getDefault!
82 assert.same result, nil
83
84 it "should work in table comprehension", -> 77 it "should work in table comprehension", ->
85 const multiplier = 2 78 const multiplier = 2
86 items = [1, 2, 3] 79 items = [1, 2, 3]
87 result = [item * multiplier for item in *items] 80 result = [item * multiplier for item in *items]
88 assert.same result, {2, 4, 6} 81 assert.same result, {2, 4, 6}
89 82
90 it "should handle const with fat arrow", ->
91 obj =
92 value: 100
93 getValue: const =>
94 @value
95
96 result = obj\getValue!
97 assert.same result, 100
98
99 it "should work with complex expressions", -> 83 it "should work with complex expressions", ->
100 const complex = { 84 const complex = {
101 data: [1, 2, 3] 85 data: [1, 2, 3]
diff --git a/spec/inputs/test/do_statement_spec.yue b/spec/inputs/test/do_statement_spec.yue
index 0adad20..2611cba 100644
--- a/spec/inputs/test/do_statement_spec.yue
+++ b/spec/inputs/test/do_statement_spec.yue
@@ -62,7 +62,7 @@ describe "do statement", ->
62 it "should support variable shadowing", -> 62 it "should support variable shadowing", ->
63 x = "outer" 63 x = "outer"
64 result = do 64 result = do
65 x = "inner" 65 local x = "inner"
66 x 66 x
67 assert.same result, "inner" 67 assert.same result, "inner"
68 assert.same x, "outer" 68 assert.same x, "outer"
@@ -74,7 +74,7 @@ describe "do statement", ->
74 74
75 result = do 75 result = do
76 with obj 76 with obj
77 \double! 77 break \double!
78 assert.same result, 20 78 assert.same result, 20
79 79
80 it "should handle comprehensions in do block", -> 80 it "should handle comprehensions in do block", ->
@@ -84,13 +84,13 @@ describe "do statement", ->
84 assert.same result, {2, 4, 6, 8, 10} 84 assert.same result, {2, 4, 6, 8, 10}
85 85
86 it "should work with try-catch", -> 86 it "should work with try-catch", ->
87 result = do 87 success, result = try
88 success = try 88 error "test error"
89 error "test error" 89 false
90 false 90 catch err
91 catch err 91 true
92 true 92 assert.is_false success
93 assert.is_true success 93 assert.is_true result
94 94
95 it "should support return statement", -> 95 it "should support return statement", ->
96 fn = -> 96 fn = ->
@@ -125,13 +125,15 @@ describe "do statement", ->
125 it "should support implicit return", -> 125 it "should support implicit return", ->
126 result = do 126 result = do
127 value = 42 127 value = 42
128 value
128 assert.same result, 42 129 assert.same result, 42
129 130
130 it "should handle empty do block", -> 131 it "should handle empty do block", ->
131 result = do 132 result = do nil
132 assert.same result, nil 133 assert.same result, nil
133 134
134 it "should work with backcalls", -> 135 it "should work with backcalls", ->
136 map = (f, items) -> [f item for item in *items]
135 result = do 137 result = do
136 items = [1, 2, 3] 138 items = [1, 2, 3]
137 (x) <- map _, items 139 (x) <- map _, items
diff --git a/spec/inputs/test/functions_advanced_spec.yue b/spec/inputs/test/functions_advanced_spec.yue
index d0e0cf5..32f0718 100644
--- a/spec/inputs/test/functions_advanced_spec.yue
+++ b/spec/inputs/test/functions_advanced_spec.yue
@@ -19,32 +19,32 @@ describe "advanced functions", ->
19 x + y 19 x + y
20 20
21 assert.same fn!, 1200 21 assert.same fn!, 1200
22 assert.same fn(50), 1150 22 assert.same fn(50), 1100
23 23
24 it "should work with multi-line arguments", -> 24 it "should work with multi-line arguments", ->
25 my_func = (a, b, c, d, e, f) -> a + b + c + d + e + f 25 my_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
26 result = my_func 5, 4, 3, 26 result = my_func 5, 4, 3,
27 8, 9, 10 27 8, 9, 10
28 assert.same result, 39 28 assert.same result, 39
29 29
30 it "should support nested function calls", -> 30 it "should support nested function calls", ->
31 another_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
32 my_func = (a, b, c, d, e, f, g) -> a + b + c + d + e + f + g
33
31 result = my_func 5, 6, 7, 34 result = my_func 5, 6, 7,
32 6, another_func 6, 7, 8, 35 6, another_func 6, 7, 8,
33 9, 1, 2, 36 9, 1, 2,
34 5, 4 37 5, 4
35 38
36 another_func = (a, b, c, d, e, f) -> a + b + c + d + e + f 39 assert.same result, 66
37 my_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
38
39 assert.same result, 52
40 40
41 it "should handle implicit return", -> 41 it "should handle implicit return", ->
42 sum = (x, y) -> x + y 42 sum = (x, y) -> x + y
43 assert.same sum 10, 20, 30 43 assert.same sum(10, 20), 30
44 44
45 it "should work with explicit return", -> 45 it "should work with explicit return", ->
46 difference = (x, y) -> return x - y 46 difference = (x, y) -> return x - y
47 assert.same difference 20, 10, 10 47 assert.same difference(20, 10), 10
48 48
49 it "should support multiple return values", -> 49 it "should support multiple return values", ->
50 mystery = (x, y) -> x + y, x - y 50 mystery = (x, y) -> x + y, x - y
@@ -85,7 +85,7 @@ describe "advanced functions", ->
85 assert.same fn(1, 2, 3), 3 85 assert.same fn(1, 2, 3), 3
86 86
87 it "should support prefixed return", -> 87 it "should support prefixed return", ->
88 findValue: "not found" -> 88 findValue = (): "not found" ->
89 items = [1, 2, 3] 89 items = [1, 2, 3]
90 for item in *items 90 for item in *items
91 if item == 5 91 if item == 5
@@ -155,4 +155,4 @@ describe "advanced functions", ->
155 -> 0 155 -> 0
156 156
157 add = get_operation "add" 157 add = get_operation "add"
158 assert.same add 5, 3, 8 158 assert.same add(5, 3), 8
diff --git a/spec/inputs/test/implicit_object_spec.yue b/spec/inputs/test/implicit_object_spec.yue
index cea926e..a0bd331 100644
--- a/spec/inputs/test/implicit_object_spec.yue
+++ b/spec/inputs/test/implicit_object_spec.yue
@@ -142,9 +142,9 @@ describe "implicit object", ->
142 it "should handle empty implicit object", -> 142 it "should handle empty implicit object", ->
143 tb = 143 tb =
144 items: 144 items:
145 - 145 - nil
146 146
147 assert.same tb.items, {nil} 147 assert.same tb, {items: [nil,]}
148 148
149 it "should work in function arguments", -> 149 it "should work in function arguments", ->
150 fn = (items) -> #items 150 fn = (items) -> #items
diff --git a/spec/inputs/test/in_expression_spec.yue b/spec/inputs/test/in_expression_spec.yue
index c1f4099..d9e3aec 100644
--- a/spec/inputs/test/in_expression_spec.yue
+++ b/spec/inputs/test/in_expression_spec.yue
@@ -9,11 +9,11 @@ describe "in expression", ->
9 assert.is_true "b" in chars 9 assert.is_true "b" in chars
10 assert.is_false "z" in chars 10 assert.is_false "z" in chars
11 11
12 it "should check keys in table", -> 12 it "should check in table literal", ->
13 obj = {x: 1, y: 2, z: 3} 13 x = 1; y = 2; z = 3; w = 4
14 assert.is_true "x" in obj 14 assert.is_true x in [x, y, z]
15 assert.is_true "y" in obj 15 assert.is_true y in [x, y, z]
16 assert.is_false "w" in obj 16 assert.is_false w in [x, y, z]
17 17
18 it "should work with mixed types", -> 18 it "should work with mixed types", ->
19 items = {1, "two", true, nil} 19 items = {1, "two", true, nil}
@@ -41,7 +41,8 @@ describe "in expression", ->
41 assert.is_false not (2 in items) 41 assert.is_false not (2 in items)
42 42
43 it "should work with nested tables", -> 43 it "should work with nested tables", ->
44 nested = {{1, 2}, {3, 4}, {5, 6}} 44 eq = (other) => @[1] == other[1] and @[2] == other[2]
45 nested = {{1, 2, :<eq>}, {3, 4, :<eq>}, {5, 6, :<eq>}}
45 assert.is_true {1, 2} in nested 46 assert.is_true {1, 2} in nested
46 assert.is_false {1, 3} in nested 47 assert.is_false {1, 3} in nested
47 48
@@ -60,7 +61,7 @@ describe "in expression", ->
60 it "should support table as value", -> 61 it "should support table as value", ->
61 key1 = {a: 1} 62 key1 = {a: 1}
62 key2 = {b: 2} 63 key2 = {b: 2}
63 tb = {[key1]: "first", [key2]: "second"} 64 tb = [key1, key2]
64 65
65 -- Note: this tests table reference equality 66 -- Note: this tests table reference equality
66 assert.is_true key1 in tb 67 assert.is_true key1 in tb
@@ -77,7 +78,7 @@ describe "in expression", ->
77 assert.is_true 1 in items 78 assert.is_true 1 in items
78 79
79 it "should work with string keys", -> 80 it "should work with string keys", ->
80 obj = {name: "test", value: 42} 81 obj = ["name", "value"]
81 assert.is_true "name" in obj 82 assert.is_true "name" in obj
82 assert.is_true "value" in obj 83 assert.is_true "value" in obj
83 assert.is_false "missing" in obj 84 assert.is_false "missing" in obj
diff --git a/spec/inputs/test/multiline_args_spec.yue b/spec/inputs/test/multiline_args_spec.yue
index bbb06f9..add9d2b 100644
--- a/spec/inputs/test/multiline_args_spec.yue
+++ b/spec/inputs/test/multiline_args_spec.yue
@@ -1,6 +1,6 @@
1describe "multiline arguments", -> 1describe "multiline arguments", ->
2 it "should split arguments across lines", -> 2 it "should split arguments across lines", ->
3 sum = (a, b, c) -> a + b + c 3 sum = (a, b, c, d, e, f) -> a + b + c + d + e + f
4 result = sum 5, 4, 3, 4 result = sum 5, 4, 3,
5 8, 9, 10 5 8, 9, 10
6 assert.same result, 39 6 assert.same result, 39
@@ -42,46 +42,46 @@ describe "multiline arguments", ->
42 assert.same result, {1, 2, 3, 4, 9, 8, 9, 10} 42 assert.same result, {1, 2, 3, 4, 9, 8, 9, 10}
43 43
44 it "should handle deeply nested indentation", -> 44 it "should handle deeply nested indentation", ->
45 y = [ fn 1, 2, 3, 45 -- Create function first
46 4, 5,
47 5, 6, 7
48 ]
49
50 -- Create the function first
51 fn = (a, b, c, d, e, f, g) -> a + b + c + d + e + f + g 46 fn = (a, b, c, d, e, f, g) -> a + b + c + d + e + f + g
47 y = { fn 1, 2, 3,
48 4,
49 5, 6, 7
50 }
52 51
53 result = y[1] 52 result = y[1]
54 assert.same result, 22 53 assert.same result, 28
55 54
56 it "should work with conditional statements", -> 55 it "should work with conditional statements", ->
57 fn = (a, b, c, d, e) -> a + b + c + d + e 56 fn = (a, b, c, d, e, f) -> a + b + c + d + e + f
58 57 result1 = fn 1, 2, 3,
59 result = if fn 1, 2, 3, 58 4, 5,
60 "hello", 59 6
61 "world" 60
62 "yes" 61 result = if result1 > 20
63 else 62 "yes"
64 "no" 63 else
64 "no"
65 assert.same result, "yes" 65 assert.same result, "yes"
66 66
67 it "should support function expressions", -> 67 it "should support function expressions", ->
68 double = (x) -> x * 2 68 doublePlus = (x, y) -> x * 2 + y
69 result = double 5, 69 result = doublePlus 5,
70 10 70 10
71 assert.same result, 20 71 assert.same result, 20
72 72
73 it "should handle chained function calls", -> 73 it "should handle chained function calls", ->
74 add = (a, b) -> a + b 74 add = (a, b, c, d) -> a + b + c + d
75 multiply = (a, b) -> a * b 75 multiply = (a, b, c, d) -> a * b * c * d
76 76
77 result = multiply add 1, 2, 77 result = multiply 1, 2,
78 add 3, 4 78 3, 4
79 assert.same result, 21 79 assert.same result, 24
80 80
81 it "should work with method calls", -> 81 it "should work with method calls", ->
82 obj = 82 obj =
83 value: 10 83 value: 10
84 add: (a, b) => @value + a + b 84 add: (a, b, c) => @value + a + b + c
85 85
86 result = obj\add 5, 10, 86 result = obj\add 5, 10,
87 15 87 15
@@ -100,7 +100,7 @@ describe "multiline arguments", ->
100 assert.same result, 45 100 assert.same result, 45
101 101
102 it "should work with return statement", -> 102 it "should work with return statement", ->
103 fn = (a, b) -> a + b 103 fn = (a, b, c) -> a + b + c
104 get_value = -> 104 get_value = ->
105 return fn 10, 20, 105 return fn 10, 20,
106 30 106 30
diff --git a/spec/inputs/test/named_varargs_spec.yue b/spec/inputs/test/named_varargs_spec.yue
index a5ab2b1..29869b5 100644
--- a/spec/inputs/test/named_varargs_spec.yue
+++ b/spec/inputs/test/named_varargs_spec.yue
@@ -97,12 +97,11 @@ describe "named varargs", ->
97 assert.same result, {"a", "b", "c"} 97 assert.same result, {"a", "b", "c"}
98 98
99 it "should support passing named varargs to another function", -> 99 it "should support passing named varargs to another function", ->
100 inner = (...) ->
101 {...}
100 outer = (...t) -> 102 outer = (...t) ->
101 inner (table.unpack t) 103 inner t[1], t[2], t[3]
102 104
103 inner = (a, b, c) ->
104 {a, b, c}
105
106 result = outer 1, 2, 3 105 result = outer 1, 2, 3
107 assert.same result, {1, 2, 3} 106 assert.same result, {1, 2, 3}
108 107
diff --git a/spec/inputs/test/operator_advanced_spec.yue b/spec/inputs/test/operator_advanced_spec.yue
index 8127fd4..8f88d17 100644
--- a/spec/inputs/test/operator_advanced_spec.yue
+++ b/spec/inputs/test/operator_advanced_spec.yue
@@ -75,7 +75,7 @@ describe "advanced operators", ->
75 75
76 it "should handle compound bitwise xor", -> 76 it "should handle compound bitwise xor", ->
77 x = 12 -- 1100 in binary 77 x = 12 -- 1100 in binary
78 x ~= 10 -- 1010 in binary 78 x = x~10 -- 1010 in binary
79 assert.same x, 6 -- 0110 in binary 79 assert.same x, 6 -- 0110 in binary
80 80
81 it "should work with compound left shift", -> 81 it "should work with compound left shift", ->
@@ -121,10 +121,10 @@ describe "advanced operators", ->
121 it "should work with :: for method chaining", -> 121 it "should work with :: for method chaining", ->
122 obj = 122 obj =
123 value: 10 123 value: 10
124 add: (n) => @value += n 124 add: (n): @ => @value += n
125 get: => @value 125 get: => @value
126 126
127 result = obj::add 5::get! 127 result = obj::add(5)::get!
128 assert.same result, 15 128 assert.same result, 15
129 129
130 it "should handle complex expressions with precedence", -> 130 it "should handle complex expressions with precedence", ->
diff --git a/spec/inputs/test/param_destructure_spec.yue b/spec/inputs/test/param_destructure_spec.yue
index 4659031..5b9ef83 100644
--- a/spec/inputs/test/param_destructure_spec.yue
+++ b/spec/inputs/test/param_destructure_spec.yue
@@ -38,10 +38,10 @@ describe "parameter destructuring", ->
38 assert.same result, {1, 2, 3} 38 assert.same result, {1, 2, 3}
39 39
40 it "should support mixed array and object", -> 40 it "should support mixed array and object", ->
41 f = ([first], {key: :value}) -> 41 f = ([first,], {key: :value}) ->
42 {first, value} 42 {first, value}
43 43
44 result = f [1], {key: "test"} 44 result = f [1,], {key: value: "test"}
45 assert.same result, {1, "test"} 45 assert.same result, {1, "test"}
46 46
47 it "should work with fat arrow", -> 47 it "should work with fat arrow", ->
@@ -54,7 +54,7 @@ describe "parameter destructuring", ->
54 assert.same result, 130 54 assert.same result, 130
55 55
56 it "should handle missing keys", -> 56 it "should handle missing keys", ->
57 f = (:a, :b = "default", :c = "missing") -> 57 f = ({:a, :b = "default", :c = "missing"}) ->
58 {a, b, c} 58 {a, b, c}
59 59
60 result = f a: 1 60 result = f a: 1
@@ -89,10 +89,10 @@ describe "parameter destructuring", ->
89 assert.same result, {1, {2, 3, 4}} 89 assert.same result, {1, {2, 3, 4}}
90 90
91 it "should support spreading", -> 91 it "should support spreading", ->
92 f = (...rest, :last) -> 92 f = ({...rest, :last}) ->
93 {rest, last} 93 {rest, last}
94 94
95 result = f 1, 2, 3, {last: "final"} 95 result = f {1, 2, 3, last: "final"}
96 assert.same result, {{1, 2, 3}, 'final'} 96 assert.same result, {{1, 2, 3}, 'final'}
97 97
98 it "should work with table comprehensions", -> 98 it "should work with table comprehensions", ->
@@ -103,8 +103,8 @@ describe "parameter destructuring", ->
103 assert.same result, {2, 4, 6} 103 assert.same result, {2, 4, 6}
104 104
105 it "should handle nil arguments", -> 105 it "should handle nil arguments", ->
106 f = (:a = "nil_a", :b = "nil_b") -> 106 f = ({:a = "nil_a", :b = "nil_b"}) ->
107 {a, b} 107 {a, b}
108 108
109 result = f nil, nil 109 result = f {}
110 assert.same result, {'nil_a', 'nil_b'} 110 assert.same result, {"nil_a", "nil_b"}
diff --git a/spec/inputs/test/reverse_index_spec.yue b/spec/inputs/test/reverse_index_spec.yue
index be67261..3c17d09 100644
--- a/spec/inputs/test/reverse_index_spec.yue
+++ b/spec/inputs/test/reverse_index_spec.yue
@@ -42,10 +42,6 @@ describe "reverse index", ->
42 last = data.items.nested[#] 42 last = data.items.nested[#]
43 assert.same last, 3 43 assert.same last, 3
44 44
45 it "should work with string", ->
46 s = "hello"
47 assert.same s[#], "o"
48
49 it "should handle negative offsets", -> 45 it "should handle negative offsets", ->
50 tab = [1, 2, 3, 4, 5] 46 tab = [1, 2, 3, 4, 5]
51 assert.same tab[#-3], 2 47 assert.same tab[#-3], 2
diff --git a/spec/inputs/test/slicing_spec.yue b/spec/inputs/test/slicing_spec.yue
index b0a686b..2f5b1a7 100644
--- a/spec/inputs/test/slicing_spec.yue
+++ b/spec/inputs/test/slicing_spec.yue
@@ -1,27 +1,27 @@
1describe "slicing", -> 1describe "slicing", ->
2 it "should slice array with basic syntax", -> 2 it "should slice array with basic syntax", ->
3 items = [1, 2, 3, 4, 5] 3 items = [1, 2, 3, 4, 5]
4 result = items[1..3] 4 result = items[1, 3]
5 assert.same result, {1, 2, 3} 5 assert.same result, {1, 2, 3}
6 6
7 it "should slice from beginning", -> 7 it "should slice from beginning", ->
8 items = [1, 2, 3, 4, 5] 8 items = [1, 2, 3, 4, 5]
9 result = items[1..#items] 9 result = items[1, #items]
10 assert.same result, {1, 2, 3, 4, 5} 10 assert.same result, {1, 2, 3, 4, 5}
11 11
12 it "should slice to end", -> 12 it "should slice to end", ->
13 items = [1, 2, 3, 4, 5] 13 items = [1, 2, 3, 4, 5]
14 result = items[3..5] 14 result = items[3, 5]
15 assert.same result, {3, 4, 5} 15 assert.same result, {3, 4, 5}
16 16
17 it "should handle negative indices", -> 17 it "should handle negative indices", ->
18 items = [1, 2, 3, 4, 5] 18 items = [1, 2, 3, 4, 5]
19 result = items[#items-2..#items] 19 result = items[-3, -1]
20 assert.same result, {3, 4, 5} 20 assert.same result, {3, 4, 5}
21 21
22 it "should slice single element", -> 22 it "should slice single element", ->
23 items = [1, 2, 3, 4, 5] 23 items = [1, 2, 3, 4, 5]
24 result = items[2..2] 24 result = items[2, 2]
25 assert.same result, {2} 25 assert.same result, {2}
26 26
27 it "should work with strings", -> 27 it "should work with strings", ->
@@ -31,18 +31,18 @@ describe "slicing", ->
31 31
32 it "should handle out of bounds", -> 32 it "should handle out of bounds", ->
33 items = [1, 2, 3] 33 items = [1, 2, 3]
34 result = items[1..10] 34 result = items[1, 10]
35 assert.same result, {1, 2, 3} 35 assert.same result, {1, 2, 3}
36 36
37 it "should create new table", -> 37 it "should create new table", ->
38 original = [1, 2, 3, 4, 5] 38 original = [1, 2, 3, 4, 5]
39 sliced = original[2..4] 39 sliced = original[2, 4]
40 sliced[1] = 99 40 sliced[1] = 99
41 assert.same original[2], 2 -- original unchanged 41 assert.same original[2], 2 -- original unchanged
42 42
43 it "should work with nested arrays", -> 43 it "should work with nested arrays", ->
44 nested = [[1, 2], [3, 4], [5, 6]] 44 nested = [ [1, 2], [3, 4], [5, 6]]
45 result = nested[1..2] 45 result = nested[1, 2]
46 assert.same result, {{1, 2}, {3, 4}} 46 assert.same result, {{1, 2}, {3, 4}}
47 47
48 it "should slice with step simulation", -> 48 it "should slice with step simulation", ->
@@ -52,8 +52,8 @@ describe "slicing", ->
52 52
53 it "should handle empty slice range", -> 53 it "should handle empty slice range", ->
54 items = [1, 2, 3, 4, 5] 54 items = [1, 2, 3, 4, 5]
55 result = items[6..10] 55 result = items[6, 10]
56 assert.same result, nil 56 assert.same result, {}
57 57
58 it "should work with reverse indexing", -> 58 it "should work with reverse indexing", ->
59 items = [1, 2, 3, 4, 5] 59 items = [1, 2, 3, 4, 5]
diff --git a/spec/inputs/test/stub_spec.yue b/spec/inputs/test/stub_spec.yue
index 99345c7..835610b 100644
--- a/spec/inputs/test/stub_spec.yue
+++ b/spec/inputs/test/stub_spec.yue
@@ -1,3 +1,6 @@
1-- Define stub_fn as a helper function that returns an empty function
2stub_fn = -> ->
3
1describe "function stub", -> 4describe "function stub", ->
2 it "should create empty function", -> 5 it "should create empty function", ->
3 stub_fn! 6 stub_fn!
diff --git a/spec/inputs/test/table_append_spec.yue b/spec/inputs/test/table_append_spec.yue
index ab3d6d2..51c7873 100644
--- a/spec/inputs/test/table_append_spec.yue
+++ b/spec/inputs/test/table_append_spec.yue
@@ -30,12 +30,12 @@ describe "table append", ->
30 tab[] = ...tb2 30 tab[] = ...tb2
31 assert.same tab, {1, 2} 31 assert.same tab, {1, 2}
32 32
33 it "should append nil values", -> 33 it "should not append nil values", ->
34 tab = [] 34 tab = []
35 tab[] = nil 35 tab[] = nil
36 tab[] = "value" 36 tab[] = "value"
37 assert.same tab[1], nil 37 assert.same tab[2], nil
38 assert.same tab[2], "value" 38 assert.same tab[1], "value"
39 39
40 it "should work in loop", -> 40 it "should work in loop", ->
41 tab = [] 41 tab = []
@@ -73,5 +73,5 @@ describe "table append", ->
73 it "should append function results", -> 73 it "should append function results", ->
74 fn = -> 1, 2, 3 74 fn = -> 1, 2, 3
75 tab = [] 75 tab = []
76 tab[] = fn! 76 tab[] = ...[fn!,]
77 assert.same tab, {1, 2, 3} 77 assert.same tab, {1, 2, 3}
diff --git a/spec/inputs/test/table_comprehension_spec.yue b/spec/inputs/test/table_comprehension_spec.yue
index f4d7cdb..caebdef 100644
--- a/spec/inputs/test/table_comprehension_spec.yue
+++ b/spec/inputs/test/table_comprehension_spec.yue
@@ -112,7 +112,7 @@ describe "table comprehension", ->
112 assert.same result.e, nil 112 assert.same result.e, nil
113 113
114 it "should work with custom iterator", -> 114 it "should work with custom iterator", ->
115 custom_iter = -> -> 115 custom_iter = ->
116 state = 0 116 state = 0
117 -> 117 ->
118 state += 1 118 state += 1
diff --git a/spec/inputs/test/tables_advanced_spec.yue b/spec/inputs/test/tables_advanced_spec.yue
index c8cc7d5..82f4d4e 100644
--- a/spec/inputs/test/tables_advanced_spec.yue
+++ b/spec/inputs/test/tables_advanced_spec.yue
@@ -35,8 +35,9 @@ describe "advanced tables", ->
35 assert.same tb[4], 4 35 assert.same tb[4], 4
36 36
37 it "should work with single line table literals", -> 37 it "should work with single line table literals", ->
38 my_function dance: "Tango", partner: "none" 38 tb = dance: "Tango", partner: "none"
39 assert.is_true true 39 assert.same tb.dance, "Tango"
40 assert.same tb.partner, "none"
40 41
41 it "should support nested tables", -> 42 it "should support nested tables", ->
42 tb = 43 tb =
@@ -90,10 +91,9 @@ describe "advanced tables", ->
90 assert.same merge.y, 1 91 assert.same merge.y, 1
91 92
92 it "should handle mixed spread", -> 93 it "should handle mixed spread", ->
93 parts = { 94 parts =
94 * "shoulders" 95 * "shoulders"
95 * "knees" 96 * "knees"
96 }
97 lyrics = 97 lyrics =
98 * "head" 98 * "head"
99 * ...parts 99 * ...parts
@@ -108,7 +108,7 @@ describe "advanced tables", ->
108 108
109 a = <>: mt, value: 1 109 a = <>: mt, value: 1
110 b = value: 2 110 b = value: 2
111 b.<>, mt 111 b.<> = mt
112 c = a + b 112 c = a + b
113 assert.same c.value, 3 113 assert.same c.value, 3
114 114
@@ -121,11 +121,12 @@ describe "advanced tables", ->
121 tb = { 121 tb = {
122 item: "test" 122 item: "test"
123 new: -> "created" 123 new: -> "created"
124 close: -> "closed" 124 <close>: -> "closed"
125 } 125 }
126 {:item, :new, :<close>} = tb 126 {:item, :new, :<close>} = tb
127 assert.same item, "test" 127 assert.same item, "test"
128 assert.same new!, "created" 128 assert.same new!, "created"
129 assert.same close!, "closed"
129 130
130 it "should work with string keys directly", -> 131 it "should work with string keys directly", ->
131 t = { 132 t = {
diff --git a/spec/inputs/test/varargs_assignment_spec.yue b/spec/inputs/test/varargs_assignment_spec.yue
index 1c3b627..dfd606b 100644
--- a/spec/inputs/test/varargs_assignment_spec.yue
+++ b/spec/inputs/test/varargs_assignment_spec.yue
@@ -46,7 +46,7 @@ describe "varargs assignment", ->
46 assert.same select(3, ...), 2 46 assert.same select(3, ...), 2
47 47
48 it "should work with table.unpack", -> 48 it "should work with table.unpack", ->
49 tb = {a: 1, b: 2, c: 3} 49 tb = [1, 2, 3]
50 fn = -> table.unpack tb 50 fn = -> table.unpack tb
51 ... = fn! 51 ... = fn!
52 count = select '#', ... 52 count = select '#', ...
diff --git a/spec/inputs/test/whitespace_spec.yue b/spec/inputs/test/whitespace_spec.yue
index baf3fd5..43b7644 100644
--- a/spec/inputs/test/whitespace_spec.yue
+++ b/spec/inputs/test/whitespace_spec.yue
@@ -8,13 +8,14 @@ describe "whitespace", ->
8 assert.same z, 30 8 assert.same z, 30
9 9
10 it "should work with semicolon in function", -> 10 it "should work with semicolon in function", ->
11 fn = -> a = 1; b = 2; a + b 11 fn = ->
12 a = 1; b = 2; a + b
12 assert.same fn!, 3 13 assert.same fn!, 3
13 14
14 it "should support multiline chaining", -> 15 it "should support multiline chaining", ->
15 obj = 16 obj =
16 value: 10 17 value: 10
17 add: (n) => @value += n 18 add: (n): @ => @value += n
18 get: => @value 19 get: => @value
19 20
20 result = obj 21 result = obj
@@ -26,7 +27,7 @@ describe "whitespace", ->
26 it "should handle multiline method calls", -> 27 it "should handle multiline method calls", ->
27 str = " hello " 28 str = " hello "
28 result = str 29 result = str
29 \trim! 30 \match "^%s*(.-)%s*$"
30 \upper! 31 \upper!
31 assert.same result, "HELLO" 32 assert.same result, "HELLO"
32 33
@@ -53,7 +54,7 @@ describe "whitespace", ->
53 54
54 it "should work with pipe in chaining", -> 55 it "should work with pipe in chaining", ->
55 result = [1, 2, 3] 56 result = [1, 2, 3]
56 |> [x * 2 for x in *] 57 |> ((tb) -> [x * 2 for x in *tb])
57 |> table.concat 58 |> table.concat
58 assert.same result, "246" 59 assert.same result, "246"
59 60
@@ -68,7 +69,7 @@ describe "whitespace", ->
68 fn = -> 69 fn = ->
69 if true 70 if true
70 result = 10 71 result = 10
71 result 72 result
72 73
73 assert.same fn!, 10 74 assert.same fn!, 10
74 75
@@ -91,7 +92,7 @@ describe "whitespace", ->
91 92
92 it "should work in multiline function call", -> 93 it "should work in multiline function call", ->
93 sum = (a, b) -> a + b 94 sum = (a, b) -> a + b
94 result = sum 5, 10, 95 result = sum 5, sum 10,
95 sum 3, 7 96 sum 3, 7
96 assert.same result, 25 97 assert.same result, 25
97 98
@@ -105,13 +106,15 @@ describe "whitespace", ->
105 assert.same doubled, 10 106 assert.same doubled, 10
106 107
107 it "should handle complex chaining", -> 108 it "should handle complex chaining", ->
108 result = "hello" 109 result = ("hello")
109 \upper! 110 \upper!
110 \sub 1, 3 111 \sub 1, 3
111 \lower! 112 \lower!
112 assert.same result, "hel" 113 assert.same result, "hel"
113 114
114 it "should work with backcalls and whitespace", -> 115 it "should work with backcalls and whitespace", ->
116 readAsync = (file, callback) -> callback "data"
117 process = (data) -> true if data
115 results = do 118 results = do
116 data <- readAsync "data.txt" 119 data <- readAsync "data.txt"
117 process data 120 process data
diff --git a/spec/inputs/test/with_statement_spec.yue b/spec/inputs/test/with_statement_spec.yue
index c2f9b3b..71ac215 100644
--- a/spec/inputs/test/with_statement_spec.yue
+++ b/spec/inputs/test/with_statement_spec.yue
@@ -27,7 +27,7 @@ describe "with statement", ->
27 obj = {x: 1} 27 obj = {x: 1}
28 with obj 28 with obj
29 .x = 10 29 .x = 10
30 with .nested = {y: 2} 30 with .nested := {y: 2}
31 .y = 20 31 .y = 20
32 assert.same obj.x, 10 32 assert.same obj.x, 10
33 assert.same obj.nested.y, 20 33 assert.same obj.nested.y, 20
@@ -35,7 +35,7 @@ describe "with statement", ->
35 it "should work in expressions", -> 35 it "should work in expressions", ->
36 obj = {value: 5} 36 obj = {value: 5}
37 result = with obj 37 result = with obj
38 .value * 2 38 break .value * 2
39 assert.same result, 10 39 assert.same result, 10
40 40
41 it "should support multiple statements", -> 41 it "should support multiple statements", ->
@@ -76,13 +76,13 @@ describe "with statement", ->
76 it "should support with in assignment", -> 76 it "should support with in assignment", ->
77 obj = {x: 5, y: 10} 77 obj = {x: 5, y: 10}
78 result = with obj 78 result = with obj
79 .x + .y 79 break .x + .y
80 assert.same result, 15 80 assert.same result, 15
81 81
82 it "should work with string methods", -> 82 it "should work with string methods", ->
83 s = "hello" 83 s = "hello"
84 result = with s 84 result = with s
85 \upper! 85 break \upper!
86 assert.same result, "HELLO" 86 assert.same result, "HELLO"
87 87
88 it "should handle metatable access", -> 88 it "should handle metatable access", ->
@@ -98,7 +98,7 @@ describe "with statement", ->
98 fn = -> 98 fn = ->
99 obj = {x: 10} 99 obj = {x: 10}
100 with obj 100 with obj
101 .x * 2 101 break .x * 2
102 102
103 result = fn! 103 result = fn!
104 assert.same result, 20 104 assert.same result, 20
@@ -107,19 +107,19 @@ describe "with statement", ->
107 get_value = -> 107 get_value = ->
108 obj = {value: 42} 108 obj = {value: 42}
109 with obj 109 with obj
110 .value 110 break .value
111 111
112 assert.same get_value!, 42 112 assert.same get_value!, 42
113 113
114 it "should work with existential operator", -> 114 it "should work with existential operator", ->
115 obj = {value: 10} 115 obj = {value: 10}
116 result = with obj 116 result = with obj
117 .value ? 0 117 break .value ?? 0
118 assert.same result, 10 118 assert.same result, 10
119 119
120 it "should handle nil object safely", -> 120 it "should handle nil object safely", ->
121 result = with nil 121 result = with? nil
122 .value 122 break .value
123 assert.same result, nil 123 assert.same result, nil
124 124
125 it "should work with method chaining", -> 125 it "should work with method chaining", ->
@@ -131,7 +131,7 @@ describe "with statement", ->
131 result = with obj 131 result = with obj
132 \add 10 132 \add 10
133 \add 5 133 \add 5
134 \get! 134 break \get!
135 assert.same result, 20 135 assert.same result, 20
136 136
137 it "should support nested property access", -> 137 it "should support nested property access", ->
@@ -141,5 +141,5 @@ describe "with statement", ->
141 level3: "deep" 141 level3: "deep"
142 142
143 result = with obj 143 result = with obj
144 .level1.level2.level3 144 break .level1.level2.level3
145 assert.same result, "deep" 145 assert.same result, "deep"
diff --git a/spec/inputs/test/yaml_string_spec.yue b/spec/inputs/test/yaml_string_spec.yue
index 1296340..0a7d61b 100644
--- a/spec/inputs/test/yaml_string_spec.yue
+++ b/spec/inputs/test/yaml_string_spec.yue
@@ -3,15 +3,15 @@ describe "yaml string", ->
3 s = | 3 s = |
4 hello 4 hello
5 world 5 world
6 assert.is_true s\match "hello" 6 assert.is_true s\match("hello")?
7 assert.is_true s\match "world" 7 assert.is_true s\match("world")?
8 8
9 it "should preserve indentation", -> 9 it "should preserve indentation", ->
10 s = | 10 s = |
11 key1: value1 11 key1: value1
12 key2: value2 12 key2: value2
13 assert.is_true s\match "key1" 13 assert.is_true s\match("key1")?
14 assert.is_true s\match "key2" 14 assert.is_true s\match("key2")?
15 15
16 it "should support interpolation", -> 16 it "should support interpolation", ->
17 name = "test" 17 name = "test"
@@ -25,13 +25,13 @@ describe "yaml string", ->
25 point: 25 point:
26 x: #{x} 26 x: #{x}
27 y: #{y} 27 y: #{y}
28 assert.is_true s\match "x: 10" 28 assert.is_true s\match("x: 10")?
29 assert.is_true s\match "y: 20" 29 assert.is_true s\match("y: 20")?
30 30
31 it "should work with expressions", -> 31 it "should work with expressions", ->
32 s = | 32 s = |
33 result: #{1 + 2} 33 result: #{1 + 2}
34 assert.is_true s\match "result: 3" 34 assert.is_true s\match("result: 3")?
35 35
36 it "should support multiline with variables", -> 36 it "should support multiline with variables", ->
37 config = | 37 config = |
@@ -39,15 +39,17 @@ describe "yaml string", ->
39 host: localhost 39 host: localhost
40 port: 5432 40 port: 5432
41 name: mydb 41 name: mydb
42 assert.is_true config\match "database:" 42 assert.is_true config\match("database:")?
43 assert.is_true config\match "host:" 43 assert.is_true config\match("host:")?
44 44
45 it "should escape special characters", -> 45 it "should escape special characters", ->
46 Hello = "Hello"
46 s = | 47 s = |
47 path: "C:\Program Files\App" 48 path: "C:\Program Files\App"
48 note: 'He said: "#{Hello}!"' 49 note: 'He said: "#{Hello}!"'
49 assert.is_true s\match "path:" 50 assert.same s, [[
50 assert.is_true s\match "note:" 51path: "C:\Program Files\App"
52note: 'He said: "Hello!"']]
51 53
52 it "should work in function", -> 54 it "should work in function", ->
53 fn = -> 55 fn = ->
@@ -57,8 +59,7 @@ describe "yaml string", ->
57 return str 59 return str
58 60
59 result = fn! 61 result = fn!
60 assert.is_true result\match "foo:" 62 assert.same result, "foo:\n\tbar: baz"
61 assert.is_true result\match "bar:"
62 63
63 it "should strip common leading whitespace", -> 64 it "should strip common leading whitespace", ->
64 fn = -> 65 fn = ->
@@ -68,40 +69,39 @@ describe "yaml string", ->
68 s 69 s
69 70
70 result = fn! 71 result = fn!
71 assert.is_true result\match "nested:" 72 assert.same result, "nested:
72 assert.is_true result\match "item:" 73 item: value"
73 74
74 it "should support empty lines", -> 75 it "should support empty lines", ->
75 s = | 76 s = |
76 line1 77 line1
77 78
78 line3 79 line3
79 assert.is_true s\match "line1" 80 assert.same s, "line1\nline3"
80 assert.is_true s\match "line3"
81 81
82 it "should work with table access in interpolation", -> 82 it "should work with table access in interpolation", ->
83 t = {value: 100} 83 t = {value: 100}
84 s = | 84 s = |
85 value: #{t.value} 85 value: #{t.value}
86 assert.is_true s\match "value: 100" 86 assert.same s, "value: 100"
87 87
88 it "should support function calls in interpolation", -> 88 it "should support function calls in interpolation", ->
89 s = | 89 s = |
90 result: #{(-> 42)!} 90 result: #{(-> 42)!}
91 assert.is_true s\match "result: 42" 91 assert.same s, "result: 42"
92 92
93 it "should handle quotes correctly", -> 93 it "should handle quotes correctly", ->
94 s = | 94 s = |
95 "quoted" 95 "quoted"
96 'single quoted' 96 'single quoted'
97 assert.is_true s\match '"quoted"' 97 assert.is_true s\match('"quoted"')?
98 assert.is_true s\match "'single quoted'" 98 assert.is_true s\match("'single quoted'")?
99 99
100 it "should work with multiple interpolations", -> 100 it "should work with multiple interpolations", ->
101 a, b, c = 1, 2, 3 101 a, b, c = 1, 2, 3
102 s = | 102 s = |
103 values: #{a}, #{b}, #{c} 103 values: #{a}, #{b}, #{c}
104 assert.is_true s\match "values: 1, 2, 3" 104 assert.same s, "values: 1, 2, 3"
105 105
106 it "should preserve newlines", -> 106 it "should preserve newlines", ->
107 s = | 107 s = |
diff --git a/spec/inputs/unicode/syntax.yue b/spec/inputs/unicode/syntax.yue
index 939579b..b5494f4 100644
--- a/spec/inputs/unicode/syntax.yue
+++ b/spec/inputs/unicode/syntax.yue
@@ -81,11 +81,11 @@ _ = 这里(我们)"去"[12123]
81 81
82分裂"abc xyz 123"\映射"#"\打印全部! 82分裂"abc xyz 123"\映射"#"\打印全部!
83 83
84_ = f""[变量a] 84_ = f("")[变量a]
85_ = f""\变量b! 85_ = f""\变量b!
86_ = f"".变量c! 86_ = f"".变量c!
87 87
88f ""[变量a] 88f ("")[变量a]
89f ""\变量b! 89f ""\变量b!
90f "".变量c! 90f "".变量c!
91 91
diff --git a/spec/outputs/test/advanced_macro_spec.lua b/spec/outputs/test/advanced_macro_spec.lua
new file mode 100644
index 0000000..0a46978
--- /dev/null
+++ b/spec/outputs/test/advanced_macro_spec.lua
@@ -0,0 +1,92 @@
1return describe("advanced macro", function()
2 it("should evaluate macro at compile time", function()
3 local area = 6.2831853071796 * 5
4 return assert.is_true(area > 0)
5 end)
6 it("should support macro with arguments", function()
7 local result = (5 + 10)
8 return assert.same(result, 15)
9 end)
10 it("should handle string returning macro", function()
11 local result = 'hello world'
12 return assert.same(result, "hello world")
13 end)
14 it("should work with conditional compilation", function()
15 debugMode = true
16 assert.is_true(debugMode)
17 return assert.is_true(debugMode)
18 end)
19 it("should support macro generating conditional code", function()
20 debugMode = true
21 local x = 10
22 return assert.same(x, 10)
23 end)
24 it("should work with lua code insertion", function()
25 local macro_test_var = 42
26 do
27local macro_test_var = 99
28 end
29 return assert.same(macro_test_var, 42)
30 end)
31 it("should support multi-line raw lua", function()
32 local multiline_var = "test"
33multiline_var = "test work"
34 local multiline_var1 = "test1"
35 assert.same(multiline_var, "test work")
36 return assert.same(multiline_var1, "test1")
37 end)
38 it("should export macro from module", function()
39 local result = (5 * 2)
40 return assert.same(result, 10)
41 end)
42 it("should work with builtin FILE macro", function()
43 local result = "./spec/inputs/test/advanced_macro_spec.yue"
44 return assert.is_true(type(result) == "string")
45 end)
46 it("should work with builtin LINE macro", function()
47 local result = 82
48 return assert.is_true(type(result) == "number")
49 end)
50 it("should support argument validation", function()
51 local result = 123
52 return assert.same(result, 123)
53 end)
54 it("should handle string argument validation", function()
55 local result = "hello"
56 return assert.same(result, "hello")
57 end)
58 it("should work with is_ast check", function()
59 local result = (10 + 20)
60 return assert.same(result, 30)
61 end)
62 it("should support macro generating macro", function()
63 local result = "Red"
64 return assert.same(result, "Red")
65 end)
66 it("should handle complex macro logic", function()
67 local my_print
68 my_print = function(...)
69 return ...
70 end
71 local a, b, c = my_print("hello", "world", 123)
72 assert.same(a, "hello")
73 assert.same(b, "world")
74 return assert.same(c, 123)
75 end)
76 it("should work with table manipulation", function()
77 local result = {
78 "1",
79 "2",
80 "3"
81 }
82 return assert.same(result, {
83 "1",
84 "2",
85 "3"
86 })
87 end)
88 return it("should support string concatenation in macro", function()
89 local result = ("hello" .. "world")
90 return assert.same(result, "helloworld")
91 end)
92end)
diff --git a/spec/outputs/test/close_attribute_spec.lua b/spec/outputs/test/close_attribute_spec.lua
new file mode 100644
index 0000000..cc64da8
--- /dev/null
+++ b/spec/outputs/test/close_attribute_spec.lua
@@ -0,0 +1,226 @@
1return describe("close attribute", function()
2 it("should declare close variable", function()
3 local closed = false
4 do
5 local _ <close> = setmetatable({ }, {
6 __close = function()
7 closed = true
8 end
9 })
10 end
11 return assert.is_true(closed)
12 end)
13 it("should work with metatable syntax", function()
14 local called = false
15 do
16 local _ <close> = setmetatable({ }, {
17 __close = function()
18 called = true
19 end
20 })
21 end
22 return assert.is_true(called)
23 end)
24 it("should handle multiple close scopes", function()
25 local order = { }
26 do
27 local first <close> = setmetatable({ }, {
28 __close = function()
29 return table.insert(order, "first")
30 end
31 })
32 local second <close> = setmetatable({ }, {
33 __close = function()
34 return table.insert(order, "second")
35 end
36 })
37 end
38 return assert.same(order, {
39 "second",
40 "first"
41 })
42 end)
43 it("should work with resources", function()
44 local resource_opened = false
45 local resource_closed = false
46 do
47 resource_opened = true
48 local _ <close> = setmetatable({ }, {
49 __close = function()
50 resource_closed = true
51 end
52 })
53 end
54 assert.is_true(resource_opened)
55 return assert.is_true(resource_closed)
56 end)
57 it("should support close in function", function()
58 local closed = false
59 local fn
60 fn = function()
61 local _ <close> = setmetatable({ }, {
62 __close = function()
63 closed = true
64 end
65 })
66 return "result"
67 end
68 local result = fn()
69 assert.same(result, "result")
70 return assert.is_true(closed)
71 end)
72 it("should work with fat arrow", function()
73 local closed = false
74 local obj = setmetatable({
75 value = 10,
76 }, {
77 __close = function(self)
78 closed = true
79 end
80 })
81 do
82 local _ <close> = obj
83 end
84 return assert.is_true(closed)
85 end)
86 it("should handle nested close scopes", function()
87 local outer_closed = false
88 local inner_closed = false
89 do
90 local outer <close> = setmetatable({ }, {
91 __close = function()
92 outer_closed = true
93 end
94 })
95 do
96 local inner <close> = setmetatable({ }, {
97 __close = function()
98 inner_closed = true
99 end
100 })
101 end
102 end
103 assert.is_true(inner_closed)
104 return assert.is_true(outer_closed)
105 end)
106 it("should work with conditional close", function()
107 local closed = false
108 local should_close = true
109 if should_close then
110 local _ <close> = setmetatable({ }, {
111 __close = function()
112 closed = true
113 end
114 })
115 end
116 return assert.is_true(closed)
117 end)
118 it("should support close in loop", function()
119 local closed_count = 0
120 for i = 1, 3 do
121 do
122 local _ <close> = setmetatable({ }, {
123 __close = function()
124 closed_count = closed_count + 1
125 end
126 })
127 end
128 end
129 return assert.same(closed_count, 3)
130 end)
131 it("should work with table destructuring", function()
132 local closed = false
133 do
134 local tb <close> = setmetatable({ }, {
135 __close = function()
136 closed = true
137 end
138 })
139 end
140 return assert.is_true(closed)
141 end)
142 it("should handle close with return value", function()
143 local closed = false
144 local fn
145 fn = function()
146 local _ <close> = setmetatable({ }, {
147 __close = function()
148 closed = true
149 end
150 })
151 return 42
152 end
153 local result = fn()
154 assert.same(result, 42)
155 return assert.is_true(closed)
156 end)
157 it("should work with error handling", function()
158 local closed = false
159 local error_thrown = false
160 do
161 local _ <close> = setmetatable({ }, {
162 __close = function()
163 closed = true
164 end
165 })
166 error_thrown = true
167 end
168 assert.is_true(closed)
169 return assert.is_true(error_thrown)
170 end)
171 it("should support close in varargs function", function()
172 local closed = false
173 local fn
174 fn = function(...)
175 local _ <close> = setmetatable({ }, {
176 __close = function()
177 closed = true
178 end
179 })
180 return {
181 ...
182 }
183 end
184 local result = fn(1, 2, 3)
185 assert.same(result, {
186 1,
187 2,
188 3
189 })
190 return assert.is_true(closed)
191 end)
192 it("should work with multiple variables", function()
193 local first_closed = false
194 local second_closed = false
195 do
196 local first <close> = setmetatable({ }, {
197 __close = function()
198 first_closed = true
199 end
200 })
201 local second <close> = setmetatable({ }, {
202 __close = function()
203 second_closed = true
204 end
205 })
206 end
207 assert.is_true(first_closed)
208 return assert.is_true(second_closed)
209 end)
210 return it("should handle close in try block", function()
211 local closed = false
212 local success = false
213 success = xpcall(function()
214 local _ <close> = setmetatable({ }, {
215 __close = function()
216 closed = true
217 end
218 })
219 return true
220 end, function(err)
221 return false
222 end)
223 assert.is_true(success)
224 return assert.is_true(closed)
225 end)
226end)
diff --git a/spec/outputs/test/const_attribute_spec.lua b/spec/outputs/test/const_attribute_spec.lua
new file mode 100644
index 0000000..2e2f7a3
--- /dev/null
+++ b/spec/outputs/test/const_attribute_spec.lua
@@ -0,0 +1,131 @@
1return describe("const attribute", function()
2 it("should declare const variable", function()
3 local a <const> = 123
4 return assert.same(a, 123)
5 end)
6 it("should prevent reassignment", function()
7 local b <const> = 456
8 return assert.same(b, 456)
9 end)
10 it("should work with strings", function()
11 local name <const> = "test"
12 return assert.same(name, "test")
13 end)
14 it("should support const with destructuring", function()
15 local tb = {
16 a = 1,
17 b = 2,
18 3,
19 4
20 }
21 local a, b, c, d
22 a, b, c, d = tb.a, tb.b, tb[1], tb[2]
23 assert.same(a, 1)
24 assert.same(b, 2)
25 assert.same(c, 3)
26 return assert.same(d, 4)
27 end)
28 it("should handle nested const", function()
29 local nested <const> = {
30 inner = {
31 value = 10
32 }
33 }
34 return assert.same(nested.inner.value, 10)
35 end)
36 it("should work with arrays", function()
37 local items
38 items = {
39 1,
40 2,
41 3
42 }
43 return assert.same(items[1], 1)
44 end)
45 it("should support const in function scope", function()
46 local fn
47 fn = function()
48 local local_const <const> = "local"
49 return local_const
50 end
51 local result = fn()
52 return assert.same(result, "local")
53 end)
54 it("should work with multiple const declarations", function()
55 local x <const> = 1
56 local y <const> = 2
57 local z <const> = 3
58 return assert.same(x + y + z, 6)
59 end)
60 it("should handle const functions", function()
61 local add
62 add = function(a, b)
63 return a + b
64 end
65 return assert.same(add(5, 10), 15)
66 end)
67 it("should work with const tables", function()
68 local config <const> = {
69 host = "localhost",
70 port = 8080
71 }
72 assert.same(config.host, "localhost")
73 return assert.same(config.port, 8080)
74 end)
75 it("should support global const", function()
76 GLOBAL_CONST = 999
77 return assert.same(GLOBAL_CONST, 999)
78 end)
79 it("should work with boolean const", function()
80 local flag <const> = true
81 local another <const> = false
82 assert.is_true(flag)
83 return assert.is_false(another)
84 end)
85 it("should handle nil const", function()
86 local nil_value <const> = nil
87 return assert.same(nil_value, nil)
88 end)
89 it("should work with expressions", function()
90 local calculated <const> = 10 + 20
91 return assert.same(calculated, 30)
92 end)
93 it("should work in table comprehension", function()
94 local multiplier <const> = 2
95 local items = {
96 1,
97 2,
98 3
99 }
100 local result
101 do
102 local _accum_0 = { }
103 local _len_0 = 1
104 for _index_0 = 1, #items do
105 local item = items[_index_0]
106 _accum_0[_len_0] = item * multiplier
107 _len_0 = _len_0 + 1
108 end
109 result = _accum_0
110 end
111 return assert.same(result, {
112 2,
113 4,
114 6
115 })
116 end)
117 return it("should work with complex expressions", function()
118 local complex <const> = {
119 data = {
120 1,
121 2,
122 3
123 },
124 nested = {
125 key = "value"
126 }
127 }
128 assert.same(complex.data[1], 1)
129 return assert.same(complex.nested.key, "value")
130 end)
131end)
diff --git a/spec/outputs/test/do_statement_spec.lua b/spec/outputs/test/do_statement_spec.lua
new file mode 100644
index 0000000..fb93fa0
--- /dev/null
+++ b/spec/outputs/test/do_statement_spec.lua
@@ -0,0 +1,238 @@
1return describe("do statement", function()
2 it("should create new scope", function()
3 local x = 10
4 do
5 local x = 20
6 assert.same(x, 20)
7 end
8 return assert.same(x, 10)
9 end)
10 it("should return value from do block", function()
11 local result
12 do
13 local x = 5
14 result = x * 2
15 end
16 return assert.same(result, 10)
17 end)
18 it("should work with multiple statements", function()
19 local result
20 do
21 local a = 1
22 local b = 2
23 local c = 3
24 result = a + b + c
25 end
26 return assert.same(result, 6)
27 end)
28 it("should handle nested do blocks", function()
29 local result
30 do
31 local x = 10
32 local y
33 do
34 local z = 5
35 y = z * 2
36 end
37 result = x + y
38 end
39 return assert.same(result, 20)
40 end)
41 it("should support conditional in do block", function()
42 local result
43 do
44 local value = 5
45 if value > 3 then
46 result = value * 2
47 else
48 result = value
49 end
50 end
51 return assert.same(result, 10)
52 end)
53 it("should work with loops in do block", function()
54 local result
55 do
56 local sum = 0
57 for i = 1, 5 do
58 sum = sum + i
59 end
60 result = sum
61 end
62 return assert.same(result, 15)
63 end)
64 it("should handle table operations", function()
65 local result
66 do
67 local tb = {
68 1,
69 2,
70 3
71 }
72 table.insert(tb, 4)
73 result = #tb
74 end
75 return assert.same(result, 4)
76 end)
77 it("should work with function definition", function()
78 local result
79 do
80 local fn
81 fn = function(x)
82 return x * 2
83 end
84 result = fn(5)
85 end
86 return assert.same(result, 10)
87 end)
88 it("should support variable shadowing", function()
89 local x = "outer"
90 local result
91 do
92 local x = "inner"
93 result = x
94 end
95 assert.same(result, "inner")
96 return assert.same(x, "outer")
97 end)
98 it("should work with method calls", function()
99 local obj = {
100 value = 10,
101 double = function(self)
102 return self.value * 2
103 end
104 }
105 local result
106 do
107 local _accum_0
108 repeat
109 _accum_0 = obj:double()
110 break
111 until true
112 result = _accum_0
113 end
114 return assert.same(result, 20)
115 end)
116 it("should handle comprehensions in do block", function()
117 local result
118 do
119 local items = {
120 1,
121 2,
122 3,
123 4,
124 5
125 }
126 local _accum_0 = { }
127 local _len_0 = 1
128 for _index_0 = 1, #items do
129 local item = items[_index_0]
130 _accum_0[_len_0] = item * 2
131 _len_0 = _len_0 + 1
132 end
133 result = _accum_0
134 end
135 return assert.same(result, {
136 2,
137 4,
138 6,
139 8,
140 10
141 })
142 end)
143 it("should work with try-catch", function()
144 local success, result = xpcall(function()
145 error("test error")
146 return false
147 end, function(err)
148 return true
149 end)
150 assert.is_false(success)
151 return assert.is_true(result)
152 end)
153 it("should support return statement", function()
154 local fn
155 fn = function()
156 do
157 local x = 10
158 return x * 2
159 end
160 return "never reached"
161 end
162 local result = fn()
163 return assert.same(result, 20)
164 end)
165 it("should work with assignment", function()
166 local result
167 do
168 local a, b, c = 1, 2, 3
169 result = a + b + c
170 end
171 return assert.same(result, 6)
172 end)
173 it("should handle destructuring", function()
174 local result
175 do
176 local tb = {
177 x = 10,
178 y = 20
179 }
180 local x, y = tb.x, tb.y
181 result = x + y
182 end
183 return assert.same(result, 30)
184 end)
185 it("should work with string interpolation", function()
186 local name = "world"
187 local result
188 do
189 local greeting = "hello"
190 result = tostring(greeting) .. " " .. tostring(name)
191 end
192 return assert.same(result, "hello world")
193 end)
194 it("should support implicit return", function()
195 local result
196 do
197 local value = 42
198 result = value
199 end
200 return assert.same(result, 42)
201 end)
202 it("should handle empty do block", function()
203 local result
204 do
205 result = nil
206 end
207 return assert.same(result, nil)
208 end)
209 return it("should work with backcalls", function()
210 local map
211 map = function(f, items)
212 local _accum_0 = { }
213 local _len_0 = 1
214 for _index_0 = 1, #items do
215 local item = items[_index_0]
216 _accum_0[_len_0] = f(item)
217 _len_0 = _len_0 + 1
218 end
219 return _accum_0
220 end
221 local result
222 do
223 local items = {
224 1,
225 2,
226 3
227 }
228 result = map(function(x)
229 return x * 2
230 end, items)
231 end
232 return assert.same(result, {
233 2,
234 4,
235 6
236 })
237 end)
238end)
diff --git a/spec/outputs/test/functions_advanced_spec.lua b/spec/outputs/test/functions_advanced_spec.lua
new file mode 100644
index 0000000..4e99023
--- /dev/null
+++ b/spec/outputs/test/functions_advanced_spec.lua
@@ -0,0 +1,259 @@
1return describe("advanced functions", function()
2 it("should support fat arrow with self", function()
3 local obj = {
4 value = 10,
5 getValue = function(self)
6 return self.value
7 end
8 }
9 return assert.same(obj:getValue(), 10)
10 end)
11 it("should work with argument defaults", function()
12 local fn
13 fn = function(name, height)
14 if name == nil then
15 name = "something"
16 end
17 if height == nil then
18 height = 100
19 end
20 return tostring(name) .. ", " .. tostring(height)
21 end
22 assert.same(fn(), "something, 100")
23 assert.same(fn("test"), "test, 100")
24 return assert.same(fn("test", 50), "test, 50")
25 end)
26 it("should handle defaults with previous arguments", function()
27 local fn
28 fn = function(x, y)
29 if x == nil then
30 x = 100
31 end
32 if y == nil then
33 y = x + 1000
34 end
35 return x + y
36 end
37 assert.same(fn(), 1200)
38 return assert.same(fn(50), 1100)
39 end)
40 it("should work with multi-line arguments", function()
41 local my_func
42 my_func = function(a, b, c, d, e, f)
43 return a + b + c + d + e + f
44 end
45 local result = my_func(5, 4, 3, 8, 9, 10)
46 return assert.same(result, 39)
47 end)
48 it("should support nested function calls", function()
49 local another_func
50 another_func = function(a, b, c, d, e, f)
51 return a + b + c + d + e + f
52 end
53 local my_func
54 my_func = function(a, b, c, d, e, f, g)
55 return a + b + c + d + e + f + g
56 end
57 local result = my_func(5, 6, 7, 6, another_func(6, 7, 8, 9, 1, 2), 5, 4)
58 return assert.same(result, 66)
59 end)
60 it("should handle implicit return", function()
61 local sum
62 sum = function(x, y)
63 return x + y
64 end
65 return assert.same(sum(10, 20), 30)
66 end)
67 it("should work with explicit return", function()
68 local difference
69 difference = function(x, y)
70 return x - y
71 end
72 return assert.same(difference(20, 10), 10)
73 end)
74 it("should support multiple return values", function()
75 local mystery
76 mystery = function(x, y)
77 return x + y, x - y
78 end
79 local a, b = mystery(10, 20)
80 assert.same(a, 30)
81 return assert.same(b, -10)
82 end)
83 it("should work with function as argument", function()
84 local apply
85 apply = function(fn, x, y)
86 return fn(x, y)
87 end
88 local result = apply((function(a, b)
89 return a + b
90 end), 5, 10)
91 return assert.same(result, 15)
92 end)
93 it("should handle function returning function", function()
94 local create_adder
95 create_adder = function(x)
96 return function(y)
97 return x + y
98 end
99 end
100 local add_five = create_adder(5)
101 return assert.same(add_five(10), 15)
102 end)
103 it("should support immediately invoked function", function()
104 local result = (function(x)
105 return x * 2
106 end)(5)
107 return assert.same(result, 10)
108 end)
109 it("should work with varargs", function()
110 local sum_all
111 sum_all = function(...)
112 local total = 0
113 for i = 1, select('#', ...) do
114 if type(select(i, ...)) == "number" then
115 total = total + select(i, ...)
116 end
117 end
118 return total
119 end
120 return assert.same(sum_all(1, 2, 3, 4, 5), 15)
121 end)
122 it("should handle named varargs", function()
123 local fn
124 fn = function(...)
125 local t = {
126 n = select("#", ...),
127 ...
128 }
129 local count = 0
130 for i = 1, t.n do
131 count = count + 1
132 end
133 return count
134 end
135 return assert.same(fn(1, 2, 3), 3)
136 end)
137 it("should support prefixed return", function()
138 local findValue
139 findValue = function()
140 local items = {
141 1,
142 2,
143 3
144 }
145 for _index_0 = 1, #items do
146 local item = items[_index_0]
147 if item == 5 then
148 return item
149 end
150 end
151 return "not found"
152 end
153 local result = findValue()
154 return assert.same(result, "not found")
155 end)
156 it("should work with parameter destructuring", function()
157 local fn
158 fn = function(_arg_0)
159 local a, b, c
160 a, b, c = _arg_0.a, _arg_0.b, _arg_0.c
161 return a + b + c
162 end
163 return assert.same(fn({
164 a = 1,
165 b = 2,
166 c = 3
167 }), 6)
168 end)
169 it("should handle default values in destructuring", function()
170 local fn
171 fn = function(_arg_0)
172 local a1, b
173 a1, b = _arg_0.a, _arg_0.b
174 if a1 == nil then
175 a1 = 123
176 end
177 if b == nil then
178 b = 'abc'
179 end
180 return a1 .. " " .. b
181 end
182 assert.same(fn({ }), "123 abc")
183 return assert.same(fn({
184 a = 456
185 }), "456 abc")
186 end)
187 it("should support empty function body", function()
188 local empty_fn
189 empty_fn = function() end
190 return assert.same(empty_fn(), nil)
191 end)
192 it("should work with function in table", function()
193 local tb = {
194 value = 10,
195 double = function(self)
196 return self.value * 2
197 end
198 }
199 return assert.same(tb:double(), 20)
200 end)
201 it("should handle function with no arguments", function()
202 local fn
203 fn = function()
204 return "result"
205 end
206 assert.same(fn(), "result")
207 return assert.same(fn(), "result")
208 end)
209 it("should support calling function with !", function()
210 local fn
211 fn = function()
212 return 42
213 end
214 return assert.same(fn(), 42)
215 end)
216 it("should work with nested functions", function()
217 local outer
218 outer = function(x)
219 local inner
220 inner = function(y)
221 return x + y
222 end
223 return inner
224 end
225 local add_five = outer(5)
226 return assert.same(add_five(10), 15)
227 end)
228 it("should handle function in expression", function()
229 local result
230 if (function(x)
231 return x > 10
232 end)(15) then
233 result = "large"
234 else
235 result = "small"
236 end
237 return assert.same(result, "large")
238 end)
239 return it("should support function as return value", function()
240 local get_operation
241 get_operation = function(op)
242 if "add" == op then
243 return function(a, b)
244 return a + b
245 end
246 elseif "subtract" == op then
247 return function(a, b)
248 return a - b
249 end
250 else
251 return function()
252 return 0
253 end
254 end
255 end
256 local add = get_operation("add")
257 return assert.same(add(5, 3), 8)
258 end)
259end)
diff --git a/spec/outputs/test/implicit_object_spec.lua b/spec/outputs/test/implicit_object_spec.lua
new file mode 100644
index 0000000..bd23978
--- /dev/null
+++ b/spec/outputs/test/implicit_object_spec.lua
@@ -0,0 +1,243 @@
1return describe("implicit object", function()
2 it("should create list with asterisk", function()
3 local list = {
4 1,
5 2,
6 3
7 }
8 return assert.same(list, {
9 1,
10 2,
11 3
12 })
13 end)
14 it("should create list with dash", function()
15 local items = {
16 "a",
17 "b",
18 "c"
19 }
20 return assert.same(items, {
21 "a",
22 "b",
23 "c"
24 })
25 end)
26 it("should work with function call", function()
27 local results = { }
28 local fn = {
29 1,
30 2,
31 3
32 }
33 for _index_0 = 1, #fn do
34 local item = fn[_index_0]
35 table.insert(results, item)
36 end
37 return assert.same(results, {
38 1,
39 2,
40 3
41 })
42 end)
43 it("should support nested implicit objects", function()
44 local tb = {
45 name = "test",
46 values = {
47 "a",
48 "b",
49 "c"
50 },
51 objects = {
52 {
53 name = "first",
54 value = 1
55 },
56 {
57 name = "second",
58 value = 2
59 }
60 }
61 }
62 assert.same(tb.values, {
63 "a",
64 "b",
65 "c"
66 })
67 assert.same(tb.objects[1].name, "first")
68 return assert.same(tb.objects[2].value, 2)
69 end)
70 it("should work with return statement", function()
71 local fn
72 fn = function()
73 return {
74 1,
75 2,
76 3
77 }
78 end
79 return assert.same(fn(), {
80 1,
81 2,
82 3
83 })
84 end)
85 it("should handle mixed content", function()
86 local tb = {
87 key = "value",
88 items = {
89 1,
90 2
91 },
92 other = "data"
93 }
94 assert.same(tb.key, "value")
95 assert.same(tb.items, {
96 1,
97 2
98 })
99 return assert.same(tb.other, "data")
100 end)
101 it("should work in assignment", function()
102 local list = {
103 "x",
104 "y",
105 "z"
106 }
107 return assert.same(list, {
108 "x",
109 "y",
110 "z"
111 })
112 end)
113 it("should support nested structures with asterisk", function()
114 local tb = {
115 1,
116 2,
117 nested = {
118 3,
119 4
120 }
121 }
122 assert.same(tb[1], 1)
123 assert.same(tb[2], 2)
124 return assert.same(tb.nested, {
125 3,
126 4
127 })
128 end)
129 it("should handle implicit object in tables", function()
130 local tb = {
131 name = "test",
132 list = {
133 1,
134 2
135 },
136 value = 42
137 }
138 return assert.same(tb.list, {
139 1,
140 2
141 })
142 end)
143 it("should work with expressions", function()
144 local x = 10
145 local list = {
146 x + 1,
147 x + 2,
148 x + 3
149 }
150 return assert.same(list, {
151 11,
152 12,
153 13
154 })
155 end)
156 it("should support method calls in implicit object", function()
157 local tb = {
158 name = "test",
159 items = {
160 {
161 name = "item1",
162 getName = function(self)
163 return self.name
164 end
165 },
166 {
167 name = "item2",
168 getName = function(self)
169 return self.name
170 end
171 }
172 }
173 }
174 assert.same(tb.items[1]:getName(), "item1")
175 return assert.same(tb.items[2]:getName(), "item2")
176 end)
177 it("should work with complex nested structures", function()
178 local config = {
179 database = {
180 host = "localhost",
181 ports = {
182 8080,
183 8081,
184 8082
185 }
186 },
187 servers = {
188 {
189 name = "server1",
190 port = 8080
191 },
192 {
193 name = "server2",
194 port = 8081
195 }
196 }
197 }
198 assert.same(config.database.ports, {
199 8080,
200 8081,
201 8082
202 })
203 return assert.same(config.servers[1].name, "server1")
204 end)
205 it("should handle empty implicit object", function()
206 local tb = {
207 items = {
208 nil
209 }
210 }
211 return assert.same(tb, {
212 items = {
213 nil
214 }
215 })
216 end)
217 it("should work in function arguments", function()
218 local fn
219 fn = function(items)
220 return #items
221 end
222 local result = fn({
223 1,
224 2,
225 3
226 })
227 return assert.same(result, 3)
228 end)
229 return it("should support mixed asterisk and dash", function()
230 local tb = {
231 values = {
232 1,
233 2,
234 3
235 }
236 }
237 return assert.same(tb.values, {
238 1,
239 2,
240 3
241 })
242 end)
243end)
diff --git a/spec/outputs/test/in_expression_spec.lua b/spec/outputs/test/in_expression_spec.lua
index fc118c2..e5af45b 100644
--- a/spec/outputs/test/in_expression_spec.lua
+++ b/spec/outputs/test/in_expression_spec.lua
@@ -34,34 +34,7 @@ local _anon_func_3 = function(chars)
34 end 34 end
35 return false 35 return false
36end 36end
37local _anon_func_4 = function(obj) 37local _anon_func_4 = function(items)
38 local _val_0 = "x"
39 for _index_0 = 1, #obj do
40 if obj[_index_0] == _val_0 then
41 return true
42 end
43 end
44 return false
45end
46local _anon_func_5 = function(obj)
47 local _val_0 = "y"
48 for _index_0 = 1, #obj do
49 if obj[_index_0] == _val_0 then
50 return true
51 end
52 end
53 return false
54end
55local _anon_func_6 = function(obj)
56 local _val_0 = "w"
57 for _index_0 = 1, #obj do
58 if obj[_index_0] == _val_0 then
59 return true
60 end
61 end
62 return false
63end
64local _anon_func_7 = function(items)
65 local _val_0 = 1 38 local _val_0 = 1
66 for _index_0 = 1, #items do 39 for _index_0 = 1, #items do
67 if items[_index_0] == _val_0 then 40 if items[_index_0] == _val_0 then
@@ -70,7 +43,7 @@ local _anon_func_7 = function(items)
70 end 43 end
71 return false 44 return false
72end 45end
73local _anon_func_8 = function(items) 46local _anon_func_5 = function(items)
74 local _val_0 = "two" 47 local _val_0 = "two"
75 for _index_0 = 1, #items do 48 for _index_0 = 1, #items do
76 if items[_index_0] == _val_0 then 49 if items[_index_0] == _val_0 then
@@ -79,7 +52,7 @@ local _anon_func_8 = function(items)
79 end 52 end
80 return false 53 return false
81end 54end
82local _anon_func_9 = function(items) 55local _anon_func_6 = function(items)
83 local _val_0 = true 56 local _val_0 = true
84 for _index_0 = 1, #items do 57 for _index_0 = 1, #items do
85 if items[_index_0] == _val_0 then 58 if items[_index_0] == _val_0 then
@@ -88,7 +61,7 @@ local _anon_func_9 = function(items)
88 end 61 end
89 return false 62 return false
90end 63end
91local _anon_func_10 = function(items) 64local _anon_func_7 = function(items)
92 local _val_0 = false 65 local _val_0 = false
93 for _index_0 = 1, #items do 66 for _index_0 = 1, #items do
94 if items[_index_0] == _val_0 then 67 if items[_index_0] == _val_0 then
@@ -97,7 +70,7 @@ local _anon_func_10 = function(items)
97 end 70 end
98 return false 71 return false
99end 72end
100local _anon_func_11 = function(empty) 73local _anon_func_8 = function(empty)
101 local _val_0 = 1 74 local _val_0 = 1
102 for _index_0 = 1, #empty do 75 for _index_0 = 1, #empty do
103 if empty[_index_0] == _val_0 then 76 if empty[_index_0] == _val_0 then
@@ -106,7 +79,7 @@ local _anon_func_11 = function(empty)
106 end 79 end
107 return false 80 return false
108end 81end
109local _anon_func_12 = function(empty) 82local _anon_func_9 = function(empty)
110 local _val_0 = "test" 83 local _val_0 = "test"
111 for _index_0 = 1, #empty do 84 for _index_0 = 1, #empty do
112 if empty[_index_0] == _val_0 then 85 if empty[_index_0] == _val_0 then
@@ -115,7 +88,7 @@ local _anon_func_12 = function(empty)
115 end 88 end
116 return false 89 return false
117end 90end
118local _anon_func_13 = function(items) 91local _anon_func_10 = function(items)
119 local _val_0 = 2 92 local _val_0 = 2
120 for _index_0 = 1, #items do 93 for _index_0 = 1, #items do
121 if items[_index_0] == _val_0 then 94 if items[_index_0] == _val_0 then
@@ -124,7 +97,7 @@ local _anon_func_13 = function(items)
124 end 97 end
125 return false 98 return false
126end 99end
127local _anon_func_14 = function(items) 100local _anon_func_11 = function(items)
128 local _val_0 = 4 101 local _val_0 = 4
129 for _index_0 = 1, #items do 102 for _index_0 = 1, #items do
130 if items[_index_0] == _val_0 then 103 if items[_index_0] == _val_0 then
@@ -133,7 +106,7 @@ local _anon_func_14 = function(items)
133 end 106 end
134 return false 107 return false
135end 108end
136local _anon_func_15 = function(items) 109local _anon_func_12 = function(items)
137 local _val_0 = 2 110 local _val_0 = 2
138 for _index_0 = 1, #items do 111 for _index_0 = 1, #items do
139 if items[_index_0] == _val_0 then 112 if items[_index_0] == _val_0 then
@@ -142,7 +115,7 @@ local _anon_func_15 = function(items)
142 end 115 end
143 return false 116 return false
144end 117end
145local _anon_func_16 = function(nested) 118local _anon_func_13 = function(nested)
146 local _val_0 = { 119 local _val_0 = {
147 1, 120 1,
148 2 121 2
@@ -154,7 +127,7 @@ local _anon_func_16 = function(nested)
154 end 127 end
155 return false 128 return false
156end 129end
157local _anon_func_17 = function(nested) 130local _anon_func_14 = function(nested)
158 local _val_0 = { 131 local _val_0 = {
159 1, 132 1,
160 3 133 3
@@ -166,7 +139,7 @@ local _anon_func_17 = function(nested)
166 end 139 end
167 return false 140 return false
168end 141end
169local _anon_func_18 = function(bools) 142local _anon_func_15 = function(bools)
170 local _val_0 = true 143 local _val_0 = true
171 for _index_0 = 1, #bools do 144 for _index_0 = 1, #bools do
172 if bools[_index_0] == _val_0 then 145 if bools[_index_0] == _val_0 then
@@ -175,7 +148,7 @@ local _anon_func_18 = function(bools)
175 end 148 end
176 return false 149 return false
177end 150end
178local _anon_func_19 = function(bools) 151local _anon_func_16 = function(bools)
179 local _val_0 = false 152 local _val_0 = false
180 for _index_0 = 1, #bools do 153 for _index_0 = 1, #bools do
181 if bools[_index_0] == _val_0 then 154 if bools[_index_0] == _val_0 then
@@ -184,7 +157,7 @@ local _anon_func_19 = function(bools)
184 end 157 end
185 return false 158 return false
186end 159end
187local _anon_func_20 = function(i, items) 160local _anon_func_17 = function(i, items)
188 for _index_0 = 1, #items do 161 for _index_0 = 1, #items do
189 if items[_index_0] == i then 162 if items[_index_0] == i then
190 return true 163 return true
@@ -192,7 +165,7 @@ local _anon_func_20 = function(i, items)
192 end 165 end
193 return false 166 return false
194end 167end
195local _anon_func_21 = function(key1, tb) 168local _anon_func_18 = function(key1, tb)
196 for _index_0 = 1, #tb do 169 for _index_0 = 1, #tb do
197 if tb[_index_0] == key1 then 170 if tb[_index_0] == key1 then
198 return true 171 return true
@@ -200,7 +173,7 @@ local _anon_func_21 = function(key1, tb)
200 end 173 end
201 return false 174 return false
202end 175end
203local _anon_func_22 = function(key2, tb) 176local _anon_func_19 = function(key2, tb)
204 for _index_0 = 1, #tb do 177 for _index_0 = 1, #tb do
205 if tb[_index_0] == key2 then 178 if tb[_index_0] == key2 then
206 return true 179 return true
@@ -208,7 +181,7 @@ local _anon_func_22 = function(key2, tb)
208 end 181 end
209 return false 182 return false
210end 183end
211local _anon_func_23 = function(get_items) 184local _anon_func_20 = function(get_items)
212 local _check_0 = get_items() 185 local _check_0 = get_items()
213 local _val_0 = 2 186 local _val_0 = 2
214 for _index_0 = 1, #_check_0 do 187 for _index_0 = 1, #_check_0 do
@@ -218,7 +191,7 @@ local _anon_func_23 = function(get_items)
218 end 191 end
219 return false 192 return false
220end 193end
221local _anon_func_24 = function(get_items) 194local _anon_func_21 = function(get_items)
222 local _check_0 = get_items() 195 local _check_0 = get_items()
223 local _val_0 = 5 196 local _val_0 = 5
224 for _index_0 = 1, #_check_0 do 197 for _index_0 = 1, #_check_0 do
@@ -228,7 +201,7 @@ local _anon_func_24 = function(get_items)
228 end 201 end
229 return false 202 return false
230end 203end
231local _anon_func_25 = function(items) 204local _anon_func_22 = function(items)
232 local _val_0 = nil 205 local _val_0 = nil
233 for _index_0 = 1, #items do 206 for _index_0 = 1, #items do
234 if items[_index_0] == _val_0 then 207 if items[_index_0] == _val_0 then
@@ -237,7 +210,7 @@ local _anon_func_25 = function(items)
237 end 210 end
238 return false 211 return false
239end 212end
240local _anon_func_26 = function(items) 213local _anon_func_23 = function(items)
241 local _val_0 = 1 214 local _val_0 = 1
242 for _index_0 = 1, #items do 215 for _index_0 = 1, #items do
243 if items[_index_0] == _val_0 then 216 if items[_index_0] == _val_0 then
@@ -246,7 +219,7 @@ local _anon_func_26 = function(items)
246 end 219 end
247 return false 220 return false
248end 221end
249local _anon_func_27 = function(obj) 222local _anon_func_24 = function(obj)
250 local _val_0 = "name" 223 local _val_0 = "name"
251 for _index_0 = 1, #obj do 224 for _index_0 = 1, #obj do
252 if obj[_index_0] == _val_0 then 225 if obj[_index_0] == _val_0 then
@@ -255,7 +228,7 @@ local _anon_func_27 = function(obj)
255 end 228 end
256 return false 229 return false
257end 230end
258local _anon_func_28 = function(obj) 231local _anon_func_25 = function(obj)
259 local _val_0 = "value" 232 local _val_0 = "value"
260 for _index_0 = 1, #obj do 233 for _index_0 = 1, #obj do
261 if obj[_index_0] == _val_0 then 234 if obj[_index_0] == _val_0 then
@@ -264,7 +237,7 @@ local _anon_func_28 = function(obj)
264 end 237 end
265 return false 238 return false
266end 239end
267local _anon_func_29 = function(obj) 240local _anon_func_26 = function(obj)
268 local _val_0 = "missing" 241 local _val_0 = "missing"
269 for _index_0 = 1, #obj do 242 for _index_0 = 1, #obj do
270 if obj[_index_0] == _val_0 then 243 if obj[_index_0] == _val_0 then
@@ -273,7 +246,7 @@ local _anon_func_29 = function(obj)
273 end 246 end
274 return false 247 return false
275end 248end
276local _anon_func_30 = function(items) 249local _anon_func_27 = function(items)
277 local _val_0 = 2 250 local _val_0 = 2
278 for _index_0 = 1, #items do 251 for _index_0 = 1, #items do
279 if items[_index_0] == _val_0 then 252 if items[_index_0] == _val_0 then
@@ -282,7 +255,7 @@ local _anon_func_30 = function(items)
282 end 255 end
283 return false 256 return false
284end 257end
285local _anon_func_31 = function(allowed, item) 258local _anon_func_28 = function(allowed, item)
286 for _index_0 = 1, #allowed do 259 for _index_0 = 1, #allowed do
287 if allowed[_index_0] == item then 260 if allowed[_index_0] == item then
288 return true 261 return true
@@ -311,15 +284,14 @@ return describe("in expression", function()
311 assert.is_true(_anon_func_2(chars)) 284 assert.is_true(_anon_func_2(chars))
312 return assert.is_false(_anon_func_3(chars)) 285 return assert.is_false(_anon_func_3(chars))
313 end) 286 end)
314 it("should check keys in table", function() 287 it("should check in table literal", function()
315 local obj = { 288 local x = 1
316 x = 1, 289 local y = 2
317 y = 2, 290 local z = 3
318 z = 3 291 local w = 4
319 } 292 assert.is_true((x == x or y == x or z == x))
320 assert.is_true(_anon_func_4(obj)) 293 assert.is_true((x == y or y == y or z == y))
321 assert.is_true(_anon_func_5(obj)) 294 return assert.is_false((x == w or y == w or z == w))
322 return assert.is_false(_anon_func_6(obj))
323 end) 295 end)
324 it("should work with mixed types", function() 296 it("should work with mixed types", function()
325 local items = { 297 local items = {
@@ -328,15 +300,15 @@ return describe("in expression", function()
328 true, 300 true,
329 nil 301 nil
330 } 302 }
331 assert.is_true(_anon_func_7(items)) 303 assert.is_true(_anon_func_4(items))
332 assert.is_true(_anon_func_8(items)) 304 assert.is_true(_anon_func_5(items))
333 assert.is_true(_anon_func_9(items)) 305 assert.is_true(_anon_func_6(items))
334 return assert.is_false(_anon_func_10(items)) 306 return assert.is_false(_anon_func_7(items))
335 end) 307 end)
336 it("should handle empty table", function() 308 it("should handle empty table", function()
337 local empty = { } 309 local empty = { }
338 assert.is_false(_anon_func_11(empty)) 310 assert.is_false(_anon_func_8(empty))
339 return assert.is_false(_anon_func_12(empty)) 311 return assert.is_false(_anon_func_9(empty))
340 end) 312 end)
341 it("should work in conditional", function() 313 it("should work in conditional", function()
342 local items = { 314 local items = {
@@ -345,7 +317,7 @@ return describe("in expression", function()
345 3 317 3
346 } 318 }
347 local result 319 local result
348 if _anon_func_13(items) then 320 if _anon_func_10(items) then
349 result = "found" 321 result = "found"
350 else 322 else
351 result = "not found" 323 result = "not found"
@@ -358,34 +330,44 @@ return describe("in expression", function()
358 2, 330 2,
359 3 331 3
360 } 332 }
361 assert.is_true(not (_anon_func_14(items))) 333 assert.is_true(not (_anon_func_11(items)))
362 return assert.is_false(not (_anon_func_15(items))) 334 return assert.is_false(not (_anon_func_12(items)))
363 end) 335 end)
364 it("should work with nested tables", function() 336 it("should work with nested tables", function()
337 local eq
338 eq = function(self, other)
339 return self[1] == other[1] and self[2] == other[2]
340 end
365 local nested = { 341 local nested = {
366 { 342 setmetatable({
367 1, 343 1,
368 2 344 2,
369 }, 345 }, {
370 { 346 __eq = eq
347 }),
348 setmetatable({
371 3, 349 3,
372 4 350 4,
373 }, 351 }, {
374 { 352 __eq = eq
353 }),
354 setmetatable({
375 5, 355 5,
376 6 356 6,
377 } 357 }, {
358 __eq = eq
359 })
378 } 360 }
379 assert.is_true(_anon_func_16(nested)) 361 assert.is_true(_anon_func_13(nested))
380 return assert.is_false(_anon_func_17(nested)) 362 return assert.is_false(_anon_func_14(nested))
381 end) 363 end)
382 it("should handle boolean values", function() 364 it("should handle boolean values", function()
383 local bools = { 365 local bools = {
384 true, 366 true,
385 false 367 false
386 } 368 }
387 assert.is_true(_anon_func_18(bools)) 369 assert.is_true(_anon_func_15(bools))
388 return assert.is_true(_anon_func_19(bools)) 370 return assert.is_true(_anon_func_16(bools))
389 end) 371 end)
390 it("should work in loop", function() 372 it("should work in loop", function()
391 local items = { 373 local items = {
@@ -397,7 +379,7 @@ return describe("in expression", function()
397 } 379 }
398 local count = 0 380 local count = 0
399 for i = 1, 10 do 381 for i = 1, 10 do
400 if (#items > 0 and _anon_func_20(i, items)) then 382 if (#items > 0 and _anon_func_17(i, items)) then
401 count = count + 1 383 count = count + 1
402 end 384 end
403 end 385 end
@@ -411,11 +393,11 @@ return describe("in expression", function()
411 b = 2 393 b = 2
412 } 394 }
413 local tb = { 395 local tb = {
414 [key1] = "first", 396 key1,
415 [key2] = "second" 397 key2
416 } 398 }
417 assert.is_true((#tb > 0 and _anon_func_21(key1, tb))) 399 assert.is_true((#tb > 0 and _anon_func_18(key1, tb)))
418 return assert.is_true((#tb > 0 and _anon_func_22(key2, tb))) 400 return assert.is_true((#tb > 0 and _anon_func_19(key2, tb)))
419 end) 401 end)
420 it("should work with function results", function() 402 it("should work with function results", function()
421 local get_items 403 local get_items
@@ -426,8 +408,8 @@ return describe("in expression", function()
426 3 408 3
427 } 409 }
428 end 410 end
429 assert.is_true(_anon_func_23(get_items)) 411 assert.is_true(_anon_func_20(get_items))
430 return assert.is_false(_anon_func_24(get_items)) 412 return assert.is_false(_anon_func_21(get_items))
431 end) 413 end)
432 it("should handle nil in table", function() 414 it("should handle nil in table", function()
433 local items = { 415 local items = {
@@ -435,17 +417,17 @@ return describe("in expression", function()
435 nil, 417 nil,
436 3 418 3
437 } 419 }
438 assert.is_true(_anon_func_25(items)) 420 assert.is_true(_anon_func_22(items))
439 return assert.is_true(_anon_func_26(items)) 421 return assert.is_true(_anon_func_23(items))
440 end) 422 end)
441 it("should work with string keys", function() 423 it("should work with string keys", function()
442 local obj = { 424 local obj = {
443 name = "test", 425 "name",
444 value = 42 426 "value"
445 } 427 }
446 assert.is_true(_anon_func_27(obj)) 428 assert.is_true(_anon_func_24(obj))
447 assert.is_true(_anon_func_28(obj)) 429 assert.is_true(_anon_func_25(obj))
448 return assert.is_false(_anon_func_29(obj)) 430 return assert.is_false(_anon_func_26(obj))
449 end) 431 end)
450 it("should support complex expressions", function() 432 it("should support complex expressions", function()
451 local items = { 433 local items = {
@@ -453,7 +435,7 @@ return describe("in expression", function()
453 2, 435 2,
454 3 436 3
455 } 437 }
456 local result = (_anon_func_30(items)) and "yes" or "no" 438 local result = (_anon_func_27(items)) and "yes" or "no"
457 return assert.same(result, "yes") 439 return assert.same(result, "yes")
458 end) 440 end)
459 return it("should work in comprehension", function() 441 return it("should work in comprehension", function()
@@ -474,7 +456,7 @@ return describe("in expression", function()
474 local _len_0 = 1 456 local _len_0 = 1
475 for _index_0 = 1, #source do 457 for _index_0 = 1, #source do
476 local item = source[_index_0] 458 local item = source[_index_0]
477 if (#allowed > 0 and _anon_func_31(allowed, item)) then 459 if (#allowed > 0 and _anon_func_28(allowed, item)) then
478 _accum_0[_len_0] = item 460 _accum_0[_len_0] = item
479 _len_0 = _len_0 + 1 461 _len_0 = _len_0 + 1
480 end 462 end
diff --git a/spec/outputs/test/multiline_args_spec.lua b/spec/outputs/test/multiline_args_spec.lua
new file mode 100644
index 0000000..562c571
--- /dev/null
+++ b/spec/outputs/test/multiline_args_spec.lua
@@ -0,0 +1,219 @@
1return describe("multiline arguments", function()
2 it("should split arguments across lines", function()
3 local sum
4 sum = function(a, b, c, d, e, f)
5 return a + b + c + d + e + f
6 end
7 local result = sum(5, 4, 3, 8, 9, 10)
8 return assert.same(result, 39)
9 end)
10 it("should handle nested function calls", function()
11 local outer
12 outer = function(a, b, c, d, e, f)
13 return a + b + c + d + e + f
14 end
15 local result = outer(5, 6, 7, 6, 2, 3)
16 return assert.same(result, 29)
17 end)
18 it("should work with string arguments", function()
19 local fn
20 fn = function(a, b, c, d)
21 return a .. b .. c .. d
22 end
23 local result = fn("hello", " ", "world", "!")
24 return assert.same(result, "hello world!")
25 end)
26 it("should support table arguments", function()
27 local fn
28 fn = function(a, b, c)
29 return {
30 a,
31 b,
32 c
33 }
34 end
35 local result = fn({
36 1,
37 2
38 }, {
39 3,
40 4
41 }, {
42 5,
43 6
44 })
45 return assert.same(result, {
46 {
47 1,
48 2
49 },
50 {
51 3,
52 4
53 },
54 {
55 5,
56 6
57 }
58 })
59 end)
60 it("should handle mixed types", function()
61 local fn
62 fn = function(a, b, c, d)
63 return {
64 a,
65 b,
66 c,
67 d
68 }
69 end
70 local result = fn("text", 123, true, nil)
71 return assert.same(result, {
72 "text",
73 123,
74 true,
75 nil
76 })
77 end)
78 it("should work in table literal", function()
79 local fn
80 fn = function(a, b)
81 return a + b
82 end
83 local result = {
84 1,
85 2,
86 3,
87 4,
88 fn(4, 5, 5, 6),
89 8,
90 9,
91 10
92 }
93 return assert.same(result, {
94 1,
95 2,
96 3,
97 4,
98 9,
99 8,
100 9,
101 10
102 })
103 end)
104 it("should handle deeply nested indentation", function()
105 local fn
106 fn = function(a, b, c, d, e, f, g)
107 return a + b + c + d + e + f + g
108 end
109 local y = {
110 fn(1, 2, 3, 4, 5, 6, 7)
111 }
112 local result = y[1]
113 return assert.same(result, 28)
114 end)
115 it("should work with conditional statements", function()
116 local fn
117 fn = function(a, b, c, d, e, f)
118 return a + b + c + d + e + f
119 end
120 local result1 = fn(1, 2, 3, 4, 5, 6)
121 local result
122 if result1 > 20 then
123 result = "yes"
124 else
125 result = "no"
126 end
127 return assert.same(result, "yes")
128 end)
129 it("should support function expressions", function()
130 local doublePlus
131 doublePlus = function(x, y)
132 return x * 2 + y
133 end
134 local result = doublePlus(5, 10)
135 return assert.same(result, 20)
136 end)
137 it("should handle chained function calls", function()
138 local add
139 add = function(a, b, c, d)
140 return a + b + c + d
141 end
142 local multiply
143 multiply = function(a, b, c, d)
144 return a * b * c * d
145 end
146 local result = multiply(1, 2, 3, 4)
147 return assert.same(result, 24)
148 end)
149 it("should work with method calls", function()
150 local obj = {
151 value = 10,
152 add = function(self, a, b, c)
153 return self.value + a + b + c
154 end
155 }
156 local result = obj:add(5, 10, 15)
157 return assert.same(result, 40)
158 end)
159 it("should support many arguments", function()
160 local sum_many
161 sum_many = function(...)
162 local total = 0
163 for i = 1, select('#', ...) do
164 if type(select(i, ...)) == "number" then
165 total = total + select(i, ...)
166 end
167 end
168 return total
169 end
170 local result = sum_many(1, 2, 3, 4, 5, 6, 7, 8, 9)
171 return assert.same(result, 45)
172 end)
173 it("should work with return statement", function()
174 local fn
175 fn = function(a, b, c)
176 return a + b + c
177 end
178 local get_value
179 get_value = function()
180 return fn(10, 20, 30)
181 end
182 local result = get_value()
183 return assert.same(result, 60)
184 end)
185 it("should handle default parameters", function()
186 local fn
187 fn = function(a, b, c)
188 if a == nil then
189 a = 1
190 end
191 if b == nil then
192 b = 2
193 end
194 if c == nil then
195 c = 3
196 end
197 return a + b + c
198 end
199 local result = fn(10, 20, 30)
200 return assert.same(result, 60)
201 end)
202 return it("should work with varargs", function()
203 local collect
204 collect = function(...)
205 return {
206 ...
207 }
208 end
209 local result = collect(1, 2, 3, 4, 5, 6)
210 return assert.same(result, {
211 1,
212 2,
213 3,
214 4,
215 5,
216 6
217 })
218 end)
219end)
diff --git a/spec/outputs/test/named_varargs_spec.lua b/spec/outputs/test/named_varargs_spec.lua
index 2a71cea..be35b22 100644
--- a/spec/outputs/test/named_varargs_spec.lua
+++ b/spec/outputs/test/named_varargs_spec.lua
@@ -187,21 +187,19 @@ return describe("named varargs", function()
187 }) 187 })
188 end) 188 end)
189 it("should support passing named varargs to another function", function() 189 it("should support passing named varargs to another function", function()
190 local inner
191 inner = function(...)
192 return {
193 ...
194 }
195 end
190 local outer 196 local outer
191 outer = function(...) 197 outer = function(...)
192 local t = { 198 local t = {
193 n = select("#", ...), 199 n = select("#", ...),
194 ... 200 ...
195 } 201 }
196 return inner((table.unpack(t))) 202 return inner(t[1], t[2], t[3])
197 end
198 local inner
199 inner = function(a, b, c)
200 return {
201 a,
202 b,
203 c
204 }
205 end 203 end
206 local result = outer(1, 2, 3) 204 local result = outer(1, 2, 3)
207 return assert.same(result, { 205 return assert.same(result, {
diff --git a/spec/outputs/test/operator_advanced_spec.lua b/spec/outputs/test/operator_advanced_spec.lua
new file mode 100644
index 0000000..42e4c30
--- /dev/null
+++ b/spec/outputs/test/operator_advanced_spec.lua
@@ -0,0 +1,210 @@
1local _anon_func_0 = function(v)
2 local _cond_0 = v(2)
3 if not (v(1) < _cond_0) then
4 return false
5 else
6 return _cond_0 <= v(3)
7 end
8end
9return describe("advanced operators", function()
10 it("should support chaining comparisons with functions", function()
11 local v
12 v = function(x)
13 return x
14 end
15 return assert.is_true(_anon_func_0(v))
16 end)
17 it("should handle compound assignment with or", function()
18 local x = nil
19 x = x or "default"
20 return assert.same(x, "default")
21 end)
22 it("should not overwrite existing value with or", function()
23 local x = "existing"
24 x = x or "default"
25 return assert.same(x, "existing")
26 end)
27 it("should support compound string concatenation", function()
28 local s = "hello"
29 s = s .. " world"
30 return assert.same(s, "hello world")
31 end)
32 it("should work with table appending", function()
33 local tab = {
34 1,
35 2
36 }
37 tab[#tab + 1] = 3
38 tab[#tab + 1] = 4
39 return assert.same(tab, {
40 1,
41 2,
42 3,
43 4
44 })
45 end)
46 it("should handle spread append", function()
47 local tbA = {
48 1,
49 2
50 }
51 local tbB = {
52 3,
53 4
54 }
55 local _len_0 = #tbA + 1
56 for _index_0 = 1, #tbB do
57 local _elm_0 = tbB[_index_0]
58 tbA[_len_0], _len_0 = _elm_0, _len_0 + 1
59 end
60 return assert.same(tbA, {
61 1,
62 2,
63 3,
64 4
65 })
66 end)
67 it("should support reverse indexing", function()
68 local items = {
69 1,
70 2,
71 3,
72 4,
73 5
74 }
75 assert.same(items[#items], 5)
76 assert.same(items[#items - 1], 4)
77 return assert.same(items[#items - 2], 3)
78 end)
79 it("should work with nil coalescing assignment", function()
80 local x = nil
81 if x == nil then
82 x = "default"
83 end
84 return assert.same(x, "default")
85 end)
86 it("should not assign with ??= when value exists", function()
87 local x = "existing"
88 if x == nil then
89 x = "default"
90 end
91 return assert.same(x, "existing")
92 end)
93 it("should chain nil coalescing", function()
94 local a = nil
95 local b = nil
96 local c = "value"
97 local result
98 if a ~= nil then
99 result = a
100 else
101 if b ~= nil then
102 result = b
103 else
104 result = c
105 end
106 end
107 return assert.same(result, "value")
108 end)
109 it("should support compound modulo", function()
110 local x = 20
111 x = x % 3
112 return assert.same(x, 2)
113 end)
114 it("should handle compound exponentiation", function()
115 local x = 2
116 x = x ^ 3
117 return assert.same(x, 8)
118 end)
119 it("should work with compound bitwise and", function()
120 local x = 15
121 x = x & 7
122 return assert.same(x, 7)
123 end)
124 it("should support compound bitwise or", function()
125 local x = 8
126 x = x | 3
127 return assert.same(x, 11)
128 end)
129 it("should handle compound bitwise xor", function()
130 local x = 12
131 x = x ~ 10
132 return assert.same(x, 6)
133 end)
134 it("should work with compound left shift", function()
135 local x = 2
136 x = x << 3
137 return assert.same(x, 16)
138 end)
139 it("should support compound right shift", function()
140 local x = 16
141 x = x >> 2
142 return assert.same(x, 4)
143 end)
144 it("should handle negation operator", function()
145 assert.same(-10, -10)
146 return assert.same
147 end)
148 it("should work with length operator on tables", function()
149 local tab = {
150 1,
151 2,
152 3,
153 4,
154 5
155 }
156 return assert.same(#tab, 5)
157 end)
158 it("should support length on strings", function()
159 local s = "hello"
160 return assert.same(#s, 5)
161 end)
162 it("should handle chaining assignment", function()
163 local a = 0
164 local b = 0
165 local c = 0
166 local d = 0
167 assert.same(a, 0)
168 assert.same(b, 0)
169 assert.same(c, 0)
170 return assert.same(d, 0)
171 end)
172 it("should work with chaining assignment with functions", function()
173 local f
174 f = function()
175 return 42
176 end
177 local x = f()
178 local y = x
179 local z = x
180 assert.same(x, 42)
181 assert.same(y, 42)
182 return assert.same(z, 42)
183 end)
184 it("should support != as alias for ~=", function()
185 assert.is_true(1 ~= 2)
186 return assert.is_false(1 ~= 1)
187 end)
188 it("should work with :: for method chaining", function()
189 local obj = {
190 value = 10,
191 add = function(self, n)
192 self.value = self.value + n
193 return self
194 end,
195 get = function(self)
196 return self.value
197 end
198 }
199 local result = obj:add(5):get()
200 return assert.same(result, 15)
201 end)
202 it("should handle complex expressions with precedence", function()
203 local result = 1 + 2 * 3 - 4 / 2
204 return assert.same(result, 5)
205 end)
206 return it("should support mixed operator types", function()
207 local result = 10 + 20 * 2 - 5 / 5
208 return assert.same(result, 49)
209 end)
210end)
diff --git a/spec/outputs/test/param_destructure_spec.lua b/spec/outputs/test/param_destructure_spec.lua
new file mode 100644
index 0000000..6aa9907
--- /dev/null
+++ b/spec/outputs/test/param_destructure_spec.lua
@@ -0,0 +1,369 @@
1local _anon_func_0 = function(_arg_0)
2 local _accum_0 = { }
3 local _len_0 = 1
4 local _max_0 = #_arg_0
5 for _index_0 = 2, _max_0 do
6 local _item_0 = _arg_0[_index_0]
7 _accum_0[_len_0] = _item_0
8 _len_0 = _len_0 + 1
9 end
10 return _accum_0
11end
12local _anon_func_1 = function(_arg_0)
13 local _accum_0 = { }
14 local _len_0 = 1
15 local _max_0 = #_arg_0
16 for _index_0 = 1, _max_0 do
17 local _item_0 = _arg_0[_index_0]
18 _accum_0[_len_0] = _item_0
19 _len_0 = _len_0 + 1
20 end
21 return _accum_0
22end
23return describe("parameter destructuring", function()
24 it("should destructure simple object", function()
25 local f
26 f = function(_arg_0)
27 local a, b, c
28 a, b, c = _arg_0.a, _arg_0.b, _arg_0.c
29 return {
30 a,
31 b,
32 c
33 }
34 end
35 local result = f({
36 a = 1,
37 b = "2",
38 c = { }
39 })
40 return assert.same(result, {
41 1,
42 "2",
43 { }
44 })
45 end)
46 it("should work with default values", function()
47 local f
48 f = function(_arg_0, c)
49 local a1, b
50 a1, b = _arg_0.a, _arg_0.b
51 if a1 == nil then
52 a1 = 123
53 end
54 if b == nil then
55 b = 'abc'
56 end
57 if c == nil then
58 c = { }
59 end
60 return {
61 a1,
62 b,
63 c
64 }
65 end
66 local result1 = f({
67 a = 0
68 }, "test")
69 assert.same(result1, {
70 0,
71 'abc',
72 'test'
73 })
74 local result2 = f({ })
75 return assert.same(result2, {
76 123,
77 'abc',
78 { }
79 })
80 end)
81 it("should destructure with mixed syntax", function()
82 local f
83 f = function(_arg_0)
84 local a, b1, c
85 a, b1, c = _arg_0.a, _arg_0.b, _arg_0.c
86 return {
87 a,
88 b1,
89 c
90 }
91 end
92 local result = f({
93 a = 1,
94 b = 2,
95 c = 3
96 })
97 return assert.same(result, {
98 1,
99 2,
100 3
101 })
102 end)
103 it("should work with nested destructuring", function()
104 local f
105 f = function(_arg_0)
106 local x, y
107 x, y = _arg_0.nested.x, _arg_0.nested.y
108 return {
109 x,
110 y
111 }
112 end
113 local result = f({
114 nested = {
115 x = 10,
116 y = 20
117 }
118 })
119 return assert.same(result, {
120 10,
121 20
122 })
123 end)
124 it("should handle array parameters", function()
125 local f
126 f = function(_arg_0)
127 local a, b, c
128 a, b, c = _arg_0[1], _arg_0[2], _arg_0[3]
129 return {
130 a,
131 b,
132 c
133 }
134 end
135 local result = f({
136 1,
137 2,
138 3
139 })
140 return assert.same(result, {
141 1,
142 2,
143 3
144 })
145 end)
146 it("should support mixed array and object", function()
147 local f
148 f = function(_arg_0, _arg_1)
149 local first
150 first = _arg_0[1]
151 local value
152 value = _arg_1.key.value
153 return {
154 first,
155 value
156 }
157 end
158 local result = f({
159 1
160 }, {
161 key = {
162 value = "test"
163 }
164 })
165 return assert.same(result, {
166 1,
167 "test"
168 })
169 end)
170 it("should work with fat arrow", function()
171 local obj = {
172 value = 100,
173 f = function(self, _arg_0)
174 local x, y
175 x, y = _arg_0.x, _arg_0.y
176 return self.value + x + y
177 end
178 }
179 local result = obj:f({
180 x = 10,
181 y = 20
182 })
183 return assert.same(result, 130)
184 end)
185 it("should handle missing keys", function()
186 local f
187 f = function(_arg_0)
188 local a, b, c
189 a, b, c = _arg_0.a, _arg_0.b, _arg_0.c
190 if b == nil then
191 b = "default"
192 end
193 if c == nil then
194 c = "missing"
195 end
196 return {
197 a,
198 b,
199 c
200 }
201 end
202 local result = f({
203 a = 1
204 })
205 return assert.same(result, {
206 1,
207 'default',
208 'missing'
209 })
210 end)
211 it("should work with complex defaults", function()
212 local f
213 f = function(_arg_0)
214 local a1, b1
215 a1, b1 = _arg_0.a, _arg_0.b
216 if a1 == nil then
217 a1 = 100
218 end
219 if b1 == nil then
220 b1 = a1 + 1000
221 end
222 return a1 + b1
223 end
224 local result = f({ })
225 return assert.same(result, 1200)
226 end)
227 it("should support deep nesting", function()
228 local f
229 f = function(_arg_0)
230 local value
231 value = _arg_0.data.nested.value
232 return value
233 end
234 local result = f({
235 data = {
236 nested = {
237 value = 42
238 }
239 }
240 })
241 return assert.same(result, 42)
242 end)
243 it("should work with multiple parameters", function()
244 local f
245 f = function(_arg_0, extra)
246 local x, y, z
247 x, y, z = _arg_0.x, _arg_0.y, _arg_0.z
248 if extra == nil then
249 extra = "default"
250 end
251 return {
252 x,
253 y,
254 z,
255 extra
256 }
257 end
258 local result = f({
259 x = 1,
260 y = 2,
261 z = 3
262 })
263 return assert.same(result, {
264 1,
265 2,
266 3,
267 'default'
268 })
269 end)
270 it("should handle array destructuring in parameters", function()
271 local f
272 f = function(_arg_0)
273 local first, rest
274 first, rest = _arg_0[1], _anon_func_0(_arg_0)
275 return {
276 first,
277 rest
278 }
279 end
280 local result = f({
281 1,
282 2,
283 3,
284 4
285 })
286 return assert.same(result, {
287 1,
288 {
289 2,
290 3,
291 4
292 }
293 })
294 end)
295 it("should support spreading", function()
296 local f
297 f = function(_arg_0)
298 local rest, last
299 rest, last = _anon_func_1(_arg_0), _arg_0.last
300 return {
301 rest,
302 last
303 }
304 end
305 local result = f({
306 1,
307 2,
308 3,
309 last = "final"
310 })
311 return assert.same(result, {
312 {
313 1,
314 2,
315 3
316 },
317 'final'
318 })
319 end)
320 it("should work with table comprehensions", function()
321 local f
322 f = function(_arg_0)
323 local items
324 items = _arg_0.items
325 local _accum_0 = { }
326 local _len_0 = 1
327 for _index_0 = 1, #items do
328 local item = items[_index_0]
329 _accum_0[_len_0] = item * 2
330 _len_0 = _len_0 + 1
331 end
332 return _accum_0
333 end
334 local result = f({
335 items = {
336 1,
337 2,
338 3
339 }
340 })
341 return assert.same(result, {
342 2,
343 4,
344 6
345 })
346 end)
347 return it("should handle nil arguments", function()
348 local f
349 f = function(_arg_0)
350 local a, b
351 a, b = _arg_0.a, _arg_0.b
352 if a == nil then
353 a = "nil_a"
354 end
355 if b == nil then
356 b = "nil_b"
357 end
358 return {
359 a,
360 b
361 }
362 end
363 local result = f({ })
364 return assert.same(result, {
365 "nil_a",
366 "nil_b"
367 })
368 end)
369end)
diff --git a/spec/outputs/test/reverse_index_spec.lua b/spec/outputs/test/reverse_index_spec.lua
index 396c3b9..b1d2359 100644
--- a/spec/outputs/test/reverse_index_spec.lua
+++ b/spec/outputs/test/reverse_index_spec.lua
@@ -116,10 +116,6 @@ return describe("reverse index", function()
116 end 116 end
117 return assert.same(last, 3) 117 return assert.same(last, 3)
118 end) 118 end)
119 it("should work with string", function()
120 local s = "hello"
121 return assert.same(s[#s], "o")
122 end)
123 it("should handle negative offsets", function() 119 it("should handle negative offsets", function()
124 local tab = { 120 local tab = {
125 1, 121 1,
diff --git a/spec/outputs/test/slicing_spec.lua b/spec/outputs/test/slicing_spec.lua
new file mode 100644
index 0000000..1db2938
--- /dev/null
+++ b/spec/outputs/test/slicing_spec.lua
@@ -0,0 +1,324 @@
1return describe("slicing", function()
2 it("should slice array with basic syntax", function()
3 local items = {
4 1,
5 2,
6 3,
7 4,
8 5
9 }
10 local result
11 do
12 local _accum_0 = { }
13 local _len_0 = 1
14 for _index_0 = 1, 3 do
15 local _item_0 = items[_index_0]
16 _accum_0[_len_0] = _item_0
17 _len_0 = _len_0 + 1
18 end
19 result = _accum_0
20 end
21 return assert.same(result, {
22 1,
23 2,
24 3
25 })
26 end)
27 it("should slice from beginning", function()
28 local items = {
29 1,
30 2,
31 3,
32 4,
33 5
34 }
35 local result
36 do
37 local _accum_0 = { }
38 local _len_0 = 1
39 local _max_0 = #items
40 _max_0 = _max_0 < 0 and #items + _max_0 + 1 or _max_0
41 for _index_0 = 1, _max_0 do
42 local _item_0 = items[_index_0]
43 _accum_0[_len_0] = _item_0
44 _len_0 = _len_0 + 1
45 end
46 result = _accum_0
47 end
48 return assert.same(result, {
49 1,
50 2,
51 3,
52 4,
53 5
54 })
55 end)
56 it("should slice to end", function()
57 local items = {
58 1,
59 2,
60 3,
61 4,
62 5
63 }
64 local result
65 do
66 local _accum_0 = { }
67 local _len_0 = 1
68 for _index_0 = 3, 5 do
69 local _item_0 = items[_index_0]
70 _accum_0[_len_0] = _item_0
71 _len_0 = _len_0 + 1
72 end
73 result = _accum_0
74 end
75 return assert.same(result, {
76 3,
77 4,
78 5
79 })
80 end)
81 it("should handle negative indices", function()
82 local items = {
83 1,
84 2,
85 3,
86 4,
87 5
88 }
89 local result
90 do
91 local _accum_0 = { }
92 local _len_0 = 1
93 local _min_0 = #items + -3 + 1
94 local _max_0 = #items + -1 + 1
95 for _index_0 = _min_0, _max_0 do
96 local _item_0 = items[_index_0]
97 _accum_0[_len_0] = _item_0
98 _len_0 = _len_0 + 1
99 end
100 result = _accum_0
101 end
102 return assert.same(result, {
103 3,
104 4,
105 5
106 })
107 end)
108 it("should slice single element", function()
109 local items = {
110 1,
111 2,
112 3,
113 4,
114 5
115 }
116 local result
117 do
118 local _accum_0 = { }
119 local _len_0 = 1
120 for _index_0 = 2, 2 do
121 local _item_0 = items[_index_0]
122 _accum_0[_len_0] = _item_0
123 _len_0 = _len_0 + 1
124 end
125 result = _accum_0
126 end
127 return assert.same(result, {
128 2
129 })
130 end)
131 it("should work with strings", function()
132 local s = "hello"
133 local result = s:sub(1, 3)
134 return assert.same(result, "hel")
135 end)
136 it("should handle out of bounds", function()
137 local items = {
138 1,
139 2,
140 3
141 }
142 local result
143 do
144 local _accum_0 = { }
145 local _len_0 = 1
146 for _index_0 = 1, 10 do
147 local _item_0 = items[_index_0]
148 _accum_0[_len_0] = _item_0
149 _len_0 = _len_0 + 1
150 end
151 result = _accum_0
152 end
153 return assert.same(result, {
154 1,
155 2,
156 3
157 })
158 end)
159 it("should create new table", function()
160 local original = {
161 1,
162 2,
163 3,
164 4,
165 5
166 }
167 local sliced
168 do
169 local _accum_0 = { }
170 local _len_0 = 1
171 for _index_0 = 2, 4 do
172 local _item_0 = original[_index_0]
173 _accum_0[_len_0] = _item_0
174 _len_0 = _len_0 + 1
175 end
176 sliced = _accum_0
177 end
178 sliced[1] = 99
179 return assert.same(original[2], 2)
180 end)
181 it("should work with nested arrays", function()
182 local nested = {
183 {
184 1,
185 2
186 },
187 {
188 3,
189 4
190 },
191 {
192 5,
193 6
194 }
195 }
196 local result
197 do
198 local _accum_0 = { }
199 local _len_0 = 1
200 for _index_0 = 1, 2 do
201 local _item_0 = nested[_index_0]
202 _accum_0[_len_0] = _item_0
203 _len_0 = _len_0 + 1
204 end
205 result = _accum_0
206 end
207 return assert.same(result, {
208 {
209 1,
210 2
211 },
212 {
213 3,
214 4
215 }
216 })
217 end)
218 it("should slice with step simulation", function()
219 local items = {
220 1,
221 2,
222 3,
223 4,
224 5
225 }
226 local result
227 do
228 local _accum_0 = { }
229 local _len_0 = 1
230 for i = 1, #items, 2 do
231 _accum_0[_len_0] = items[i]
232 _len_0 = _len_0 + 1
233 end
234 result = _accum_0
235 end
236 return assert.same(result, {
237 1,
238 3,
239 5
240 })
241 end)
242 it("should handle empty slice range", function()
243 local items = {
244 1,
245 2,
246 3,
247 4,
248 5
249 }
250 local result
251 do
252 local _accum_0 = { }
253 local _len_0 = 1
254 for _index_0 = 6, 10 do
255 local _item_0 = items[_index_0]
256 _accum_0[_len_0] = _item_0
257 _len_0 = _len_0 + 1
258 end
259 result = _accum_0
260 end
261 return assert.same(result, { })
262 end)
263 it("should work with reverse indexing", function()
264 local items = {
265 1,
266 2,
267 3,
268 4,
269 5
270 }
271 local last = items[#items]
272 local second_last = items[#items - 1]
273 assert.same(last, 5)
274 return assert.same(second_last, 4)
275 end)
276 it("should support slice in assignment", function()
277 local items = {
278 1,
279 2,
280 3,
281 4,
282 5
283 }
284 local a, b, c
285 do
286 local _accum_0 = { }
287 local _len_0 = 1
288 local _list_0 = {
289 1,
290 2,
291 3
292 }
293 for _index_0 = 1, #_list_0 do
294 local i = _list_0[_index_0]
295 _accum_0[_len_0] = items[i]
296 _len_0 = _len_0 + 1
297 end
298 a, b, c = _accum_0[1], _accum_0[2], _accum_0[3]
299 end
300 assert.same(a, 1)
301 assert.same(b, 2)
302 return assert.same(c, 3)
303 end)
304 return it("should work with table comprehensions", function()
305 local items = {
306 1,
307 2,
308 3,
309 4,
310 5
311 }
312 local result
313 do
314 local _tbl_0 = { }
315 for i = 2, 4 do
316 _tbl_0[i] = items[i]
317 end
318 result = _tbl_0
319 end
320 assert.same(result[2], 2)
321 assert.same(result[3], 3)
322 return assert.same(result[4], 4)
323 end)
324end)
diff --git a/spec/outputs/test/stub_spec.lua b/spec/outputs/test/stub_spec.lua
new file mode 100644
index 0000000..0daf5b6
--- /dev/null
+++ b/spec/outputs/test/stub_spec.lua
@@ -0,0 +1,148 @@
1local stub_fn
2stub_fn = function()
3 return function() end
4end
5local _anon_func_0 = function(stub_fn)
6 stub_fn()
7 return true
8end
9return describe("function stub", function()
10 it("should create empty function", function()
11 stub_fn()
12 return assert.is_true(true)
13 end)
14 it("should support stub in table", function()
15 local obj = {
16 stub = stub_fn()
17 }
18 return assert.is_true(true)
19 end)
20 it("should work with method stub", function()
21 local obj = {
22 method = stub_fn()
23 }
24 return assert.is_true(true)
25 end)
26 it("should handle stub in assignment", function()
27 local my_func = stub_fn()
28 return assert.is_true(true)
29 end)
30 it("should support stub in return", function()
31 local get_stub
32 get_stub = function()
33 return stub_fn()
34 end
35 local fn = get_stub()
36 return assert.is_true(true)
37 end)
38 it("should work in conditional", function()
39 if stub_fn() then
40 return assert.is_true(true)
41 end
42 end)
43 it("should support stub as callback", function()
44 local call_fn
45 call_fn = function(fn)
46 return fn()
47 end
48 local result = call_fn(stub_fn())
49 return assert.is_true(true)
50 end)
51 it("should handle stub in table literal", function()
52 local tb = {
53 on_click = stub_fn(),
54 on_hover = stub_fn()
55 }
56 return assert.is_true(true)
57 end)
58 it("should work with fat arrow stub", function()
59 local obj = {
60 value = 10,
61 method = stub_fn()
62 }
63 local result = obj:method()
64 return assert.is_true(true)
65 end)
66 it("should support stub in array", function()
67 local callbacks = {
68 stub_fn(),
69 stub_fn(),
70 stub_fn()
71 }
72 return assert.same(#callbacks, 3)
73 end)
74 it("should handle stub in expression", function()
75 local result = stub_fn() and true or false
76 return assert.is_true(result)
77 end)
78 it("should work with chained stub calls", function()
79 stub_fn()
80 stub_fn()
81 stub_fn()
82 return assert.is_true(true)
83 end)
84 it("should support stub in comprehension", function()
85 local result
86 do
87 local _accum_0 = { }
88 local _len_0 = 1
89 for i = 1, 3 do
90 _accum_0[_len_0] = stub_fn()
91 _len_0 = _len_0 + 1
92 end
93 result = _accum_0
94 end
95 return assert.same(#result, 3)
96 end)
97 it("should handle stub in switch", function()
98 local value = "test"
99 local result
100 if "test" == value then
101 stub_fn()
102 result = "matched"
103 else
104 result = "not matched"
105 end
106 return assert.same(result, "matched")
107 end)
108 it("should work in with statement", function()
109 local obj = {
110 stub = stub_fn()
111 }
112 obj.stub()
113 return assert.is_true(true)
114 end)
115 it("should support stub as argument default", function()
116 local fn
117 fn = function(callback)
118 if callback == nil then
119 callback = stub_fn()
120 end
121 return callback()
122 end
123 local result = fn()
124 return assert.is_true(true)
125 end)
126 it("should handle stub in varargs", function()
127 local collect
128 collect = function(...)
129 return {
130 ...
131 }
132 end
133 local result = collect(stub_fn(), stub_fn())
134 return assert.same(#result, 2)
135 end)
136 it("should work in do block", function()
137 do
138 stub_fn()
139 end
140 return assert.is_true(true)
141 end)
142 return it("should support stub in try block", function()
143 local success = xpcall(_anon_func_0, function(err)
144 return false
145 end, stub_fn)
146 return assert.is_true(success)
147 end)
148end)
diff --git a/spec/outputs/test/table_append_spec.lua b/spec/outputs/test/table_append_spec.lua
index 5ce1156..4705161 100644
--- a/spec/outputs/test/table_append_spec.lua
+++ b/spec/outputs/test/table_append_spec.lua
@@ -72,12 +72,12 @@ return describe("table append", function()
72 2 72 2
73 }) 73 })
74 end) 74 end)
75 it("should append nil values", function() 75 it("should not append nil values", function()
76 local tab = { } 76 local tab = { }
77 tab[#tab + 1] = nil 77 tab[#tab + 1] = nil
78 tab[#tab + 1] = "value" 78 tab[#tab + 1] = "value"
79 assert.same(tab[1], nil) 79 assert.same(tab[2], nil)
80 return assert.same(tab[2], "value") 80 return assert.same(tab[1], "value")
81 end) 81 end)
82 it("should work in loop", function() 82 it("should work in loop", function()
83 local tab = { } 83 local tab = { }
@@ -150,7 +150,14 @@ return describe("table append", function()
150 return 1, 2, 3 150 return 1, 2, 3
151 end 151 end
152 local tab = { } 152 local tab = { }
153 tab[#tab + 1] = fn() 153 local _len_0 = #tab + 1
154 local _list_0 = {
155 fn()
156 }
157 for _index_0 = 1, #_list_0 do
158 local _elm_0 = _list_0[_index_0]
159 tab[_len_0], _len_0 = _elm_0, _len_0 + 1
160 end
154 return assert.same(tab, { 161 return assert.same(tab, {
155 1, 162 1,
156 2, 163 2,
diff --git a/spec/outputs/test/table_comprehension_spec.lua b/spec/outputs/test/table_comprehension_spec.lua
new file mode 100644
index 0000000..90fa647
--- /dev/null
+++ b/spec/outputs/test/table_comprehension_spec.lua
@@ -0,0 +1,297 @@
1return describe("table comprehension", function()
2 it("should create simple table copy", function()
3 local thing = {
4 color = "red",
5 name = "fast",
6 width = 123
7 }
8 local thing_copy
9 do
10 local _tbl_0 = { }
11 for k, v in pairs(thing) do
12 _tbl_0[k] = v
13 end
14 thing_copy = _tbl_0
15 end
16 assert.same(thing_copy.color, thing.color)
17 assert.same(thing_copy.name, thing.name)
18 return assert.same(thing_copy.width, thing.width)
19 end)
20 it("should filter with when clause", function()
21 local thing = {
22 color = "red",
23 name = "fast",
24 width = 123
25 }
26 local no_color
27 do
28 local _tbl_0 = { }
29 for k, v in pairs(thing) do
30 if k ~= "color" then
31 _tbl_0[k] = v
32 end
33 end
34 no_color = _tbl_0
35 end
36 assert.same(no_color.color, nil)
37 assert.same(no_color.name, "fast")
38 return assert.same(no_color.width, 123)
39 end)
40 it("should transform values", function()
41 local numbers = {
42 a = 1,
43 b = 2,
44 c = 3
45 }
46 local doubled
47 do
48 local _tbl_0 = { }
49 for k, v in pairs(numbers) do
50 _tbl_0[k] = v * 2
51 end
52 doubled = _tbl_0
53 end
54 assert.same(doubled.a, 2)
55 assert.same(doubled.b, 4)
56 return assert.same(doubled.c, 6)
57 end)
58 it("should transform keys", function()
59 local data = {
60 a = 1,
61 b = 2
62 }
63 local upper_keys
64 do
65 local _tbl_0 = { }
66 for k, v in pairs(data) do
67 _tbl_0[k:upper()] = v
68 end
69 upper_keys = _tbl_0
70 end
71 assert.same(upper_keys.A, 1)
72 return assert.same(upper_keys.B, 2)
73 end)
74 it("should work with ipairs", function()
75 local items = {
76 "a",
77 "b",
78 "c"
79 }
80 local reversed
81 do
82 local _tbl_0 = { }
83 for i, v in ipairs(items) do
84 _tbl_0[i] = v
85 end
86 reversed = _tbl_0
87 end
88 assert.same(reversed[1], "a")
89 assert.same(reversed[2], "b")
90 return assert.same(reversed[3], "c")
91 end)
92 it("should filter array items", function()
93 local items = {
94 1,
95 2,
96 3,
97 4,
98 5
99 }
100 local evens
101 do
102 local _tbl_0 = { }
103 for i, v in ipairs(items) do
104 if v % 2 == 0 then
105 _tbl_0[i] = v
106 end
107 end
108 evens = _tbl_0
109 end
110 assert.same(evens[2], 2)
111 assert.same(evens[4], 4)
112 return assert.same(evens[1], nil)
113 end)
114 it("should work with numeric for loop", function()
115 local squares
116 do
117 local _tbl_0 = { }
118 for i = 1, 5 do
119 _tbl_0[i] = i * i
120 end
121 squares = _tbl_0
122 end
123 assert.same(squares[1], 1)
124 assert.same(squares[2], 4)
125 assert.same(squares[3], 9)
126 assert.same(squares[4], 16)
127 return assert.same(squares[5], 25)
128 end)
129 it("should support nested comprehensions", function()
130 local matrix = {
131 {
132 1,
133 2
134 },
135 {
136 3,
137 4
138 },
139 {
140 5,
141 6
142 }
143 }
144 local flat = { }
145 for _index_0 = 1, #matrix do
146 local row = matrix[_index_0]
147 for i, v in ipairs(row) do
148 flat[#flat + 1] = v
149 end
150 end
151 return assert.same(flat, {
152 1,
153 2,
154 3,
155 4,
156 5,
157 6
158 })
159 end)
160 it("should combine pairs and when", function()
161 local data = {
162 a = 1,
163 b = 2,
164 c = 3,
165 d = 4
166 }
167 local greater_than_two
168 do
169 local _tbl_0 = { }
170 for k, v in pairs(data) do
171 if v > 2 then
172 _tbl_0[k] = v
173 end
174 end
175 greater_than_two = _tbl_0
176 end
177 assert.same(greater_than_two.a, nil)
178 assert.same(greater_than_two.b, nil)
179 assert.same(greater_than_two.c, 3)
180 return assert.same(greater_than_two.d, 4)
181 end)
182 it("should work with string keys", function()
183 local obj = {
184 ["key-with-dash"] = "value1",
185 ["key_with_underscore"] = "value2"
186 }
187 local result
188 do
189 local _tbl_0 = { }
190 for k, v in pairs(obj) do
191 _tbl_0[k] = v
192 end
193 result = _tbl_0
194 end
195 assert.same(result["key-with-dash"], "value1")
196 return assert.same(result["key_with_underscore"], "value2")
197 end)
198 it("should handle empty source", function()
199 local empty = { }
200 local result
201 do
202 local _tbl_0 = { }
203 for k, v in pairs(empty) do
204 _tbl_0[k] = v
205 end
206 result = _tbl_0
207 end
208 return assert.same(#result, 0)
209 end)
210 it("should work with computed keys", function()
211 local base = {
212 a = 1,
213 b = 2
214 }
215 local result
216 do
217 local _tbl_0 = { }
218 for k, v in pairs(base) do
219 _tbl_0[k .. "_suffix"] = v * 10
220 end
221 result = _tbl_0
222 end
223 assert.same(result.a_suffix, 10)
224 return assert.same(result.b_suffix, 20)
225 end)
226 it("should support nested table transformation", function()
227 local data = {
228 first = {
229 x = 1,
230 y = 2
231 },
232 second = {
233 x = 3,
234 y = 4
235 }
236 }
237 local transformed
238 do
239 local _tbl_0 = { }
240 for k, v in pairs(data) do
241 _tbl_0[k] = v.x + v.y
242 end
243 transformed = _tbl_0
244 end
245 assert.same(transformed.first, 3)
246 return assert.same(transformed.second, 7)
247 end)
248 it("should filter with multiple conditions", function()
249 local numbers = {
250 a = 1,
251 b = 2,
252 c = 3,
253 d = 4,
254 e = 5
255 }
256 local result
257 do
258 local _tbl_0 = { }
259 for k, v in pairs(numbers) do
260 if v > 1 and v < 5 then
261 _tbl_0[k] = v
262 end
263 end
264 result = _tbl_0
265 end
266 assert.same(result.a, nil)
267 assert.same(result.b, 2)
268 assert.same(result.c, 3)
269 assert.same(result.d, 4)
270 return assert.same(result.e, nil)
271 end)
272 return it("should work with custom iterator", function()
273 local custom_iter
274 custom_iter = function()
275 local state = 0
276 return function()
277 state = state + 1
278 if state <= 3 then
279 return state, state * 10
280 else
281 return nil
282 end
283 end
284 end
285 local result
286 do
287 local _tbl_0 = { }
288 for k, v in custom_iter() do
289 _tbl_0[k] = v
290 end
291 result = _tbl_0
292 end
293 assert.same(result[1], 10)
294 assert.same(result[2], 20)
295 return assert.same(result[3], 30)
296 end)
297end)
diff --git a/spec/outputs/test/tables_advanced_spec.lua b/spec/outputs/test/tables_advanced_spec.lua
new file mode 100644
index 0000000..de36953
--- /dev/null
+++ b/spec/outputs/test/tables_advanced_spec.lua
@@ -0,0 +1,260 @@
1return describe("advanced tables", function()
2 it("should create table with implicit keys", function()
3 local hair = "golden"
4 local height = 200
5 local person = {
6 hair = hair,
7 height = height,
8 shoe_size = 40
9 }
10 assert.same(person.hair, "golden")
11 return assert.same(person.height, 200)
12 end)
13 it("should work with computed keys", function()
14 local t = {
15 [1 + 2] = "hello",
16 ["key_" .. "suffix"] = "value"
17 }
18 assert.same(t[3], "hello")
19 return assert.same(t["key_suffix"], "value")
20 end)
21 it("should support keyword keys", function()
22 local tbl = {
23 ["do"] = "something",
24 ["end"] = "hunger",
25 ["function"] = "test"
26 }
27 assert.same(tbl["do"], "something")
28 assert.same(tbl["end"], "hunger")
29 return assert.same(tbl["function"], "test")
30 end)
31 it("should handle array syntax with mixed content", function()
32 local tb = {
33 1,
34 2,
35 3,
36 name = "superman",
37 4,
38 5,
39 6
40 }
41 assert.same(tb[1], 1)
42 assert.same(tb.name, "superman")
43 return assert.same(tb[4], 4)
44 end)
45 it("should work with single line table literals", function()
46 local tb = {
47 dance = "Tango",
48 partner = "none"
49 }
50 assert.same(tb.dance, "Tango")
51 return assert.same(tb.partner, "none")
52 end)
53 it("should support nested tables", function()
54 local tb = {
55 outer = {
56 inner = {
57 value = 42
58 }
59 }
60 }
61 return assert.same(tb.outer.inner.value, 42)
62 end)
63 it("should handle table without braces", function()
64 local profile = {
65 height = "4 feet",
66 shoe_size = 13,
67 favorite_foods = {
68 "ice cream",
69 "donuts"
70 }
71 }
72 assert.same(profile.height, "4 feet")
73 return assert.same(profile.shoe_size, 13)
74 end)
75 it("should work with colon syntax for keys", function()
76 local t = {
77 name = "Bill",
78 age = 200,
79 ["favorite food"] = "rice"
80 }
81 assert.same(t.name, "Bill")
82 return assert.same(t["favorite food"], "rice")
83 end)
84 it("should support implicit object in table", function()
85 local tb = {
86 name = "abc",
87 values = {
88 "a",
89 "b",
90 "c"
91 }
92 }
93 return assert.same(tb.values, {
94 "a",
95 "b",
96 "c"
97 })
98 end)
99 it("should handle array only table", function()
100 local some_values = {
101 1,
102 2,
103 3,
104 4
105 }
106 assert.same(some_values[1], 1)
107 return assert.same(some_values[4], 4)
108 end)
109 it("should work with trailing comma", function()
110 local list_with_one = {
111 1
112 }
113 return assert.same(list_with_one[1], 1)
114 end)
115 it("should support table spreading", function()
116 local a = {
117 1,
118 2,
119 3,
120 x = 1
121 }
122 local b = {
123 4,
124 5,
125 y = 1
126 }
127 local merge
128 do
129 local _tab_0 = { }
130 local _idx_0 = 1
131 for _key_0, _value_0 in pairs(a) do
132 if _idx_0 == _key_0 then
133 _tab_0[#_tab_0 + 1] = _value_0
134 _idx_0 = _idx_0 + 1
135 else
136 _tab_0[_key_0] = _value_0
137 end
138 end
139 local _idx_1 = 1
140 for _key_0, _value_0 in pairs(b) do
141 if _idx_1 == _key_0 then
142 _tab_0[#_tab_0 + 1] = _value_0
143 _idx_1 = _idx_1 + 1
144 else
145 _tab_0[_key_0] = _value_0
146 end
147 end
148 merge = _tab_0
149 end
150 assert.same(merge[1], 1)
151 assert.same(merge[4], 4)
152 assert.same(merge.x, 1)
153 return assert.same(merge.y, 1)
154 end)
155 it("should handle mixed spread", function()
156 local parts = {
157 "shoulders",
158 "knees"
159 }
160 local lyrics
161 do
162 local _tab_0 = {
163 "head"
164 }
165 local _idx_0 = 1
166 for _key_0, _value_0 in pairs(parts) do
167 if _idx_0 == _key_0 then
168 _tab_0[#_tab_0 + 1] = _value_0
169 _idx_0 = _idx_0 + 1
170 else
171 _tab_0[_key_0] = _value_0
172 end
173 end
174 _tab_0[#_tab_0 + 1] = "and"
175 _tab_0[#_tab_0 + 1] = "toes"
176 lyrics = _tab_0
177 end
178 return assert.same(lyrics, {
179 "head",
180 "shoulders",
181 "knees",
182 "and",
183 "toes"
184 })
185 end)
186 it("should work with metatable creation", function()
187 local mt = { }
188 local add
189 add = function(self, right)
190 return setmetatable({
191 value = self.value + right.value
192 }, mt)
193 end
194 mt.__add = add
195 local a = setmetatable({
196 value = 1
197 }, mt)
198 local b = {
199 value = 2
200 }
201 setmetatable(b, mt)
202 local c = a + b
203 return assert.same(c.value, 3)
204 end)
205 it("should support metatable accessing", function()
206 local tb = setmetatable({ }, {
207 ["value"] = 123
208 })
209 getmetatable(tb).__index = getmetatable(tb)
210 return assert.same(tb.value, 123)
211 end)
212 it("should handle metatable destructuring", function()
213 local tb = setmetatable({
214 item = "test",
215 new = function()
216 return "created"
217 end,
218 }, {
219 __close = function()
220 return "closed"
221 end
222 })
223 local item, new = tb.item, tb.new
224 local close = getmetatable(tb).__close
225 assert.same(item, "test")
226 assert.same(new(), "created")
227 return assert.same(close(), "closed")
228 end)
229 it("should work with string keys directly", function()
230 local t = {
231 ["hello world"] = true,
232 ["test-key"] = "value"
233 }
234 assert.is_true(t["hello world"])
235 return assert.same(t["test-key"], "value")
236 end)
237 it("should support number keys", function()
238 local t = {
239 [10] = "ten",
240 [20] = "twenty"
241 }
242 assert.same(t[10], "ten")
243 return assert.same(t[20], "twenty")
244 end)
245 it("should handle empty tables", function()
246 local empty = { }
247 return assert.same(#empty, 0)
248 end)
249 return it("should work with table literals in function calls", function()
250 local fn
251 fn = function(tb)
252 return tb.x + tb.y
253 end
254 local result = fn({
255 x = 10,
256 y = 20
257 })
258 return assert.same(result, 30)
259 end)
260end)
diff --git a/spec/outputs/test/varargs_assignment_spec.lua b/spec/outputs/test/varargs_assignment_spec.lua
index 60eab29..4d41404 100644
--- a/spec/outputs/test/varargs_assignment_spec.lua
+++ b/spec/outputs/test/varargs_assignment_spec.lua
@@ -119,9 +119,9 @@ return describe("varargs assignment", function()
119 end) 119 end)
120 it("should work with table.unpack", function() 120 it("should work with table.unpack", function()
121 local tb = { 121 local tb = {
122 a = 1, 122 1,
123 b = 2, 123 2,
124 c = 3 124 3
125 } 125 }
126 local fn 126 local fn
127 fn = function() 127 fn = function()
diff --git a/spec/outputs/test/whitespace_spec.lua b/spec/outputs/test/whitespace_spec.lua
new file mode 100644
index 0000000..ca9116e
--- /dev/null
+++ b/spec/outputs/test/whitespace_spec.lua
@@ -0,0 +1,159 @@
1return describe("whitespace", function()
2 it("should support semicolon statement separator", function()
3 local a = 1
4 local b = 2
5 local result = a + b
6 return assert.same(result, 3)
7 end)
8 it("should handle multiple statements on one line", function()
9 local x = 10
10 local y = 20
11 local z = x + y
12 return assert.same(z, 30)
13 end)
14 it("should work with semicolon in function", function()
15 local fn
16 fn = function()
17 local a = 1
18 local b = 2
19 return a + b
20 end
21 return assert.same(fn(), 3)
22 end)
23 it("should support multiline chaining", function()
24 local obj = {
25 value = 10,
26 add = function(self, n)
27 self.value = self.value + n
28 return self
29 end,
30 get = function(self)
31 return self.value
32 end
33 }
34 local result = obj:add(5):add(10):get()
35 return assert.same(result, 25)
36 end)
37 it("should handle multiline method calls", function()
38 local str = " hello "
39 local result = str:match("^%s*(.-)%s*$"):upper()
40 return assert.same(result, "HELLO")
41 end)
42 it("should work with nested chaining", function()
43 local obj = {
44 level1 = {
45 level2 = {
46 level3 = function(self)
47 return "deep"
48 end
49 }
50 }
51 }
52 local result = obj.level1.level2:level3()
53 return assert.same(result, "deep")
54 end)
55 it("should support chaining with conditionals", function()
56 local obj = {
57 value = 10,
58 isPositive = function(self)
59 return self.value > 0
60 end
61 }
62 local result = obj:isPositive()
63 return assert.is_true(result)
64 end)
65 it("should work with pipe in chaining", function()
66 local result = table.concat((function(tb)
67 local _accum_0 = { }
68 local _len_0 = 1
69 for _index_0 = 1, #tb do
70 local x = tb[_index_0]
71 _accum_0[_len_0] = x * 2
72 _len_0 = _len_0 + 1
73 end
74 return _accum_0
75 end)({
76 1,
77 2,
78 3
79 }))
80 return assert.same(result, "246")
81 end)
82 it("should handle mixed separators", function()
83 local a = 1
84 local b = 2
85 local c = 3
86 local d = 4
87 local result = a + b + c + d
88 return assert.same(result, 10)
89 end)
90 it("should support indentation with spaces", function()
91 local fn
92 fn = function()
93 if true then
94 local result = 10
95 return result
96 end
97 end
98 return assert.same(fn(), 10)
99 end)
100 it("should work with consistent indentation", function()
101 local tb = {
102 a = 1,
103 b = 2,
104 nested = {
105 c = 3,
106 d = 4
107 }
108 }
109 assert.same(tb.a, 1)
110 return assert.same(tb.nested.c, 3)
111 end)
112 it("should handle semicolon with comments", function()
113 local a = 1
114 local b = 2
115 local result = a + b
116 return assert.same(result, 3)
117 end)
118 it("should work in multiline function call", function()
119 local sum
120 sum = function(a, b)
121 return a + b
122 end
123 local result = sum(5, sum(10, sum(3, 7)))
124 return assert.same(result, 25)
125 end)
126 it("should support chaining in assignment", function()
127 local obj = {
128 value = 5,
129 double = function(self)
130 return self.value * 2
131 end
132 }
133 local doubled = obj:double()
134 return assert.same(doubled, 10)
135 end)
136 it("should handle complex chaining", function()
137 local result = ("hello"):upper():sub(1, 3):lower()
138 return assert.same(result, "hel")
139 end)
140 return it("should work with backcalls and whitespace", function()
141 local readAsync
142 readAsync = function(file, callback)
143 return callback("data")
144 end
145 local process
146 process = function(data)
147 if data then
148 return true
149 end
150 end
151 local results
152 do
153 results = readAsync("data.txt", function(data)
154 return process(data)
155 end)
156 end
157 return assert.is_true(true)
158 end)
159end)
diff --git a/spec/outputs/test/with_statement_spec.lua b/spec/outputs/test/with_statement_spec.lua
new file mode 100644
index 0000000..dcd2aa1
--- /dev/null
+++ b/spec/outputs/test/with_statement_spec.lua
@@ -0,0 +1,279 @@
1return describe("with statement", function()
2 it("should access properties with dot", function()
3 local obj = {
4 x = 10,
5 y = 20
6 }
7 local result = nil
8 do
9 result = obj.x + obj.y
10 end
11 return assert.same(result, 30)
12 end)
13 it("should chain property access", function()
14 local obj = {
15 nested = {
16 value = 42
17 }
18 }
19 local result = nil
20 do
21 result = obj.nested.value
22 end
23 return assert.same(result, 42)
24 end)
25 it("should work with method calls", function()
26 local obj = {
27 value = 10,
28 double = function(self)
29 return self.value * 2
30 end
31 }
32 local result = nil
33 do
34 result = obj:double()
35 end
36 return assert.same(result, 20)
37 end)
38 it("should handle nested with statements", function()
39 local obj = {
40 x = 1
41 }
42 obj.x = 10
43 local _with_0 = {
44 y = 2
45 }
46 obj.nested = _with_0
47 _with_0.y = 20
48 assert.same(obj.x, 10)
49 return assert.same(obj.nested.y, 20)
50 end)
51 it("should work in expressions", function()
52 local obj = {
53 value = 5
54 }
55 local result
56 do
57 local _accum_0
58 repeat
59 _accum_0 = obj.value * 2
60 break
61 until true
62 result = _accum_0
63 end
64 return assert.same(result, 10)
65 end)
66 it("should support multiple statements", function()
67 local obj = {
68 a = 1,
69 b = 2
70 }
71 local sum = nil
72 local product = nil
73 do
74 sum = obj.a + obj.b
75 product = obj.a * obj.b
76 end
77 assert.same(sum, 3)
78 return assert.same(product, 2)
79 end)
80 it("should work with table manipulation", function()
81 local obj = {
82 items = {
83 1,
84 2,
85 3
86 }
87 }
88 table.insert(obj.items, 4)
89 return assert.same(#obj.items, 4)
90 end)
91 it("should handle conditional inside with", function()
92 local obj = {
93 value = 10
94 }
95 local result = nil
96 if obj.value > 5 then
97 result = "large"
98 else
99 result = "small"
100 end
101 return assert.same(result, "large")
102 end)
103 it("should work with loops", function()
104 local obj = {
105 items = {
106 1,
107 2,
108 3
109 }
110 }
111 local sum = nil
112 do
113 sum = 0
114 local _list_0 = obj.items
115 for _index_0 = 1, #_list_0 do
116 local item = _list_0[_index_0]
117 sum = sum + item
118 end
119 end
120 return assert.same(sum, 6)
121 end)
122 it("should support with in assignment", function()
123 local obj = {
124 x = 5,
125 y = 10
126 }
127 local result
128 do
129 local _accum_0
130 repeat
131 _accum_0 = obj.x + obj.y
132 break
133 until true
134 result = _accum_0
135 end
136 return assert.same(result, 15)
137 end)
138 it("should work with string methods", function()
139 local s = "hello"
140 local result
141 do
142 local _accum_0
143 repeat
144 _accum_0 = s:upper()
145 break
146 until true
147 result = _accum_0
148 end
149 return assert.same(result, "HELLO")
150 end)
151 it("should handle metatable access", function()
152 local obj = setmetatable({
153 value = 10
154 }, {
155 __index = {
156 extra = 5
157 }
158 })
159 local sum = nil
160 do
161 sum = obj.value + getmetatable(obj).__index.extra
162 end
163 return assert.same(sum, 15)
164 end)
165 it("should work in function", function()
166 local fn
167 fn = function()
168 local obj = {
169 x = 10
170 }
171 local _val_0
172 local _accum_0
173 repeat
174 _accum_0 = obj.x * 2
175 break
176 until true
177 _val_0 = _accum_0
178 return _val_0
179 end
180 local result = fn()
181 return assert.same(result, 20)
182 end)
183 it("should support with in return", function()
184 local get_value
185 get_value = function()
186 local obj = {
187 value = 42
188 }
189 local _val_0
190 local _accum_0
191 repeat
192 _accum_0 = obj.value
193 break
194 until true
195 _val_0 = _accum_0
196 return _val_0
197 end
198 return assert.same(get_value(), 42)
199 end)
200 it("should work with existential operator", function()
201 local obj = {
202 value = 10
203 }
204 local result
205 do
206 local _accum_0
207 repeat
208 local _exp_0 = obj.value
209 if _exp_0 ~= nil then
210 _accum_0 = _exp_0
211 else
212 _accum_0 = 0
213 end
214 break
215 until true
216 result = _accum_0
217 end
218 return assert.same(result, 10)
219 end)
220 it("should handle nil object safely", function()
221 local result
222 do
223 local _with_0 = nil
224 do
225 local _accum_0
226 repeat
227 if _with_0 ~= nil then
228 _accum_0 = _with_0.value
229 break
230 end
231 until true
232 result = _accum_0
233 end
234 end
235 return assert.same(result, nil)
236 end)
237 it("should work with method chaining", function()
238 local obj = {
239 value = 5,
240 add = function(self, n)
241 self.value = self.value + n
242 end,
243 get = function(self)
244 return self.value
245 end
246 }
247 local result
248 do
249 local _accum_0
250 repeat
251 obj:add(10)
252 obj:add(5)
253 _accum_0 = obj:get()
254 break
255 until true
256 result = _accum_0
257 end
258 return assert.same(result, 20)
259 end)
260 return it("should support nested property access", function()
261 local obj = {
262 level1 = {
263 level2 = {
264 level3 = "deep"
265 }
266 }
267 }
268 local result
269 do
270 local _accum_0
271 repeat
272 _accum_0 = obj.level1.level2.level3
273 break
274 until true
275 result = _accum_0
276 end
277 return assert.same(result, "deep")
278 end)
279end)
diff --git a/spec/outputs/test/yaml_string_spec.lua b/spec/outputs/test/yaml_string_spec.lua
index 258ab92..e95ab55 100644
--- a/spec/outputs/test/yaml_string_spec.lua
+++ b/spec/outputs/test/yaml_string_spec.lua
@@ -1,13 +1,13 @@
1return describe("yaml string", function() 1return describe("yaml string", function()
2 it("should create basic yaml string", function() 2 it("should create basic yaml string", function()
3 local s = "hello\nworld" 3 local s = "hello\nworld"
4 assert.is_true(s:match("hello")) 4 assert.is_true((s:match("hello") ~= nil))
5 return assert.is_true(s:match("world")) 5 return assert.is_true((s:match("world") ~= nil))
6 end) 6 end)
7 it("should preserve indentation", function() 7 it("should preserve indentation", function()
8 local s = "key1: value1\nkey2: value2" 8 local s = "key1: value1\nkey2: value2"
9 assert.is_true(s:match("key1")) 9 assert.is_true((s:match("key1") ~= nil))
10 return assert.is_true(s:match("key2")) 10 return assert.is_true((s:match("key2") ~= nil))
11 end) 11 end)
12 it("should support interpolation", function() 12 it("should support interpolation", function()
13 local name = "test" 13 local name = "test"
@@ -17,22 +17,23 @@ return describe("yaml string", function()
17 it("should handle complex interpolation", function() 17 it("should handle complex interpolation", function()
18 local x, y = 10, 20 18 local x, y = 10, 20
19 local s = "point:\n\tx: " .. tostring(x) .. "\n\ty: " .. tostring(y) 19 local s = "point:\n\tx: " .. tostring(x) .. "\n\ty: " .. tostring(y)
20 assert.is_true(s:match("x: 10")) 20 assert.is_true((s:match("x: 10") ~= nil))
21 return assert.is_true(s:match("y: 20")) 21 return assert.is_true((s:match("y: 20") ~= nil))
22 end) 22 end)
23 it("should work with expressions", function() 23 it("should work with expressions", function()
24 local s = "result: " .. tostring(1 + 2) 24 local s = "result: " .. tostring(1 + 2)
25 return assert.is_true(s:match("result: 3")) 25 return assert.is_true((s:match("result: 3") ~= nil))
26 end) 26 end)
27 it("should support multiline with variables", function() 27 it("should support multiline with variables", function()
28 local config = "database:\n\thost: localhost\n\tport: 5432\n\tname: mydb" 28 local config = "database:\n\thost: localhost\n\tport: 5432\n\tname: mydb"
29 assert.is_true(config:match("database:")) 29 assert.is_true((config:match("database:") ~= nil))
30 return assert.is_true(config:match("host:")) 30 return assert.is_true((config:match("host:") ~= nil))
31 end) 31 end)
32 it("should escape special characters", function() 32 it("should escape special characters", function()
33 local Hello = "Hello"
33 local s = "path: \"C:\\Program Files\\App\"\nnote: 'He said: \"" .. tostring(Hello) .. "!\"'" 34 local s = "path: \"C:\\Program Files\\App\"\nnote: 'He said: \"" .. tostring(Hello) .. "!\"'"
34 assert.is_true(s:match("path:")) 35 return assert.same(s, [[path: "C:\Program Files\App"
35 return assert.is_true(s:match("note:")) 36note: 'He said: "Hello!"']])
36 end) 37 end)
37 it("should work in function", function() 38 it("should work in function", function()
38 local fn 39 local fn
@@ -41,8 +42,7 @@ return describe("yaml string", function()
41 return str 42 return str
42 end 43 end
43 local result = fn() 44 local result = fn()
44 assert.is_true(result:match("foo:")) 45 return assert.same(result, "foo:\n\tbar: baz")
45 return assert.is_true(result:match("bar:"))
46 end) 46 end)
47 it("should strip common leading whitespace", function() 47 it("should strip common leading whitespace", function()
48 local fn 48 local fn
@@ -51,36 +51,34 @@ return describe("yaml string", function()
51 return s 51 return s
52 end 52 end
53 local result = fn() 53 local result = fn()
54 assert.is_true(result:match("nested:")) 54 return assert.same(result, "nested:\n item: value")
55 return assert.is_true(result:match("item:"))
56 end) 55 end)
57 it("should support empty lines", function() 56 it("should support empty lines", function()
58 local s = "line1\nline3" 57 local s = "line1\nline3"
59 assert.is_true(s:match("line1")) 58 return assert.same(s, "line1\nline3")
60 return assert.is_true(s:match("line3"))
61 end) 59 end)
62 it("should work with table access in interpolation", function() 60 it("should work with table access in interpolation", function()
63 local t = { 61 local t = {
64 value = 100 62 value = 100
65 } 63 }
66 local s = "value: " .. tostring(t.value) 64 local s = "value: " .. tostring(t.value)
67 return assert.is_true(s:match("value: 100")) 65 return assert.same(s, "value: 100")
68 end) 66 end)
69 it("should support function calls in interpolation", function() 67 it("should support function calls in interpolation", function()
70 local s = "result: " .. tostring((function() 68 local s = "result: " .. tostring((function()
71 return 42 69 return 42
72 end)()) 70 end)())
73 return assert.is_true(s:match("result: 42")) 71 return assert.same(s, "result: 42")
74 end) 72 end)
75 it("should handle quotes correctly", function() 73 it("should handle quotes correctly", function()
76 local s = "\"quoted\"\n'single quoted'" 74 local s = "\"quoted\"\n'single quoted'"
77 assert.is_true(s:match('"quoted"')) 75 assert.is_true((s:match('"quoted"') ~= nil))
78 return assert.is_true(s:match("'single quoted'")) 76 return assert.is_true((s:match("'single quoted'") ~= nil))
79 end) 77 end)
80 it("should work with multiple interpolations", function() 78 it("should work with multiple interpolations", function()
81 local a, b, c = 1, 2, 3 79 local a, b, c = 1, 2, 3
82 local s = "values: " .. tostring(a) .. ", " .. tostring(b) .. ", " .. tostring(c) 80 local s = "values: " .. tostring(a) .. ", " .. tostring(b) .. ", " .. tostring(c)
83 return assert.is_true(s:match("values: 1, 2, 3")) 81 return assert.same(s, "values: 1, 2, 3")
84 end) 82 end)
85 return it("should preserve newlines", function() 83 return it("should preserve newlines", function()
86 local s = "first line\nsecond line\nthird line" 84 local s = "first line\nsecond line\nthird line"
diff --git a/spec/outputs/unicode/string.lua b/spec/outputs/unicode/string.lua
index 6bfb033..2fbf0fa 100644
--- a/spec/outputs/unicode/string.lua
+++ b/spec/outputs/unicode/string.lua
@@ -33,21 +33,21 @@ _u53d8_u91cfa = '你好 #{问候} 你好'
33_u53d8_u91cfb = '#{问候} 你好' 33_u53d8_u91cfb = '#{问候} 你好'
34_u53d8_u91cfc = '你好 #{问候}' 34_u53d8_u91cfc = '你好 #{问候}'
35local _u53d8_u91cf_ = "你好" 35local _u53d8_u91cf_ = "你好"
36local _call_0 = ("你好") 36local _call_0 = "你好"
37_call_0["格式"](_call_0, 1) 37_call_0["格式"](_call_0, 1)
38local _call_1 = ("你好") 38local _call_1 = "你好"
39_call_1["格式"](_call_1, 1, 2, 3) 39_call_1["格式"](_call_1, 1, 2, 3)
40local _call_2 = ("你好") 40local _call_2 = "你好"
41_call_2["格式"](_call_2, 1, 2, 3)(1, 2, 3) 41_call_2["格式"](_call_2, 1, 2, 3)(1, 2, 3)
42local _call_3 = ("你好") 42local _call_3 = "你好"
43_call_3["世界"](_call_3) 43_call_3["世界"](_call_3)
44local _call_4 = ("你好") 44local _call_4 = "你好"
45_call_4["格式"](_call_4)["问候"](1, 2, 3) 45_call_4["格式"](_call_4)["问候"](1, 2, 3)
46local _call_5 = ("你好") 46local _call_5 = "你好"
47_call_5["格式"](_call_5, 1, 2, 3) 47_call_5["格式"](_call_5, 1, 2, 3)
48local _call_6 = _u67d0_u4e8b("你好") 48local _call_6 = _u67d0_u4e8b("你好")
49_call_6["世界"](_call_6) 49_call_6["世界"](_call_6)
50return _u67d0_u4e8b((function() 50return _u67d0_u4e8b((function()
51 local _call_7 = ("你好") 51 local _call_7 = "你好"
52 return _call_7["世界"](_call_7) 52 return _call_7["世界"](_call_7)
53end)()) 53end)())
diff --git a/spec/outputs/unicode/syntax.lua b/spec/outputs/unicode/syntax.lua
index f5d5d8a..e897475 100644
--- a/spec/outputs/unicode/syntax.lua
+++ b/spec/outputs/unicode/syntax.lua
@@ -77,7 +77,7 @@ _ = _call_2["变量b"](_call_2)
77_ = f("")["变量c"]() 77_ = f("")["变量c"]()
78f(("")[_u53d8_u91cfa]) 78f(("")[_u53d8_u91cfa])
79f((function() 79f((function()
80 local _call_3 = ("") 80 local _call_3 = ""
81 return _call_3["变量b"](_call_3) 81 return _call_3["变量b"](_call_3)
82end)()) 82end)())
83f(("")["变量c"]()) 83f(("")["变量c"]())