aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/inputs/test/advanced_macro_spec.yue141
-rw-r--r--spec/inputs/test/chaining_comparison_spec.yue54
-rw-r--r--spec/inputs/test/close_attribute_spec.yue143
-rw-r--r--spec/inputs/test/const_attribute_spec.yue107
-rw-r--r--spec/inputs/test/do_statement_spec.yue139
-rw-r--r--spec/inputs/test/functions_advanced_spec.yue158
-rw-r--r--spec/inputs/test/if_assignment_spec.yue89
-rw-r--r--spec/inputs/test/implicit_object_spec.yue164
-rw-r--r--spec/inputs/test/in_expression_spec.yue94
-rw-r--r--spec/inputs/test/multiline_args_spec.yue125
-rw-r--r--spec/inputs/test/named_varargs_spec.yue121
-rw-r--r--spec/inputs/test/operator_advanced_spec.yue136
-rw-r--r--spec/inputs/test/param_destructure_spec.yue110
-rw-r--r--spec/inputs/test/prefixed_return_spec.yue48
-rw-r--r--spec/inputs/test/reverse_index_spec.yue59
-rw-r--r--spec/inputs/test/slicing_spec.yue77
-rw-r--r--spec/inputs/test/stub_spec.yue109
-rw-r--r--spec/inputs/test/table_append_spec.yue77
-rw-r--r--spec/inputs/test/table_comprehension_spec.yue127
-rw-r--r--spec/inputs/test/tables_advanced_spec.yue153
-rw-r--r--spec/inputs/test/varargs_assignment_spec.yue96
-rw-r--r--spec/inputs/test/while_assignment_spec.yue42
-rw-r--r--spec/inputs/test/whitespace_spec.yue118
-rw-r--r--spec/inputs/test/with_statement_spec.yue145
-rw-r--r--spec/inputs/test/yaml_string_spec.yue112
-rw-r--r--spec/outputs/test/chaining_comparison_spec.lua85
-rw-r--r--spec/outputs/test/if_assignment_spec.lua171
-rw-r--r--spec/outputs/test/in_expression_spec.lua489
-rw-r--r--spec/outputs/test/named_varargs_spec.lua246
-rw-r--r--spec/outputs/test/prefixed_return_spec.lua105
-rw-r--r--spec/outputs/test/reverse_index_spec.lua152
-rw-r--r--spec/outputs/test/table_append_spec.lua160
-rw-r--r--spec/outputs/test/varargs_assignment_spec.lua188
-rw-r--r--spec/outputs/test/while_assignment_spec.lua84
-rw-r--r--spec/outputs/test/yaml_string_spec.lua99
35 files changed, 4523 insertions, 0 deletions
diff --git a/spec/inputs/test/advanced_macro_spec.yue b/spec/inputs/test/advanced_macro_spec.yue
new file mode 100644
index 0000000..3d7b10a
--- /dev/null
+++ b/spec/inputs/test/advanced_macro_spec.yue
@@ -0,0 +1,141 @@
1describe "advanced macro", ->
2 it "should evaluate macro at compile time", ->
3 macro PI2 = -> math.pi * 2
4 area = $PI2 * 5
5 assert.is_true area > 0
6
7 it "should support macro with arguments", ->
8 macro add = (a, b) -> "#{a} + #{b}"
9 result = $add 5, 10
10 assert.same result, 15
11
12 it "should handle string returning macro", ->
13 macro HELLO = -> "'hello world'"
14 result = $HELLO
15 assert.same result, "hello world"
16
17 it "should work with conditional compilation", ->
18 macro config = (debugging) ->
19 global debugMode = debugging == "true"
20 ""
21
22 $config true
23 assert.is_true debugMode
24
25 $config false
26 assert.is_false debugMode
27
28 it "should support macro generating conditional code", ->
29 macro asserts = (cond) ->
30 debugMode and "assert #{cond}" or ""
31
32 global debugMode = true
33 x = 10
34 $asserts x == 10 -- should assert
35 assert.same x, 10
36
37 it "should work with lua code insertion", ->
38 macro luaCode = (code) -> {
39 :code
40 type: "lua"
41 }
42
43 $luaCode "local macro_test_var = 42"
44 assert.same macro_test_var, 42
45
46 it "should support multi-line raw lua", ->
47 macro lua = (code) -> {
48 :code
49 type: "lua"
50 }
51
52 $lua[==[
53 local multiline_var = "test"
54 ]==]
55 assert.same multiline_var, "test"
56
57 it "should export macro from module", ->
58 -- This test demonstrates macro export syntax
59 -- Actual testing would require separate files
60 macro exported_macro = (x) -> "#{x} * 2"
61 result = $exported_macro 5
62 assert.same result, 10
63
64 it "should work with builtin FILE macro", ->
65 macro file_test = ->
66 "$FILE"
67
68 result = $file_test
69 assert.is_true type(result) == "string"
70
71 it "should work with builtin LINE macro", ->
72 macro line_test = ->
73 "$LINE"
74
75 result = $line_test
76 assert.is_true type(result) == "number"
77
78 it "should support argument validation", ->
79 macro expect_num = (val `Num) ->
80 "#{val}"
81
82 result = $expect_num 123
83 assert.same result, 123
84
85 it "should handle string argument validation", ->
86 macro expect_str = (str `String) ->
87 "#{str}"
88
89 result = $expect_str "hello"
90 assert.same result, "hello"
91
92 it "should work with is_ast check", ->
93 macro safe_add = (a, b) ->
94 error "expected numbers" unless $is_ast Num, a
95 error "expected numbers" unless $is_ast Num, b
96 "#{a} + #{b}"
97
98 result = $safe_add 10, 20
99 assert.same result, 30
100
101 it "should support macro generating macro", ->
102 macro Enum = (...) ->
103 items = {...}
104 itemSet = {item, true for item in *items}
105 (item) ->
106 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item]
107 "\"#{item}\""
108
109 macro Color = $Enum(
110 Red
111 Green
112 Blue
113 )
114
115 result = $Color Red
116 assert.same result, "Red"
117
118 it "should handle complex macro logic", ->
119 macro smart_print = (items) ->
120 "print(#{table.concat [item for item in *items], ', ')})"
121
122 $smart_print {"hello", "world", 123}
123
124 it "should work with table manipulation", ->
125 macro create_table = (...) ->
126 items = {...}
127 "{#{table.concat items, ', '}}"
128
129 result = $create_table "1", "2", "3"
130 assert.same result, {"1", "2", "3"}
131
132 it "should support string concatenation in macro", ->
133 macro concat = (...) ->
134 args = {...}
135 res = {}
136 for arg in *args
137 table.insert res, tostring arg
138 "'" .. table.concat(res, " .. ") .. "'"
139
140 result = $concat "hello", "world"
141 assert.same result, "helloworld"
diff --git a/spec/inputs/test/chaining_comparison_spec.yue b/spec/inputs/test/chaining_comparison_spec.yue
new file mode 100644
index 0000000..f86cf5f
--- /dev/null
+++ b/spec/inputs/test/chaining_comparison_spec.yue
@@ -0,0 +1,54 @@
1describe "chaining comparison", ->
2 it "should support simple chaining", ->
3 assert.is_true 1 < 2 < 3
4 assert.is_true 1 <= 2 <= 3
5 assert.is_true 3 > 2 > 1
6 assert.is_true 3 >= 2 >= 1
7
8 it "should support complex chaining", ->
9 assert.is_true 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 ~= 5
10
11 it "should work with variables", ->
12 a = 5
13 assert.is_true 1 <= a <= 10
14 assert.is_true a >= 3
15 assert.is_true a <= 10
16
17 it "should handle mixed comparisons", ->
18 x = 5
19 assert.is_true 1 < x < 10
20 assert.is_true 1 <= x <= 5
21
22 it "should work with string comparisons", ->
23 assert.is_true "a" < "b" < "c"
24 assert.is_true "a" <= "b" <= "c"
25
26 it "should handle edge cases", ->
27 assert.is_true 0 <= 0 <= 0
28 assert.is_true -5 < 0 < 5
29
30 it "should work in expressions", ->
31 result = if 1 < 2 < 3
32 "yes"
33 else
34 "no"
35 assert.same result, "yes"
36
37 it "should support != operator", ->
38 assert.is_true 1 != 2 != 3
39 assert.is_true 1 ~= 2 ~= 3
40
41 it "should handle boolean results", ->
42 assert.is_true 1 < 2 < 3
43 assert.is_false 3 < 2 < 1
44
45 it "should work with function calls", ->
46 v = (x) -> x
47 assert.is_true v(1) < v(2) < v(3)
48
49 it "should handle negation", ->
50 assert.is_true -10 < -5 < 0
51
52 it "should support mixed operators", ->
53 assert.is_true 1 < 2 <= 2 < 3
54 assert.is_true 3 > 2 >= 2 > 1
diff --git a/spec/inputs/test/close_attribute_spec.yue b/spec/inputs/test/close_attribute_spec.yue
new file mode 100644
index 0000000..2354df7
--- /dev/null
+++ b/spec/inputs/test/close_attribute_spec.yue
@@ -0,0 +1,143 @@
1describe "close attribute", ->
2 it "should declare close variable", ->
3 closed = false
4 do
5 close _ = <close>: -> closed = true
6 assert.is_true closed
7
8 it "should work with metatable syntax", ->
9 called = false
10 do
11 close _ = <close>: -> called = true
12 assert.is_true called
13
14 it "should handle multiple close scopes", ->
15 order = []
16 do
17 close first = <close>: -> table.insert order, "first"
18 close second = <close>: -> table.insert order, "second"
19 assert.same order, {"second", "first"}
20
21 it "should work with resources", ->
22 resource_opened = false
23 resource_closed = false
24
25 do
26 resource_opened = true
27 close _ = <close>: -> resource_closed = true
28
29 assert.is_true resource_opened
30 assert.is_true resource_closed
31
32 it "should support close in function", ->
33 closed = false
34 fn = ->
35 close _ = <close>: -> closed = true
36 return "result"
37
38 result = fn!
39 assert.same result, "result"
40 assert.is_true closed
41
42 it "should work with fat arrow", ->
43 closed = false
44 obj =
45 value: 10
46 close_method: <close>: =>
47 closed = true
48
49 do
50 close _ = obj
51
52 assert.is_true closed
53
54 it "should handle nested close scopes", ->
55 outer_closed = false
56 inner_closed = false
57
58 do
59 close outer = <close>: -> outer_closed = true
60 do
61 close inner = <close>: -> inner_closed = true
62
63 assert.is_true inner_closed
64 assert.is_true outer_closed
65
66 it "should work with conditional close", ->
67 closed = false
68 should_close = true
69
70 if should_close
71 close _ = <close>: -> closed = true
72
73 assert.is_true closed
74
75 it "should support close in loop", ->
76 closed_count = 0
77 for i = 1, 3
78 do
79 close _ = <close>: -> closed_count += 1
80
81 assert.same closed_count, 3
82
83 it "should work with table destructuring", ->
84 closed = false
85 tb = {close: <close>: -> closed = true}
86 do
87 {:close} = tb
88 assert.is_true closed
89
90 it "should handle close with return value", ->
91 closed = false
92 fn = ->
93 close _ = <close>: -> closed = true
94 return 42
95
96 result = fn!
97 assert.same result, 42
98 assert.is_true closed
99
100 it "should work with error handling", ->
101 closed = false
102 error_thrown = false
103
104 do
105 close _ = <close>: -> closed = true
106 error_thrown = true
107
108 assert.is_true closed
109 assert.is_true error_thrown
110
111 it "should support close in varargs function", ->
112 closed = false
113 fn = (...) ->
114 close _ = <close>: -> closed = true
115 {...}
116
117 result = fn 1, 2, 3
118 assert.same result, {1, 2, 3}
119 assert.is_true closed
120
121 it "should work with multiple variables", ->
122 first_closed = false
123 second_closed = false
124
125 do
126 close first = <close>: -> first_closed = true
127 close second = <close>: -> second_closed = true
128
129 assert.is_true first_closed
130 assert.is_true second_closed
131
132 it "should handle close in try block", ->
133 closed = false
134 success = false
135
136 success = try
137 close _ = <close>: -> closed = true
138 true
139 catch err
140 false
141
142 assert.is_true success
143 assert.is_true closed
diff --git a/spec/inputs/test/const_attribute_spec.yue b/spec/inputs/test/const_attribute_spec.yue
new file mode 100644
index 0000000..e3cc638
--- /dev/null
+++ b/spec/inputs/test/const_attribute_spec.yue
@@ -0,0 +1,107 @@
1describe "const attribute", ->
2 it "should declare const variable", ->
3 const a = 123
4 assert.same a, 123
5
6 it "should prevent reassignment", ->
7 const b = 456
8 -- b = 789 -- This should cause error
9 assert.same b, 456
10
11 it "should work with strings", ->
12 const name = "test"
13 assert.same name, "test"
14
15 it "should support const with destructuring", ->
16 tb = {a: 1, b: 2, c: 3, d: 4}
17 const {:a, :b, c, d} = tb
18 assert.same a, 1
19 assert.same b, 2
20 assert.same c, 3
21 assert.same d, 4
22
23 it "should handle nested const", ->
24 const nested = {
25 inner: {value: 10}
26 }
27 assert.same nested.inner.value, 10
28
29 it "should work with arrays", ->
30 const items = [1, 2, 3]
31 assert.same items[1], 1
32
33 it "should support const in function scope", ->
34 fn = ->
35 const local_const = "local"
36 local_const
37
38 result = fn!
39 assert.same result, "local"
40
41 it "should work with multiple const declarations", ->
42 const x = 1
43 const y = 2
44 const z = 3
45 assert.same x + y + z, 6
46
47 it "should handle const functions", ->
48 const add = (a, b) -> a + b
49 assert.same add 5, 10, 15
50
51 it "should work with const tables", ->
52 const config = {
53 host: "localhost"
54 port: 8080
55 }
56 assert.same config.host, "localhost"
57 assert.same config.port, 8080
58
59 it "should support global const", ->
60 global const GLOBAL_CONST = 999
61 assert.same GLOBAL_CONST, 999
62
63 it "should work with boolean const", ->
64 const flag = true
65 const another = false
66 assert.is_true flag
67 assert.is_false another
68
69 it "should handle nil const", ->
70 const nil_value = nil
71 assert.same nil_value, nil
72
73 it "should work with expressions", ->
74 const calculated = 10 + 20
75 assert.same calculated, 30
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", ->
85 const multiplier = 2
86 items = [1, 2, 3]
87 result = [item * multiplier for item in *items]
88 assert.same result, {2, 4, 6}
89
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", ->
100 const complex = {
101 data: [1, 2, 3]
102 nested: {
103 key: "value"
104 }
105 }
106 assert.same complex.data[1], 1
107 assert.same complex.nested.key, "value"
diff --git a/spec/inputs/test/do_statement_spec.yue b/spec/inputs/test/do_statement_spec.yue
new file mode 100644
index 0000000..0adad20
--- /dev/null
+++ b/spec/inputs/test/do_statement_spec.yue
@@ -0,0 +1,139 @@
1describe "do statement", ->
2 it "should create new scope", ->
3 x = 10
4 do
5 local x = 20
6 assert.same x, 20
7 assert.same x, 10
8
9 it "should return value from do block", ->
10 result = do
11 x = 5
12 x * 2
13 assert.same result, 10
14
15 it "should work with multiple statements", ->
16 result = do
17 a = 1
18 b = 2
19 c = 3
20 a + b + c
21 assert.same result, 6
22
23 it "should handle nested do blocks", ->
24 result = do
25 x = 10
26 y = do
27 z = 5
28 z * 2
29 x + y
30 assert.same result, 20
31
32 it "should support conditional in do block", ->
33 result = do
34 value = 5
35 if value > 3
36 value * 2
37 else
38 value
39 assert.same result, 10
40
41 it "should work with loops in do block", ->
42 result = do
43 sum = 0
44 for i = 1, 5
45 sum += i
46 sum
47 assert.same result, 15
48
49 it "should handle table operations", ->
50 result = do
51 tb = {1, 2, 3}
52 table.insert tb, 4
53 #tb
54 assert.same result, 4
55
56 it "should work with function definition", ->
57 result = do
58 fn = (x) -> x * 2
59 fn 5
60 assert.same result, 10
61
62 it "should support variable shadowing", ->
63 x = "outer"
64 result = do
65 x = "inner"
66 x
67 assert.same result, "inner"
68 assert.same x, "outer"
69
70 it "should work with method calls", ->
71 obj =
72 value: 10
73 double: => @value * 2
74
75 result = do
76 with obj
77 \double!
78 assert.same result, 20
79
80 it "should handle comprehensions in do block", ->
81 result = do
82 items = [1, 2, 3, 4, 5]
83 [item * 2 for item in *items]
84 assert.same result, {2, 4, 6, 8, 10}
85
86 it "should work with try-catch", ->
87 result = do
88 success = try
89 error "test error"
90 false
91 catch err
92 true
93 assert.is_true success
94
95 it "should support return statement", ->
96 fn = ->
97 do
98 x = 10
99 return x * 2
100 "never reached"
101
102 result = fn!
103 assert.same result, 20
104
105 it "should work with assignment", ->
106 result = do
107 a, b, c = 1, 2, 3
108 a + b + c
109 assert.same result, 6
110
111 it "should handle destructuring", ->
112 result = do
113 tb = {x: 10, y: 20}
114 {:x, :y} = tb
115 x + y
116 assert.same result, 30
117
118 it "should work with string interpolation", ->
119 name = "world"
120 result = do
121 greeting = "hello"
122 "#{greeting} #{name}"
123 assert.same result, "hello world"
124
125 it "should support implicit return", ->
126 result = do
127 value = 42
128 assert.same result, 42
129
130 it "should handle empty do block", ->
131 result = do
132 assert.same result, nil
133
134 it "should work with backcalls", ->
135 result = do
136 items = [1, 2, 3]
137 (x) <- map _, items
138 x * 2
139 assert.same result, {2, 4, 6}
diff --git a/spec/inputs/test/functions_advanced_spec.yue b/spec/inputs/test/functions_advanced_spec.yue
new file mode 100644
index 0000000..d0e0cf5
--- /dev/null
+++ b/spec/inputs/test/functions_advanced_spec.yue
@@ -0,0 +1,158 @@
1describe "advanced functions", ->
2 it "should support fat arrow with self", ->
3 obj =
4 value: 10
5 getValue: => @value
6
7 assert.same obj\getValue!, 10
8
9 it "should work with argument defaults", ->
10 fn = (name = "something", height = 100) ->
11 "#{name}, #{height}"
12
13 assert.same fn!, "something, 100"
14 assert.same fn("test"), "test, 100"
15 assert.same fn("test", 50), "test, 50"
16
17 it "should handle defaults with previous arguments", ->
18 fn = (x = 100, y = x + 1000) ->
19 x + y
20
21 assert.same fn!, 1200
22 assert.same fn(50), 1150
23
24 it "should work with multi-line arguments", ->
25 my_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
26 result = my_func 5, 4, 3,
27 8, 9, 10
28 assert.same result, 39
29
30 it "should support nested function calls", ->
31 result = my_func 5, 6, 7,
32 6, another_func 6, 7, 8,
33 9, 1, 2,
34 5, 4
35
36 another_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
37 my_func = (a, b, c, d, e, f) -> a + b + c + d + e + f
38
39 assert.same result, 52
40
41 it "should handle implicit return", ->
42 sum = (x, y) -> x + y
43 assert.same sum 10, 20, 30
44
45 it "should work with explicit return", ->
46 difference = (x, y) -> return x - y
47 assert.same difference 20, 10, 10
48
49 it "should support multiple return values", ->
50 mystery = (x, y) -> x + y, x - y
51 a, b = mystery 10, 20
52 assert.same a, 30
53 assert.same b, -10
54
55 it "should work with function as argument", ->
56 apply = (fn, x, y) -> fn x, y
57 result = apply ((a, b) -> a + b), 5, 10
58 assert.same result, 15
59
60 it "should handle function returning function", ->
61 create_adder = (x) -> (y) -> x + y
62 add_five = create_adder 5
63 assert.same add_five(10), 15
64
65 it "should support immediately invoked function", ->
66 result = ((x) -> x * 2) 5
67 assert.same result, 10
68
69 it "should work with varargs", ->
70 sum_all = (...) ->
71 total = 0
72 for i = 1, select '#', ...
73 total += select(i, ...) if type(select(i, ...)) == "number"
74 total
75
76 assert.same sum_all(1, 2, 3, 4, 5), 15
77
78 it "should handle named varargs", ->
79 fn = (...t) ->
80 count = 0
81 for i = 1, t.n
82 count += 1
83 count
84
85 assert.same fn(1, 2, 3), 3
86
87 it "should support prefixed return", ->
88 findValue: "not found" ->
89 items = [1, 2, 3]
90 for item in *items
91 if item == 5
92 return item
93
94 result = findValue!
95 assert.same result, "not found"
96
97 it "should work with parameter destructuring", ->
98 fn = (:a, :b, :c) ->
99 a + b + c
100
101 assert.same fn(a: 1, b: 2, c: 3), 6
102
103 it "should handle default values in destructuring", ->
104 fn = ({a: a1 = 123, :b = 'abc'}) ->
105 a1 .. " " .. b
106
107 assert.same fn{}, "123 abc"
108 assert.same fn({a: 456}), "456 abc"
109
110 it "should support empty function body", ->
111 empty_fn = ->
112 assert.same empty_fn!, nil
113
114 it "should work with function in table", ->
115 tb =
116 value: 10
117 double: => @value * 2
118
119 assert.same tb\double!, 20
120
121 it "should handle function with no arguments", ->
122 fn = ->
123 "result"
124
125 assert.same fn!, "result"
126 assert.same fn(), "result"
127
128 it "should support calling function with !", ->
129 fn = -> 42
130 assert.same fn!, 42
131
132 it "should work with nested functions", ->
133 outer = (x) ->
134 inner = (y) -> x + y
135 inner
136
137 add_five = outer 5
138 assert.same add_five(10), 15
139
140 it "should handle function in expression", ->
141 result = if ((x) -> x > 10) 15
142 "large"
143 else
144 "small"
145 assert.same result, "large"
146
147 it "should support function as return value", ->
148 get_operation = (op) ->
149 switch op
150 when "add"
151 (a, b) -> a + b
152 when "subtract"
153 (a, b) -> a - b
154 else
155 -> 0
156
157 add = get_operation "add"
158 assert.same add 5, 3, 8
diff --git a/spec/inputs/test/if_assignment_spec.yue b/spec/inputs/test/if_assignment_spec.yue
new file mode 100644
index 0000000..1ce028e
--- /dev/null
+++ b/spec/inputs/test/if_assignment_spec.yue
@@ -0,0 +1,89 @@
1describe "if assignment", ->
2 it "should assign and check truthy value", ->
3 obj = find_user: (name) -> name == "valid" and {name: name} or nil
4 if user := obj\find_user "valid"
5 assert.same user.name, "valid"
6
7 it "should not enter block when nil", ->
8 obj = find_user: -> nil
9 if user := obj\find_user!
10 assert.is_true false -- should not reach
11 else
12 assert.is_true true
13
14 it "should work with elseif", ->
15 get_value = (key) ->
16 switch key
17 when "a" then 1
18 when "b" then 2
19 else nil
20
21 result = nil
22 if val := get_value "c"
23 result = "c: #{val}"
24 elseif val := get_value "b"
25 result = "b: #{val}"
26 else
27 result = "no match"
28 assert.same result, "b: 2"
29
30 it "should scope variable to if block", ->
31 if x := 10
32 assert.same x, 10
33 -- x should not be accessible here
34 assert.is_true true
35
36 it "should work with multiple return values", ->
37 fn = -> true, "success"
38 if success, result := fn!
39 assert.is_true success
40 assert.same result, "success"
41
42 it "should work with table destructuring", ->
43 get_point = -> {x: 10, y: 20}
44 if {:x, :y} := get_point!
45 assert.same x, 10
46 assert.same y, 20
47
48 it "should work with array destructuring", ->
49 get_coords = -> [1, 2, 3]
50 if [a, b, c] := get_coords!
51 assert.same a, 1
52 assert.same b, 2
53 assert.same c, 3
54
55 it "should chain multiple assignments", ->
56 if a := 1
57 if b := a + 1
58 assert.same b, 2
59
60 it "should work in expression context", ->
61 get_value = (x) -> if x > 0 then x else nil
62 result = if val := get_value 5
63 val * 2
64 else
65 0
66 assert.same result, 10
67
68 it "should work with os.getenv", ->
69 -- test with environment variable
70 if path := os.getenv "PATH"
71 assert.is_true type(path) == "string"
72 else
73 assert.is_true true
74
75 it "should support table access", ->
76 tb = {key: "value"}
77 if val := tb.key
78 assert.same val, "value"
79
80 it "should work with function call results", ->
81 fn = -> "result"
82 if s := fn!
83 assert.same s, "result"
84
85 it "should handle false values", ->
86 if val := false
87 assert.is_true false -- should not enter
88 else
89 assert.is_true true
diff --git a/spec/inputs/test/implicit_object_spec.yue b/spec/inputs/test/implicit_object_spec.yue
new file mode 100644
index 0000000..cea926e
--- /dev/null
+++ b/spec/inputs/test/implicit_object_spec.yue
@@ -0,0 +1,164 @@
1describe "implicit object", ->
2 it "should create list with asterisk", ->
3 list =
4 * 1
5 * 2
6 * 3
7 assert.same list, {1, 2, 3}
8
9 it "should create list with dash", ->
10 items =
11 - "a"
12 - "b"
13 - "c"
14 assert.same items, {"a", "b", "c"}
15
16 it "should work with function call", ->
17 results = []
18 fn =
19 * 1
20 * 2
21 * 3
22
23 for item in *fn
24 table.insert results, item
25
26 assert.same results, {1, 2, 3}
27
28 it "should support nested implicit objects", ->
29 tb =
30 name: "test"
31
32 values:
33 - "a"
34 - "b"
35 - "c"
36
37 objects:
38 - name: "first"
39 value: 1
40 - name: "second"
41 value: 2
42
43 assert.same tb.values, {"a", "b", "c"}
44 assert.same tb.objects[1].name, "first"
45 assert.same tb.objects[2].value, 2
46
47 it "should work with return statement", ->
48 fn = ->
49 return
50 * 1
51 * 2
52 * 3
53
54 assert.same fn!, {1, 2, 3}
55
56 it "should handle mixed content", ->
57 tb =
58 key: "value"
59
60 items:
61 - 1
62 - 2
63
64 other: "data"
65
66 assert.same tb.key, "value"
67 assert.same tb.items, {1, 2}
68 assert.same tb.other, "data"
69
70 it "should work in assignment", ->
71 list =
72 * "x"
73 * "y"
74 * "z"
75
76 assert.same list, {"x", "y", "z"}
77
78 it "should support nested structures with asterisk", ->
79 tb =
80 * 1
81 * 2
82 nested:
83 * 3
84 * 4
85
86 assert.same tb[1], 1
87 assert.same tb[2], 2
88 assert.same tb.nested, {3, 4}
89
90 it "should handle implicit object in tables", ->
91 tb = {
92 name: "test"
93
94 list:
95 - 1
96 - 2
97
98 value: 42
99 }
100
101 assert.same tb.list, {1, 2}
102
103 it "should work with expressions", ->
104 x = 10
105 list =
106 * x + 1
107 * x + 2
108 * x + 3
109
110 assert.same list, {11, 12, 13}
111
112 it "should support method calls in implicit object", ->
113 tb =
114 name: "test"
115 items:
116 - name: "item1"
117 getName: => @name
118 - name: "item2"
119 getName: => @name
120
121 assert.same tb.items[1]\getName!, "item1"
122 assert.same tb.items[2]\getName!, "item2"
123
124 it "should work with complex nested structures", ->
125 config =
126 database:
127 host: "localhost"
128 ports:
129 - 8080
130 - 8081
131 - 8082
132
133 servers:
134 - name: "server1"
135 port: 8080
136 - name: "server2"
137 port: 8081
138
139 assert.same config.database.ports, {8080, 8081, 8082}
140 assert.same config.servers[1].name, "server1"
141
142 it "should handle empty implicit object", ->
143 tb =
144 items:
145 -
146
147 assert.same tb.items, {nil}
148
149 it "should work in function arguments", ->
150 fn = (items) -> #items
151 result = fn
152 * 1
153 * 2
154 * 3
155 assert.same result, 3
156
157 it "should support mixed asterisk and dash", ->
158 tb =
159 values:
160 * 1
161 - 2
162 * 3
163
164 assert.same tb.values, {1, 2, 3}
diff --git a/spec/inputs/test/in_expression_spec.yue b/spec/inputs/test/in_expression_spec.yue
new file mode 100644
index 0000000..c1f4099
--- /dev/null
+++ b/spec/inputs/test/in_expression_spec.yue
@@ -0,0 +1,94 @@
1describe "in expression", ->
2 it "should check value in table", ->
3 items = {1, 2, 3, 4, 5}
4 assert.is_true 3 in items
5 assert.is_false 10 in items
6
7 it "should work with strings", ->
8 chars = {"a", "b", "c"}
9 assert.is_true "b" in chars
10 assert.is_false "z" in chars
11
12 it "should check keys in table", ->
13 obj = {x: 1, y: 2, z: 3}
14 assert.is_true "x" in obj
15 assert.is_true "y" in obj
16 assert.is_false "w" in obj
17
18 it "should work with mixed types", ->
19 items = {1, "two", true, nil}
20 assert.is_true 1 in items
21 assert.is_true "two" in items
22 assert.is_true true in items
23 assert.is_false false in items
24
25 it "should handle empty table", ->
26 empty = {}
27 assert.is_false 1 in empty
28 assert.is_false "test" in empty
29
30 it "should work in conditional", ->
31 items = {1, 2, 3}
32 result = if 2 in items
33 "found"
34 else
35 "not found"
36 assert.same result, "found"
37
38 it "should support negation", ->
39 items = {1, 2, 3}
40 assert.is_true not (4 in items)
41 assert.is_false not (2 in items)
42
43 it "should work with nested tables", ->
44 nested = {{1, 2}, {3, 4}, {5, 6}}
45 assert.is_true {1, 2} in nested
46 assert.is_false {1, 3} in nested
47
48 it "should handle boolean values", ->
49 bools = {true, false}
50 assert.is_true true in bools
51 assert.is_true false in bools
52
53 it "should work in loop", ->
54 items = {1, 2, 3, 4, 5}
55 count = 0
56 for i = 1, 10
57 count += 1 if i in items
58 assert.same count, 5
59
60 it "should support table as value", ->
61 key1 = {a: 1}
62 key2 = {b: 2}
63 tb = {[key1]: "first", [key2]: "second"}
64
65 -- Note: this tests table reference equality
66 assert.is_true key1 in tb
67 assert.is_true key2 in tb
68
69 it "should work with function results", ->
70 get_items = -> {1, 2, 3}
71 assert.is_true 2 in get_items!
72 assert.is_false 5 in get_items!
73
74 it "should handle nil in table", ->
75 items = {1, nil, 3}
76 assert.is_true nil in items
77 assert.is_true 1 in items
78
79 it "should work with string keys", ->
80 obj = {name: "test", value: 42}
81 assert.is_true "name" in obj
82 assert.is_true "value" in obj
83 assert.is_false "missing" in obj
84
85 it "should support complex expressions", ->
86 items = {1, 2, 3}
87 result = (2 in items) and "yes" or "no"
88 assert.same result, "yes"
89
90 it "should work in comprehension", ->
91 source = {1, 2, 3, 4, 5}
92 allowed = {2, 4}
93 result = [item for item in *source when item in allowed]
94 assert.same result, {2, 4}
diff --git a/spec/inputs/test/multiline_args_spec.yue b/spec/inputs/test/multiline_args_spec.yue
new file mode 100644
index 0000000..bbb06f9
--- /dev/null
+++ b/spec/inputs/test/multiline_args_spec.yue
@@ -0,0 +1,125 @@
1describe "multiline arguments", ->
2 it "should split arguments across lines", ->
3 sum = (a, b, c) -> a + b + c
4 result = sum 5, 4, 3,
5 8, 9, 10
6 assert.same result, 39
7
8 it "should handle nested function calls", ->
9 outer = (a, b, c, d, e, f) -> a + b + c + d + e + f
10 result = outer 5, 6, 7,
11 6, 2, 3
12 assert.same result, 29
13
14 it "should work with string arguments", ->
15 fn = (a, b, c, d) -> a .. b .. c .. d
16 result = fn "hello",
17 " ", "world", "!"
18 assert.same result, "hello world!"
19
20 it "should support table arguments", ->
21 fn = (a, b, c) -> {a, b, c}
22 result = fn {1, 2},
23 {3, 4},
24 {5, 6}
25 assert.same result, {{1, 2}, {3, 4}, {5, 6}}
26
27 it "should handle mixed types", ->
28 fn = (a, b, c, d) -> {a, b, c, d}
29 result = fn "text",
30 123,
31 true,
32 nil
33 assert.same result, {"text", 123, true, nil}
34
35 it "should work in table literal", ->
36 fn = (a, b) -> a + b
37 result = [
38 1, 2, 3, 4, fn 4, 5,
39 5, 6,
40 8, 9, 10
41 ]
42 assert.same result, {1, 2, 3, 4, 9, 8, 9, 10}
43
44 it "should handle deeply nested indentation", ->
45 y = [ fn 1, 2, 3,
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
52
53 result = y[1]
54 assert.same result, 22
55
56 it "should work with conditional statements", ->
57 fn = (a, b, c, d, e) -> a + b + c + d + e
58
59 result = if fn 1, 2, 3,
60 "hello",
61 "world"
62 "yes"
63 else
64 "no"
65 assert.same result, "yes"
66
67 it "should support function expressions", ->
68 double = (x) -> x * 2
69 result = double 5,
70 10
71 assert.same result, 20
72
73 it "should handle chained function calls", ->
74 add = (a, b) -> a + b
75 multiply = (a, b) -> a * b
76
77 result = multiply add 1, 2,
78 add 3, 4
79 assert.same result, 21
80
81 it "should work with method calls", ->
82 obj =
83 value: 10
84 add: (a, b) => @value + a + b
85
86 result = obj\add 5, 10,
87 15
88 assert.same result, 40
89
90 it "should support many arguments", ->
91 sum_many = (...) ->
92 total = 0
93 for i = 1, select '#', ...
94 total += select(i, ...) if type(select(i, ...)) == "number"
95 total
96
97 result = sum_many 1, 2, 3,
98 4, 5, 6,
99 7, 8, 9
100 assert.same result, 45
101
102 it "should work with return statement", ->
103 fn = (a, b) -> a + b
104 get_value = ->
105 return fn 10, 20,
106 30
107
108 result = get_value!
109 assert.same result, 60
110
111 it "should handle default parameters", ->
112 fn = (a = 1, b = 2, c = 3) -> a + b + c
113 result = fn 10,
114 20,
115 30
116 assert.same result, 60
117
118 it "should work with varargs", ->
119 collect = (...) ->
120 {...}
121
122 result = collect 1, 2,
123 3, 4,
124 5, 6
125 assert.same result, {1, 2, 3, 4, 5, 6}
diff --git a/spec/inputs/test/named_varargs_spec.yue b/spec/inputs/test/named_varargs_spec.yue
new file mode 100644
index 0000000..a5ab2b1
--- /dev/null
+++ b/spec/inputs/test/named_varargs_spec.yue
@@ -0,0 +1,121 @@
1describe "named varargs", ->
2 it "should store varargs in named table", ->
3 f = (...t) ->
4 assert.same t.n, 3
5 assert.same t[1], 1
6 assert.same t[2], 2
7 assert.same t[3], 3
8
9 f 1, 2, 3
10
11 it "should handle string arguments", ->
12 f = (...args) ->
13 assert.same args.n, 3
14 assert.same args[1], "a"
15 assert.same args[2], "b"
16 assert.same args[3], "c"
17
18 f "a", "b", "c"
19
20 it "should handle empty varargs", ->
21 f = (...t) ->
22 assert.same t.n, 0
23 assert.same #t, 0
24
25 f!
26
27 it "should preserve nil values", ->
28 f = (...args) ->
29 assert.same args.n, 5
30 assert.same args[1], 1
31 assert.same args[2], nil
32 assert.same args[3], 3
33 assert.same args[4], nil
34 assert.same args[5], 5
35
36 f 1, nil, 3, nil, 5
37
38 it "should work with loop", ->
39 f = (...t) ->
40 sum = 0
41 for i = 1, t.n
42 sum += t[i] if type(t[i]) == "number"
43 sum
44
45 result = f 1, 2, 3, 4, 5
46 assert.same result, 15
47
48 it "should handle mixed types", ->
49 f = (...args) ->
50 types = [type(args[i]) for i = 1, args.n]
51 types
52
53 result = f "string", 123, true, nil, {}
54 assert.same result, {"string", "number", "boolean", "nil", "table"}
55
56 it "should work with table access", ->
57 f = (...t) ->
58 first = t[1]
59 last = t[t.n]
60 {first, last}
61
62 result = f 1, 2, 3, 4, 5
63 assert.same result, {1, 5}
64
65 it "should support select with named args", ->
66 f = (...args) ->
67 second = select 2, table.unpack args
68 second
69
70 result = f "a", "b", "c"
71 assert.same result, "b"
72
73 it "should work with pcall", ->
74 f = (...t) ->
75 success = true
76 for i = 1, t.n
77 if t[i] == nil
78 success = false
79 success
80
81 result = f 1, nil, 3
82 assert.is_false result
83
84 it "should handle function results", ->
85 g = -> 1, 2, 3
86 f = (...t) ->
87 t.n
88
89 result = f g!
90 assert.same result, 3
91
92 it "should work with unpacking", ->
93 f = (...args) ->
94 {table.unpack args}
95
96 result = f "a", "b", "c"
97 assert.same result, {"a", "b", "c"}
98
99 it "should support passing named varargs to another function", ->
100 outer = (...t) ->
101 inner (table.unpack t)
102
103 inner = (a, b, c) ->
104 {a, b, c}
105
106 result = outer 1, 2, 3
107 assert.same result, {1, 2, 3}
108
109 it "should work with default parameter", ->
110 f = (x = 10, ...t) ->
111 x + t[1] or 0
112
113 result = f 5, 15
114 assert.same result, 20
115
116 it "should handle single argument", ->
117 f = (...t) ->
118 {t.n, t[1]}
119
120 result = f 42
121 assert.same result, {1, 42}
diff --git a/spec/inputs/test/operator_advanced_spec.yue b/spec/inputs/test/operator_advanced_spec.yue
new file mode 100644
index 0000000..8127fd4
--- /dev/null
+++ b/spec/inputs/test/operator_advanced_spec.yue
@@ -0,0 +1,136 @@
1describe "advanced operators", ->
2 it "should support chaining comparisons with functions", ->
3 v = (x) -> x
4 assert.is_true v(1) < v(2) <= v(3)
5
6 it "should handle compound assignment with or", ->
7 x = nil
8 x or= "default"
9 assert.same x, "default"
10
11 it "should not overwrite existing value with or", ->
12 x = "existing"
13 x or= "default"
14 assert.same x, "existing"
15
16 it "should support compound string concatenation", ->
17 s = "hello"
18 s ..= " world"
19 assert.same s, "hello world"
20
21 it "should work with table appending", ->
22 tab = [1, 2]
23 tab[] = 3
24 tab[] = 4
25 assert.same tab, {1, 2, 3, 4}
26
27 it "should handle spread append", ->
28 tbA = [1, 2]
29 tbB = [3, 4]
30 tbA[] = ...tbB
31 assert.same tbA, {1, 2, 3, 4}
32
33 it "should support reverse indexing", ->
34 items = [1, 2, 3, 4, 5]
35 assert.same items[#], 5
36 assert.same items[#-1], 4
37 assert.same items[#-2], 3
38
39 it "should work with nil coalescing assignment", ->
40 x = nil
41 x ??= "default"
42 assert.same x, "default"
43
44 it "should not assign with ??= when value exists", ->
45 x = "existing"
46 x ??= "default"
47 assert.same x, "existing"
48
49 it "should chain nil coalescing", ->
50 a = nil
51 b = nil
52 c = "value"
53 result = a ?? b ?? c
54 assert.same result, "value"
55
56 it "should support compound modulo", ->
57 x = 20
58 x %= 3
59 assert.same x, 2
60
61 it "should handle compound exponentiation", ->
62 x = 2
63 x ^= 3
64 assert.same x, 8
65
66 it "should work with compound bitwise and", ->
67 x = 15 -- 1111 in binary
68 x &= 7 -- 0111 in binary
69 assert.same x, 7
70
71 it "should support compound bitwise or", ->
72 x = 8 -- 1000 in binary
73 x |= 3 -- 0011 in binary
74 assert.same x, 11 -- 1011 in binary
75
76 it "should handle compound bitwise xor", ->
77 x = 12 -- 1100 in binary
78 x ~= 10 -- 1010 in binary
79 assert.same x, 6 -- 0110 in binary
80
81 it "should work with compound left shift", ->
82 x = 2
83 x <<= 3
84 assert.same x, 16
85
86 it "should support compound right shift", ->
87 x = 16
88 x >>= 2
89 assert.same x, 4
90
91 it "should handle negation operator", ->
92 assert.same -10, -10
93 assert.same --5, 5
94
95 it "should work with length operator on tables", ->
96 tab = {1, 2, 3, 4, 5}
97 assert.same #tab, 5
98
99 it "should support length on strings", ->
100 s = "hello"
101 assert.same #s, 5
102
103 it "should handle chaining assignment", ->
104 a = b = c = d = 0
105 assert.same a, 0
106 assert.same b, 0
107 assert.same c, 0
108 assert.same d, 0
109
110 it "should work with chaining assignment with functions", ->
111 f = -> 42
112 x = y = z = f!
113 assert.same x, 42
114 assert.same y, 42
115 assert.same z, 42
116
117 it "should support != as alias for ~=", ->
118 assert.is_true 1 != 2
119 assert.is_false 1 != 1
120
121 it "should work with :: for method chaining", ->
122 obj =
123 value: 10
124 add: (n) => @value += n
125 get: => @value
126
127 result = obj::add 5::get!
128 assert.same result, 15
129
130 it "should handle complex expressions with precedence", ->
131 result = 1 + 2 * 3 - 4 / 2
132 assert.same result, 5
133
134 it "should support mixed operator types", ->
135 result = 10 + 20 * 2 - 5 / 5
136 assert.same result, 49
diff --git a/spec/inputs/test/param_destructure_spec.yue b/spec/inputs/test/param_destructure_spec.yue
new file mode 100644
index 0000000..4659031
--- /dev/null
+++ b/spec/inputs/test/param_destructure_spec.yue
@@ -0,0 +1,110 @@
1describe "parameter destructuring", ->
2 it "should destructure simple object", ->
3 f = (:a, :b, :c) ->
4 {a, b, c}
5
6 result = f a: 1, b: "2", c: {}
7 assert.same result, {1, "2", {}}
8
9 it "should work with default values", ->
10 f = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
11 {a1, b, c}
12
13 result1 = f {a: 0}, "test"
14 assert.same result1, {0, 'abc', 'test'}
15
16 result2 = f {}
17 assert.same result2, {123, 'abc', {}}
18
19 it "should destructure with mixed syntax", ->
20 f = (:a, b: b1, :c) ->
21 {a, b1, c}
22
23 result = f a: 1, b: 2, c: 3
24 assert.same result, {1, 2, 3}
25
26 it "should work with nested destructuring", ->
27 f = ({nested: {:x, :y}}) ->
28 {x, y}
29
30 result = f nested: {x: 10, y: 20}
31 assert.same result, {10, 20}
32
33 it "should handle array parameters", ->
34 f = ([a, b, c]) ->
35 {a, b, c}
36
37 result = f [1, 2, 3]
38 assert.same result, {1, 2, 3}
39
40 it "should support mixed array and object", ->
41 f = ([first], {key: :value}) ->
42 {first, value}
43
44 result = f [1], {key: "test"}
45 assert.same result, {1, "test"}
46
47 it "should work with fat arrow", ->
48 obj =
49 value: 100
50 f: ({:x, :y}) =>
51 @value + x + y
52
53 result = obj\f {x: 10, y: 20}
54 assert.same result, 130
55
56 it "should handle missing keys", ->
57 f = (:a, :b = "default", :c = "missing") ->
58 {a, b, c}
59
60 result = f a: 1
61 assert.same result, {1, 'default', 'missing'}
62
63 it "should work with complex defaults", ->
64 f = ({a: a1 = 100, b: b1 = a1 + 1000}) ->
65 a1 + b1
66
67 result = f {}
68 assert.same result, 1200
69
70 it "should support deep nesting", ->
71 f = ({data: {nested: {:value}}}) ->
72 value
73
74 result = f data: {nested: {value: 42}}
75 assert.same result, 42
76
77 it "should work with multiple parameters", ->
78 f = (:x, :y, :z, extra = "default") ->
79 {x, y, z, extra}
80
81 result = f x: 1, y: 2, z: 3
82 assert.same result, {1, 2, 3, 'default'}
83
84 it "should handle array destructuring in parameters", ->
85 f = ([first, ...rest]) ->
86 {first, rest}
87
88 result = f [1, 2, 3, 4]
89 assert.same result, {1, {2, 3, 4}}
90
91 it "should support spreading", ->
92 f = (...rest, :last) ->
93 {rest, last}
94
95 result = f 1, 2, 3, {last: "final"}
96 assert.same result, {{1, 2, 3}, 'final'}
97
98 it "should work with table comprehensions", ->
99 f = ({:items}) ->
100 [item * 2 for item in *items]
101
102 result = f items: {1, 2, 3}
103 assert.same result, {2, 4, 6}
104
105 it "should handle nil arguments", ->
106 f = (:a = "nil_a", :b = "nil_b") ->
107 {a, b}
108
109 result = f nil, nil
110 assert.same result, {'nil_a', 'nil_b'}
diff --git a/spec/inputs/test/prefixed_return_spec.yue b/spec/inputs/test/prefixed_return_spec.yue
new file mode 100644
index 0000000..027cd60
--- /dev/null
+++ b/spec/inputs/test/prefixed_return_spec.yue
@@ -0,0 +1,48 @@
1describe "prefixed return", ->
2 it "should return prefixed value with no explicit return", ->
3 findFirstEven = (list): nil ->
4 for item in *list
5 if type(item) == "table"
6 for sub in *item
7 if sub % 2 == 0
8 return sub
9
10 result = findFirstEven {1, 3, {4, 6}, 5}
11 assert.same result, 4
12
13 it "should return prefixed nil when not found", ->
14 findValue = (list): nil ->
15 for item in *list
16 if item == 999
17 return item
18
19 result = findValue {1, 2, 3}
20 assert.same result, nil
21
22 it "should return prefixed string", ->
23 findName = (items): "not found" ->
24 for item in *items
25 if item.name == "target"
26 return item.name
27
28 result = findName [{name: "a"}, {name: "b"}]
29 assert.same result, "not found"
30
31 it "should return prefixed number", ->
32 calculateSum = (): 0 ->
33 -- no explicit return
34 total = 0
35
36 result = calculateSum!
37 assert.same result, 0
38
39 it "should work with nested logic", ->
40 findNested = (data): "missing" ->
41 for category in *data
42 if type(category) == "table"
43 for item in *category
44 if item == "target"
45 return "found"
46
47 result = findNested {{1, 2}, {"target", 3}}
48 assert.same result, "found"
diff --git a/spec/inputs/test/reverse_index_spec.yue b/spec/inputs/test/reverse_index_spec.yue
new file mode 100644
index 0000000..be67261
--- /dev/null
+++ b/spec/inputs/test/reverse_index_spec.yue
@@ -0,0 +1,59 @@
1describe "reverse index", ->
2 it "should get last element", ->
3 data = {items: [1, 2, 3, 4, 5]}
4 last = data.items[#]
5 assert.same last, 5
6
7 it "should get second last element", ->
8 data = {items: [1, 2, 3, 4, 5]}
9 second_last = data.items[#-1]
10 assert.same second_last, 4
11
12 it "should get third last element", ->
13 data = {items: [1, 2, 3, 4, 5]}
14 third_last = data.items[#-2]
15 assert.same third_last, 3
16
17 it "should set last element", ->
18 data = {items: [1, 2, 3, 4, 5]}
19 data.items[#] = 10
20 assert.same data.items[5], 10
21
22 it "should set second last element", ->
23 data = {items: [1, 2, 3, 4, 5]}
24 data.items[#-1] = 20
25 assert.same data.items[4], 20
26
27 it "should work with single element", ->
28 tab = {42}
29 assert.same tab[#], 42
30
31 it "should work with empty table", ->
32 tab = []
33 assert.same tab[#], nil
34
35 it "should work in expressions", ->
36 tab = [1, 2, 3, 4, 5]
37 result = tab[#] + tab[#-1]
38 assert.same result, 9
39
40 it "should support chaining", ->
41 data = {items: {nested: [1, 2, 3]}}
42 last = data.items.nested[#]
43 assert.same last, 3
44
45 it "should work with string", ->
46 s = "hello"
47 assert.same s[#], "o"
48
49 it "should handle negative offsets", ->
50 tab = [1, 2, 3, 4, 5]
51 assert.same tab[#-3], 2
52 assert.same tab[#-4], 1
53
54 it "should work in loops", ->
55 tab = [1, 2, 3, 4, 5]
56 results = []
57 for i = 0, 2
58 table.insert results, tab[#-i]
59 assert.same results, {5, 4, 3}
diff --git a/spec/inputs/test/slicing_spec.yue b/spec/inputs/test/slicing_spec.yue
new file mode 100644
index 0000000..b0a686b
--- /dev/null
+++ b/spec/inputs/test/slicing_spec.yue
@@ -0,0 +1,77 @@
1describe "slicing", ->
2 it "should slice array with basic syntax", ->
3 items = [1, 2, 3, 4, 5]
4 result = items[1..3]
5 assert.same result, {1, 2, 3}
6
7 it "should slice from beginning", ->
8 items = [1, 2, 3, 4, 5]
9 result = items[1..#items]
10 assert.same result, {1, 2, 3, 4, 5}
11
12 it "should slice to end", ->
13 items = [1, 2, 3, 4, 5]
14 result = items[3..5]
15 assert.same result, {3, 4, 5}
16
17 it "should handle negative indices", ->
18 items = [1, 2, 3, 4, 5]
19 result = items[#items-2..#items]
20 assert.same result, {3, 4, 5}
21
22 it "should slice single element", ->
23 items = [1, 2, 3, 4, 5]
24 result = items[2..2]
25 assert.same result, {2}
26
27 it "should work with strings", ->
28 s = "hello"
29 result = s\sub 1, 3
30 assert.same result, "hel"
31
32 it "should handle out of bounds", ->
33 items = [1, 2, 3]
34 result = items[1..10]
35 assert.same result, {1, 2, 3}
36
37 it "should create new table", ->
38 original = [1, 2, 3, 4, 5]
39 sliced = original[2..4]
40 sliced[1] = 99
41 assert.same original[2], 2 -- original unchanged
42
43 it "should work with nested arrays", ->
44 nested = [[1, 2], [3, 4], [5, 6]]
45 result = nested[1..2]
46 assert.same result, {{1, 2}, {3, 4}}
47
48 it "should slice with step simulation", ->
49 items = [1, 2, 3, 4, 5]
50 result = [items[i] for i = 1, #items, 2]
51 assert.same result, {1, 3, 5}
52
53 it "should handle empty slice range", ->
54 items = [1, 2, 3, 4, 5]
55 result = items[6..10]
56 assert.same result, nil
57
58 it "should work with reverse indexing", ->
59 items = [1, 2, 3, 4, 5]
60 last = items[#]
61 second_last = items[#-1]
62 assert.same last, 5
63 assert.same second_last, 4
64
65 it "should support slice in assignment", ->
66 items = [1, 2, 3, 4, 5]
67 [a, b, c] = [items[i] for i in *{1, 2, 3}]
68 assert.same a, 1
69 assert.same b, 2
70 assert.same c, 3
71
72 it "should work with table comprehensions", ->
73 items = [1, 2, 3, 4, 5]
74 result = {i, items[i] for i = 2, 4}
75 assert.same result[2], 2
76 assert.same result[3], 3
77 assert.same result[4], 4
diff --git a/spec/inputs/test/stub_spec.yue b/spec/inputs/test/stub_spec.yue
new file mode 100644
index 0000000..99345c7
--- /dev/null
+++ b/spec/inputs/test/stub_spec.yue
@@ -0,0 +1,109 @@
1describe "function stub", ->
2 it "should create empty function", ->
3 stub_fn!
4 assert.is_true true
5
6 it "should support stub in table", ->
7 obj = {
8 stub: stub_fn!
9 }
10 assert.is_true true
11
12 it "should work with method stub", ->
13 obj =
14 method: stub_fn!
15 assert.is_true true
16
17 it "should handle stub in assignment", ->
18 my_func = stub_fn!
19 assert.is_true true
20
21 it "should support stub in return", ->
22 get_stub = -> stub_fn!
23 fn = get_stub!
24 assert.is_true true
25
26 it "should work in conditional", ->
27 if stub_fn!
28 assert.is_true true
29
30 it "should support stub as callback", ->
31 call_fn = (fn) -> fn!
32 result = call_fn stub_fn!
33 assert.is_true true
34
35 it "should handle stub in table literal", ->
36 tb = {
37 on_click: stub_fn!
38 on_hover: stub_fn!
39 }
40 assert.is_true true
41
42 it "should work with fat arrow stub", ->
43 obj =
44 value: 10
45 method: stub_fn!
46
47 result = obj\method!
48 assert.is_true true
49
50 it "should support stub in array", ->
51 callbacks = [stub_fn!, stub_fn!, stub_fn!]
52 assert.same #callbacks, 3
53
54 it "should handle stub in expression", ->
55 result = stub_fn! and true or false
56 assert.is_true result
57
58 it "should work with chained stub calls", ->
59 stub_fn!
60 stub_fn!
61 stub_fn!
62 assert.is_true true
63
64 it "should support stub in comprehension", ->
65 result = [stub_fn! for i = 1, 3]
66 assert.same #result, 3
67
68 it "should handle stub in switch", ->
69 value = "test"
70 result = switch value
71 when "test"
72 stub_fn!
73 "matched"
74 else
75 "not matched"
76 assert.same result, "matched"
77
78 it "should work in with statement", ->
79 obj = {stub: stub_fn!}
80 with obj
81 .stub!
82 assert.is_true true
83
84 it "should support stub as argument default", ->
85 fn = (callback = stub_fn!) ->
86 callback!
87
88 result = fn!
89 assert.is_true true
90
91 it "should handle stub in varargs", ->
92 collect = (...) ->
93 {...}
94
95 result = collect stub_fn!, stub_fn!
96 assert.same #result, 2
97
98 it "should work in do block", ->
99 do
100 stub_fn!
101 assert.is_true true
102
103 it "should support stub in try block", ->
104 success = try
105 stub_fn!
106 true
107 catch err
108 false
109 assert.is_true success
diff --git a/spec/inputs/test/table_append_spec.yue b/spec/inputs/test/table_append_spec.yue
new file mode 100644
index 0000000..ab3d6d2
--- /dev/null
+++ b/spec/inputs/test/table_append_spec.yue
@@ -0,0 +1,77 @@
1describe "table append", ->
2 it "should append single value", ->
3 tab = []
4 tab[] = "Value"
5 assert.same tab[1], "Value"
6 assert.same #tab, 1
7
8 it "should append multiple values", ->
9 tab = []
10 tab[] = 1
11 tab[] = 2
12 tab[] = 3
13 assert.same tab, {1, 2, 3}
14
15 it "should append with spread operator", ->
16 tbA = [1, 2, 3]
17 tbB = [4, 5, 6]
18 tbA[] = ...tbB
19 assert.same tbA, {1, 2, 3, 4, 5, 6}
20
21 it "should append table with single element", ->
22 tab = [1, 2]
23 tb2 = {3}
24 tab[] = table.unpack tb2
25 assert.same tab, {1, 2, 3}
26
27 it "should append empty table", ->
28 tab = [1, 2]
29 tb2 = []
30 tab[] = ...tb2
31 assert.same tab, {1, 2}
32
33 it "should append nil values", ->
34 tab = []
35 tab[] = nil
36 tab[] = "value"
37 assert.same tab[1], nil
38 assert.same tab[2], "value"
39
40 it "should work in loop", ->
41 tab = []
42 for i = 1, 3
43 tab[] = i * 2
44 assert.same tab, {2, 4, 6}
45
46 it "should append with expressions", ->
47 tab = []
48 x = 10
49 tab[] = x + 5
50 assert.same tab[1], 15
51
52 it "should append mixed types", ->
53 tab = []
54 tab[] = "string"
55 tab[] = 123
56 tab[] = true
57 tab[] = nil
58 assert.same tab, {"string", 123, true, nil}
59
60 it "should append to table with existing elements", ->
61 tab = [1, 2, 3]
62 tab[] = 4
63 tab[] = 5
64 assert.same tab, {1, 2, 3, 4, 5}
65
66 it "should work with nested tables", ->
67 tab = []
68 tab[] = {a: 1, b: 2}
69 tab[] = [3, 4]
70 assert.same tab[1], {a: 1, b: 2}
71 assert.same tab[2], [3, 4]
72
73 it "should append function results", ->
74 fn = -> 1, 2, 3
75 tab = []
76 tab[] = fn!
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
new file mode 100644
index 0000000..f4d7cdb
--- /dev/null
+++ b/spec/inputs/test/table_comprehension_spec.yue
@@ -0,0 +1,127 @@
1describe "table comprehension", ->
2 it "should create simple table copy", ->
3 thing = {
4 color: "red"
5 name: "fast"
6 width: 123
7 }
8
9 thing_copy = {k, v for k, v in pairs thing}
10 assert.same thing_copy.color, thing.color
11 assert.same thing_copy.name, thing.name
12 assert.same thing_copy.width, thing.width
13
14 it "should filter with when clause", ->
15 thing = {
16 color: "red"
17 name: "fast"
18 width: 123
19 }
20
21 no_color = {k, v for k, v in pairs thing when k != "color"}
22 assert.same no_color.color, nil
23 assert.same no_color.name, "fast"
24 assert.same no_color.width, 123
25
26 it "should transform values", ->
27 numbers = {a: 1, b: 2, c: 3}
28 doubled = {k, v * 2 for k, v in pairs numbers}
29 assert.same doubled.a, 2
30 assert.same doubled.b, 4
31 assert.same doubled.c, 6
32
33 it "should transform keys", ->
34 data = {a: 1, b: 2}
35 upper_keys = {k\upper!, v for k, v in pairs data}
36 assert.same upper_keys.A, 1
37 assert.same upper_keys.B, 2
38
39 it "should work with ipairs", ->
40 items = {"a", "b", "c"}
41 reversed = {i, v for i, v in ipairs items}
42 assert.same reversed[1], "a"
43 assert.same reversed[2], "b"
44 assert.same reversed[3], "c"
45
46 it "should filter array items", ->
47 items = {1, 2, 3, 4, 5}
48 evens = {i, v for i, v in ipairs items when v % 2 == 0}
49 assert.same evens[2], 2
50 assert.same evens[4], 4
51 assert.same evens[1], nil
52
53 it "should work with numeric for loop", ->
54 squares = {i, i * i for i = 1, 5}
55 assert.same squares[1], 1
56 assert.same squares[2], 4
57 assert.same squares[3], 9
58 assert.same squares[4], 16
59 assert.same squares[5], 25
60
61 it "should support nested comprehensions", ->
62 matrix = {{1, 2}, {3, 4}, {5, 6}}
63 flat = {}
64 for row in *matrix
65 for i, v in ipairs row
66 flat[#flat + 1] = v
67
68 assert.same flat, {1, 2, 3, 4, 5, 6}
69
70 it "should combine pairs and when", ->
71 data = {a: 1, b: 2, c: 3, d: 4}
72 greater_than_two = {k, v for k, v in pairs data when v > 2}
73 assert.same greater_than_two.a, nil
74 assert.same greater_than_two.b, nil
75 assert.same greater_than_two.c, 3
76 assert.same greater_than_two.d, 4
77
78 it "should work with string keys", ->
79 obj = {["key-with-dash"]: "value1", ["key_with_underscore"]: "value2"}
80 result = {k, v for k, v in pairs obj}
81 assert.same result["key-with-dash"], "value1"
82 assert.same result["key_with_underscore"], "value2"
83
84 it "should handle empty source", ->
85 empty = {}
86 result = {k, v for k, v in pairs empty}
87 assert.same #result, 0
88
89 it "should work with computed keys", ->
90 base = {a: 1, b: 2}
91 result = {k .. "_suffix", v * 10 for k, v in pairs base}
92 assert.same result.a_suffix, 10
93 assert.same result.b_suffix, 20
94
95 it "should support nested table transformation", ->
96 data = {
97 first: {x: 1, y: 2}
98 second: {x: 3, y: 4}
99 }
100
101 transformed = {k, v.x + v.y for k, v in pairs data}
102 assert.same transformed.first, 3
103 assert.same transformed.second, 7
104
105 it "should filter with multiple conditions", ->
106 numbers = {a: 1, b: 2, c: 3, d: 4, e: 5}
107 result = {k, v for k, v in pairs numbers when v > 1 and v < 5}
108 assert.same result.a, nil
109 assert.same result.b, 2
110 assert.same result.c, 3
111 assert.same result.d, 4
112 assert.same result.e, nil
113
114 it "should work with custom iterator", ->
115 custom_iter = -> ->
116 state = 0
117 ->
118 state += 1
119 if state <= 3
120 state, state * 10
121 else
122 nil
123
124 result = {k, v for k, v in custom_iter!}
125 assert.same result[1], 10
126 assert.same result[2], 20
127 assert.same result[3], 30
diff --git a/spec/inputs/test/tables_advanced_spec.yue b/spec/inputs/test/tables_advanced_spec.yue
new file mode 100644
index 0000000..c8cc7d5
--- /dev/null
+++ b/spec/inputs/test/tables_advanced_spec.yue
@@ -0,0 +1,153 @@
1describe "advanced tables", ->
2 it "should create table with implicit keys", ->
3 hair = "golden"
4 height = 200
5 person = { :hair, :height, shoe_size: 40 }
6 assert.same person.hair, "golden"
7 assert.same person.height, 200
8
9 it "should work with computed keys", ->
10 t = {
11 [1 + 2]: "hello"
12 ["key_" .. "suffix"]: "value"
13 }
14 assert.same t[3], "hello"
15 assert.same t["key_suffix"], "value"
16
17 it "should support keyword keys", ->
18 tbl = {
19 do: "something"
20 end: "hunger"
21 function: "test"
22 }
23 assert.same tbl.do, "something"
24 assert.same tbl.end, "hunger"
25 assert.same tbl.function, "test"
26
27 it "should handle array syntax with mixed content", ->
28 tb = {
29 1, 2, 3
30 name: "superman"
31 4, 5, 6
32 }
33 assert.same tb[1], 1
34 assert.same tb.name, "superman"
35 assert.same tb[4], 4
36
37 it "should work with single line table literals", ->
38 my_function dance: "Tango", partner: "none"
39 assert.is_true true
40
41 it "should support nested tables", ->
42 tb =
43 outer:
44 inner:
45 value: 42
46 assert.same tb.outer.inner.value, 42
47
48 it "should handle table without braces", ->
49 profile =
50 height: "4 feet"
51 shoe_size: 13
52 favorite_foods: ["ice cream", "donuts"]
53 assert.same profile.height, "4 feet"
54 assert.same profile.shoe_size, 13
55
56 it "should work with colon syntax for keys", ->
57 t = {
58 name: "Bill"
59 age: 200
60 ["favorite food"]: "rice"
61 }
62 assert.same t.name, "Bill"
63 assert.same t["favorite food"], "rice"
64
65 it "should support implicit object in table", ->
66 tb =
67 name: "abc"
68 values:
69 - "a"
70 - "b"
71 - "c"
72 assert.same tb.values, {"a", "b", "c"}
73
74 it "should handle array only table", ->
75 some_values = [1, 2, 3, 4]
76 assert.same some_values[1], 1
77 assert.same some_values[4], 4
78
79 it "should work with trailing comma", ->
80 list_with_one = [1,]
81 assert.same list_with_one[1], 1
82
83 it "should support table spreading", ->
84 a = {1, 2, 3, x: 1}
85 b = {4, 5, y: 1}
86 merge = {...a, ...b}
87 assert.same merge[1], 1
88 assert.same merge[4], 4
89 assert.same merge.x, 1
90 assert.same merge.y, 1
91
92 it "should handle mixed spread", ->
93 parts = {
94 * "shoulders"
95 * "knees"
96 }
97 lyrics =
98 * "head"
99 * ...parts
100 * "and"
101 * "toes"
102 assert.same lyrics, {"head", "shoulders", "knees", "and", "toes"}
103
104 it "should work with metatable creation", ->
105 mt = {}
106 add = (right) => <>: mt, value: @value + right.value
107 mt.__add = add
108
109 a = <>: mt, value: 1
110 b = value: 2
111 b.<>, mt
112 c = a + b
113 assert.same c.value, 3
114
115 it "should support metatable accessing", ->
116 tb = <"value">: 123
117 tb.<index> = tb.<>
118 assert.same tb.value, 123
119
120 it "should handle metatable destructuring", ->
121 tb = {
122 item: "test"
123 new: -> "created"
124 close: -> "closed"
125 }
126 {:item, :new, :<close>} = tb
127 assert.same item, "test"
128 assert.same new!, "created"
129
130 it "should work with string keys directly", ->
131 t = {
132 "hello world": true
133 "test-key": "value"
134 }
135 assert.is_true t["hello world"]
136 assert.same t["test-key"], "value"
137
138 it "should support number keys", ->
139 t = {
140 [10]: "ten"
141 [20]: "twenty"
142 }
143 assert.same t[10], "ten"
144 assert.same t[20], "twenty"
145
146 it "should handle empty tables", ->
147 empty = {}
148 assert.same #empty, 0
149
150 it "should work with table literals in function calls", ->
151 fn = (tb) -> tb.x + tb.y
152 result = fn x: 10, y: 20
153 assert.same result, 30
diff --git a/spec/inputs/test/varargs_assignment_spec.yue b/spec/inputs/test/varargs_assignment_spec.yue
new file mode 100644
index 0000000..1c3b627
--- /dev/null
+++ b/spec/inputs/test/varargs_assignment_spec.yue
@@ -0,0 +1,96 @@
1describe "varargs assignment", ->
2 it "should assign varargs from function", ->
3 list = [1, 2, 3, 4, 5]
4 fn = (ok) -> ok, table.unpack list
5 ok, ... = fn true
6 count = select '#', ...
7 assert.same count, 5
8 assert.same ok, true
9
10 it "should access varargs elements", ->
11 list = [10, 20, 30]
12 fn = -> table.unpack list
13 ... = fn!
14 first = select 1, ...
15 second = select 2, ...
16 third = select 3, ...
17 assert.same first, 10
18 assert.same second, 20
19 assert.same third, 30
20
21 it "should work with pcall", ->
22 fn = -> 1, 2, 3
23 success, ... = pcall fn
24 assert.is_true success
25 assert.same select('#', ...), 3
26
27 it "should handle empty varargs", ->
28 fn = ->
29 ... = fn!
30 count = select '#', ...
31 assert.same count, 0
32
33 it "should work with mixed return values", ->
34 fn = -> "first", nil, "third", false
35 a, ... = fn!
36 assert.same a, "first"
37 assert.same select('#', ...), 3
38
39 it "should preserve nil values in varargs", ->
40 fn = -> 1, nil, 2, nil, 3
41 ... = fn!
42 count = select '#', ...
43 assert.same count, 5
44 assert.same select(1, ...), 1
45 assert.same select(2, ...), nil
46 assert.same select(3, ...), 2
47
48 it "should work with table.unpack", ->
49 tb = {a: 1, b: 2, c: 3}
50 fn = -> table.unpack tb
51 ... = fn!
52 count = select '#', ...
53 assert.same count, 3
54
55 it "should chain varargs assignment", ->
56 fn1 = -> 1, 2, 3
57 fn2 = -> table.unpack {4, 5, 6}
58 a, ... = fn1!
59 b, ... = fn2!
60 assert.same a, 1
61 assert.same b, 4
62 assert.same select('#', ...), 2
63
64 it "should work in expressions", ->
65 sum = (...) ->
66 total = 0
67 for i = 1, select '#', ...
68 total += select i, ... if type(select(i, ...)) == "number"
69 total
70
71 fn = -> 1, 2, 3, 4, 5
72 ... = fn!
73 result = sum ...
74 assert.same result, 15
75
76 it "should work with string.format", ->
77 ... = "hello", 123, true
78 result = string.format "str: %s, num: %d, bool: %s", ...
79 assert.same result, "str: hello, num: 123, bool: true"
80
81 it "should handle single return value", ->
82 fn = -> 42
83 ... = fn!
84 count = select '#', ...
85 assert.same count, 1
86 assert.same select(1, ...), 42
87
88 it "should work with nested functions", ->
89 outer = -> 1, 2, 3
90 inner = -> 4, 5
91 a, b, ... = outer!
92 c, d = inner!
93 assert.same a, 1
94 assert.same b, 2
95 assert.same c, 4
96 assert.same d, 5
diff --git a/spec/inputs/test/while_assignment_spec.yue b/spec/inputs/test/while_assignment_spec.yue
new file mode 100644
index 0000000..1c98e58
--- /dev/null
+++ b/spec/inputs/test/while_assignment_spec.yue
@@ -0,0 +1,42 @@
1describe "while assignment", ->
2 it "should loop while value is truthy", ->
3 counter = 0
4 get_next = ->
5 if counter < 3
6 counter += 1
7 counter
8 else
9 nil
10 results = {}
11 while val := get_next!
12 table.insert results, val
13 assert.same results, {1, 2, 3}
14
15 it "should work with function results", ->
16 counter = 0
17 fn = ->
18 counter += 1
19 if counter <= 3
20 counter * 10
21 else
22 nil
23
24 sum = 0
25 while val := fn!
26 sum += val
27 assert.same sum, 60 -- (10+20+30)
28
29 it "should exit immediately on nil", ->
30 get_val = -> nil
31 counter = 0
32 while val := get_val!
33 counter += 1
34 assert.same counter, 0
35
36 it "should support break in loop", ->
37 items = {1, 2, 3, 4, 5}
38 sum = 0
39 for item in *items
40 sum += item
41 break if sum > 6
42 assert.same sum, 10
diff --git a/spec/inputs/test/whitespace_spec.yue b/spec/inputs/test/whitespace_spec.yue
new file mode 100644
index 0000000..baf3fd5
--- /dev/null
+++ b/spec/inputs/test/whitespace_spec.yue
@@ -0,0 +1,118 @@
1describe "whitespace", ->
2 it "should support semicolon statement separator", ->
3 a = 1; b = 2; result = a + b
4 assert.same result, 3
5
6 it "should handle multiple statements on one line", ->
7 x = 10; y = 20; z = x + y
8 assert.same z, 30
9
10 it "should work with semicolon in function", ->
11 fn = -> a = 1; b = 2; a + b
12 assert.same fn!, 3
13
14 it "should support multiline chaining", ->
15 obj =
16 value: 10
17 add: (n) => @value += n
18 get: => @value
19
20 result = obj
21 \add 5
22 \add 10
23 \get!
24 assert.same result, 25
25
26 it "should handle multiline method calls", ->
27 str = " hello "
28 result = str
29 \trim!
30 \upper!
31 assert.same result, "HELLO"
32
33 it "should work with nested chaining", ->
34 obj =
35 level1:
36 level2:
37 level3: => "deep"
38
39 result = obj
40 .level1
41 .level2
42 \level3!
43 assert.same result, "deep"
44
45 it "should support chaining with conditionals", ->
46 obj =
47 value: 10
48 isPositive: => @value > 0
49
50 result = obj
51 \isPositive!
52 assert.is_true result
53
54 it "should work with pipe in chaining", ->
55 result = [1, 2, 3]
56 |> [x * 2 for x in *]
57 |> table.concat
58 assert.same result, "246"
59
60 it "should handle mixed separators", ->
61 a = 1; b = 2
62 c = 3
63 d = 4
64 result = a + b + c + d
65 assert.same result, 10
66
67 it "should support indentation with spaces", ->
68 fn = ->
69 if true
70 result = 10
71 result
72
73 assert.same fn!, 10
74
75 it "should work with consistent indentation", ->
76 tb = {
77 a: 1
78 b: 2
79 nested:
80 c: 3
81 d: 4
82 }
83 assert.same tb.a, 1
84 assert.same tb.nested.c, 3
85
86 it "should handle semicolon with comments", ->
87 a = 1; -- comment
88 b = 2; -- another comment
89 result = a + b
90 assert.same result, 3
91
92 it "should work in multiline function call", ->
93 sum = (a, b) -> a + b
94 result = sum 5, 10,
95 sum 3, 7
96 assert.same result, 25
97
98 it "should support chaining in assignment", ->
99 obj =
100 value: 5
101 double: => @value * 2
102
103 doubled = obj
104 \double!
105 assert.same doubled, 10
106
107 it "should handle complex chaining", ->
108 result = "hello"
109 \upper!
110 \sub 1, 3
111 \lower!
112 assert.same result, "hel"
113
114 it "should work with backcalls and whitespace", ->
115 results = do
116 data <- readAsync "data.txt"
117 process data
118 assert.is_true true
diff --git a/spec/inputs/test/with_statement_spec.yue b/spec/inputs/test/with_statement_spec.yue
new file mode 100644
index 0000000..c2f9b3b
--- /dev/null
+++ b/spec/inputs/test/with_statement_spec.yue
@@ -0,0 +1,145 @@
1describe "with statement", ->
2 it "should access properties with dot", ->
3 obj = {x: 10, y: 20}
4 result = nil
5 with obj
6 result = .x + .y
7 assert.same result, 30
8
9 it "should chain property access", ->
10 obj = {nested: {value: 42}}
11 result = nil
12 with obj
13 result = .nested.value
14 assert.same result, 42
15
16 it "should work with method calls", ->
17 obj =
18 value: 10
19 double: => @value * 2
20
21 result = nil
22 with obj
23 result = \double!
24 assert.same result, 20
25
26 it "should handle nested with statements", ->
27 obj = {x: 1}
28 with obj
29 .x = 10
30 with .nested = {y: 2}
31 .y = 20
32 assert.same obj.x, 10
33 assert.same obj.nested.y, 20
34
35 it "should work in expressions", ->
36 obj = {value: 5}
37 result = with obj
38 .value * 2
39 assert.same result, 10
40
41 it "should support multiple statements", ->
42 obj = {a: 1, b: 2}
43 sum = nil
44 product = nil
45 with obj
46 sum = .a + .b
47 product = .a * .b
48 assert.same sum, 3
49 assert.same product, 2
50
51 it "should work with table manipulation", ->
52 obj = {items: [1, 2, 3]}
53 with obj
54 table.insert .items, 4
55 assert.same #obj.items, 4
56
57 it "should handle conditional inside with", ->
58 obj = {value: 10}
59 result = nil
60 with obj
61 if .value > 5
62 result = "large"
63 else
64 result = "small"
65 assert.same result, "large"
66
67 it "should work with loops", ->
68 obj = {items: [1, 2, 3]}
69 sum = nil
70 with obj
71 sum = 0
72 for item in *.items
73 sum += item
74 assert.same sum, 6
75
76 it "should support with in assignment", ->
77 obj = {x: 5, y: 10}
78 result = with obj
79 .x + .y
80 assert.same result, 15
81
82 it "should work with string methods", ->
83 s = "hello"
84 result = with s
85 \upper!
86 assert.same result, "HELLO"
87
88 it "should handle metatable access", ->
89 obj = setmetatable {value: 10}, {
90 __index: {extra: 5}
91 }
92 sum = nil
93 with obj
94 sum = .value + .<index>.extra
95 assert.same sum, 15
96
97 it "should work in function", ->
98 fn = ->
99 obj = {x: 10}
100 with obj
101 .x * 2
102
103 result = fn!
104 assert.same result, 20
105
106 it "should support with in return", ->
107 get_value = ->
108 obj = {value: 42}
109 with obj
110 .value
111
112 assert.same get_value!, 42
113
114 it "should work with existential operator", ->
115 obj = {value: 10}
116 result = with obj
117 .value ? 0
118 assert.same result, 10
119
120 it "should handle nil object safely", ->
121 result = with nil
122 .value
123 assert.same result, nil
124
125 it "should work with method chaining", ->
126 obj =
127 value: 5
128 add: (n) => @value += n
129 get: => @value
130
131 result = with obj
132 \add 10
133 \add 5
134 \get!
135 assert.same result, 20
136
137 it "should support nested property access", ->
138 obj =
139 level1:
140 level2:
141 level3: "deep"
142
143 result = with obj
144 .level1.level2.level3
145 assert.same result, "deep"
diff --git a/spec/inputs/test/yaml_string_spec.yue b/spec/inputs/test/yaml_string_spec.yue
new file mode 100644
index 0000000..1296340
--- /dev/null
+++ b/spec/inputs/test/yaml_string_spec.yue
@@ -0,0 +1,112 @@
1describe "yaml string", ->
2 it "should create basic yaml string", ->
3 s = |
4 hello
5 world
6 assert.is_true s\match "hello"
7 assert.is_true s\match "world"
8
9 it "should preserve indentation", ->
10 s = |
11 key1: value1
12 key2: value2
13 assert.is_true s\match "key1"
14 assert.is_true s\match "key2"
15
16 it "should support interpolation", ->
17 name = "test"
18 s = |
19 hello #{name}
20 assert.same s, "hello test"
21
22 it "should handle complex interpolation", ->
23 x, y = 10, 20
24 s = |
25 point:
26 x: #{x}
27 y: #{y}
28 assert.is_true s\match "x: 10"
29 assert.is_true s\match "y: 20"
30
31 it "should work with expressions", ->
32 s = |
33 result: #{1 + 2}
34 assert.is_true s\match "result: 3"
35
36 it "should support multiline with variables", ->
37 config = |
38 database:
39 host: localhost
40 port: 5432
41 name: mydb
42 assert.is_true config\match "database:"
43 assert.is_true config\match "host:"
44
45 it "should escape special characters", ->
46 s = |
47 path: "C:\Program Files\App"
48 note: 'He said: "#{Hello}!"'
49 assert.is_true s\match "path:"
50 assert.is_true s\match "note:"
51
52 it "should work in function", ->
53 fn = ->
54 str = |
55 foo:
56 bar: baz
57 return str
58
59 result = fn!
60 assert.is_true result\match "foo:"
61 assert.is_true result\match "bar:"
62
63 it "should strip common leading whitespace", ->
64 fn = ->
65 s = |
66 nested:
67 item: value
68 s
69
70 result = fn!
71 assert.is_true result\match "nested:"
72 assert.is_true result\match "item:"
73
74 it "should support empty lines", ->
75 s = |
76 line1
77
78 line3
79 assert.is_true s\match "line1"
80 assert.is_true s\match "line3"
81
82 it "should work with table access in interpolation", ->
83 t = {value: 100}
84 s = |
85 value: #{t.value}
86 assert.is_true s\match "value: 100"
87
88 it "should support function calls in interpolation", ->
89 s = |
90 result: #{(-> 42)!}
91 assert.is_true s\match "result: 42"
92
93 it "should handle quotes correctly", ->
94 s = |
95 "quoted"
96 'single quoted'
97 assert.is_true s\match '"quoted"'
98 assert.is_true s\match "'single quoted'"
99
100 it "should work with multiple interpolations", ->
101 a, b, c = 1, 2, 3
102 s = |
103 values: #{a}, #{b}, #{c}
104 assert.is_true s\match "values: 1, 2, 3"
105
106 it "should preserve newlines", ->
107 s = |
108 first line
109 second line
110 third line
111 lines = [line for line in s\gmatch "[^\n]+"]
112 assert.same #lines, 3
diff --git a/spec/outputs/test/chaining_comparison_spec.lua b/spec/outputs/test/chaining_comparison_spec.lua
new file mode 100644
index 0000000..fe61fae
--- /dev/null
+++ b/spec/outputs/test/chaining_comparison_spec.lua
@@ -0,0 +1,85 @@
1local _anon_func_0 = function()
2 local _cond_0 = "b"
3 if not ("a" < _cond_0) then
4 return false
5 else
6 return _cond_0 < "c"
7 end
8end
9local _anon_func_1 = function()
10 local _cond_0 = "b"
11 if not ("a" <= _cond_0) then
12 return false
13 else
14 return _cond_0 <= "c"
15 end
16end
17local _anon_func_2 = function(v)
18 local _cond_0 = v(2)
19 if not (v(1) < _cond_0) then
20 return false
21 else
22 return _cond_0 < v(3)
23 end
24end
25return describe("chaining comparison", function()
26 it("should support simple chaining", function()
27 assert.is_true(1 < 2 and 2 < 3)
28 assert.is_true(1 <= 2 and 2 <= 3)
29 assert.is_true(3 > 2 and 2 > 1)
30 return assert.is_true(3 >= 2 and 2 >= 1)
31 end)
32 it("should support complex chaining", function()
33 return assert.is_true(1 < 2 and 2 <= 2 and 2 < 3 and 3 == 3 and 3 > 2 and 2 >= 1 and 1 == 1 and 1 < 3 and 3 ~= 5)
34 end)
35 it("should work with variables", function()
36 local a = 5
37 assert.is_true(1 <= a and a <= 10)
38 assert.is_true(a >= 3)
39 return assert.is_true(a <= 10)
40 end)
41 it("should handle mixed comparisons", function()
42 local x = 5
43 assert.is_true(1 < x and x < 10)
44 return assert.is_true(1 <= x and x <= 5)
45 end)
46 it("should work with string comparisons", function()
47 assert.is_true(_anon_func_0())
48 return assert.is_true(_anon_func_1())
49 end)
50 it("should handle edge cases", function()
51 assert.is_true(0 <= 0 and 0 <= 0)
52 return assert.is_true(-5 < 0 and 0 < 5)
53 end)
54 it("should work in expressions", function()
55 local result
56 if 1 < 2 and 2 < 3 then
57 result = "yes"
58 else
59 result = "no"
60 end
61 return assert.same(result, "yes")
62 end)
63 it("should support != operator", function()
64 assert.is_true(1 ~= 2 and 2 ~= 3)
65 return assert.is_true(1 ~= 2 and 2 ~= 3)
66 end)
67 it("should handle boolean results", function()
68 assert.is_true(1 < 2 and 2 < 3)
69 return assert.is_false(3 < 2 and 2 < 1)
70 end)
71 it("should work with function calls", function()
72 local v
73 v = function(x)
74 return x
75 end
76 return assert.is_true(_anon_func_2(v))
77 end)
78 it("should handle negation", function()
79 return assert.is_true(-10 < -5 and -5 < 0)
80 end)
81 return it("should support mixed operators", function()
82 assert.is_true(1 < 2 and 2 <= 2 and 2 < 3)
83 return assert.is_true(3 > 2 and 2 >= 2 and 2 > 1)
84 end)
85end)
diff --git a/spec/outputs/test/if_assignment_spec.lua b/spec/outputs/test/if_assignment_spec.lua
new file mode 100644
index 0000000..7d3b708
--- /dev/null
+++ b/spec/outputs/test/if_assignment_spec.lua
@@ -0,0 +1,171 @@
1return describe("if assignment", function()
2 it("should assign and check truthy value", function()
3 local obj = {
4 find_user = function(name)
5 return name == "valid" and {
6 name = name
7 } or nil
8 end
9 }
10 local user = obj:find_user("valid")
11 if user then
12 return assert.same(user.name, "valid")
13 end
14 end)
15 it("should not enter block when nil", function()
16 local obj = {
17 find_user = function()
18 return nil
19 end
20 }
21 local user = obj:find_user()
22 if user then
23 return assert.is_true(false)
24 else
25 return assert.is_true(true)
26 end
27 end)
28 it("should work with elseif", function()
29 local get_value
30 get_value = function(key)
31 if "a" == key then
32 return 1
33 elseif "b" == key then
34 return 2
35 else
36 return nil
37 end
38 end
39 local result = nil
40 do
41 local val = get_value("c")
42 if val then
43 result = "c: " .. tostring(val)
44 else
45 val = get_value("b")
46 if val then
47 result = "b: " .. tostring(val)
48 else
49 result = "no match"
50 end
51 end
52 end
53 return assert.same(result, "b: 2")
54 end)
55 it("should scope variable to if block", function()
56 do
57 local x = 10
58 if x then
59 assert.same(x, 10)
60 end
61 end
62 return assert.is_true(true)
63 end)
64 it("should work with multiple return values", function()
65 local fn
66 fn = function()
67 return true, "success"
68 end
69 local success, result = fn()
70 if success then
71 assert.is_true(success)
72 return assert.same(result, "success")
73 end
74 end)
75 it("should work with table destructuring", function()
76 local get_point
77 get_point = function()
78 return {
79 x = 10,
80 y = 20
81 }
82 end
83 local _des_0 = get_point()
84 if _des_0 then
85 local x, y = _des_0.x, _des_0.y
86 assert.same(x, 10)
87 return assert.same(y, 20)
88 end
89 end)
90 it("should work with array destructuring", function()
91 local get_coords
92 get_coords = function()
93 return {
94 1,
95 2,
96 3
97 }
98 end
99 local _des_0 = get_coords()
100 if _des_0 then
101 local a, b, c = _des_0[1], _des_0[2], _des_0[3]
102 assert.same(a, 1)
103 assert.same(b, 2)
104 return assert.same(c, 3)
105 end
106 end)
107 it("should chain multiple assignments", function()
108 local a = 1
109 if a then
110 local b = a + 1
111 if b then
112 return assert.same(b, 2)
113 end
114 end
115 end)
116 it("should work in expression context", function()
117 local get_value
118 get_value = function(x)
119 if x > 0 then
120 return x
121 else
122 return nil
123 end
124 end
125 local result
126 do
127 local val = get_value(5)
128 if val then
129 result = val * 2
130 else
131 result = 0
132 end
133 end
134 return assert.same(result, 10)
135 end)
136 it("should work with os.getenv", function()
137 local path = os.getenv("PATH")
138 if path then
139 return assert.is_true(type(path) == "string")
140 else
141 return assert.is_true(true)
142 end
143 end)
144 it("should support table access", function()
145 local tb = {
146 key = "value"
147 }
148 local val = tb.key
149 if val then
150 return assert.same(val, "value")
151 end
152 end)
153 it("should work with function call results", function()
154 local fn
155 fn = function()
156 return "result"
157 end
158 local s = fn()
159 if s then
160 return assert.same(s, "result")
161 end
162 end)
163 return it("should handle false values", function()
164 local val = false
165 if val then
166 return assert.is_true(false)
167 else
168 return assert.is_true(true)
169 end
170 end)
171end)
diff --git a/spec/outputs/test/in_expression_spec.lua b/spec/outputs/test/in_expression_spec.lua
new file mode 100644
index 0000000..fc118c2
--- /dev/null
+++ b/spec/outputs/test/in_expression_spec.lua
@@ -0,0 +1,489 @@
1local _anon_func_0 = function(items)
2 local _val_0 = 3
3 for _index_0 = 1, #items do
4 if items[_index_0] == _val_0 then
5 return true
6 end
7 end
8 return false
9end
10local _anon_func_1 = function(items)
11 local _val_0 = 10
12 for _index_0 = 1, #items do
13 if items[_index_0] == _val_0 then
14 return true
15 end
16 end
17 return false
18end
19local _anon_func_2 = function(chars)
20 local _val_0 = "b"
21 for _index_0 = 1, #chars do
22 if chars[_index_0] == _val_0 then
23 return true
24 end
25 end
26 return false
27end
28local _anon_func_3 = function(chars)
29 local _val_0 = "z"
30 for _index_0 = 1, #chars do
31 if chars[_index_0] == _val_0 then
32 return true
33 end
34 end
35 return false
36end
37local _anon_func_4 = function(obj)
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
66 for _index_0 = 1, #items do
67 if items[_index_0] == _val_0 then
68 return true
69 end
70 end
71 return false
72end
73local _anon_func_8 = function(items)
74 local _val_0 = "two"
75 for _index_0 = 1, #items do
76 if items[_index_0] == _val_0 then
77 return true
78 end
79 end
80 return false
81end
82local _anon_func_9 = function(items)
83 local _val_0 = true
84 for _index_0 = 1, #items do
85 if items[_index_0] == _val_0 then
86 return true
87 end
88 end
89 return false
90end
91local _anon_func_10 = function(items)
92 local _val_0 = false
93 for _index_0 = 1, #items do
94 if items[_index_0] == _val_0 then
95 return true
96 end
97 end
98 return false
99end
100local _anon_func_11 = function(empty)
101 local _val_0 = 1
102 for _index_0 = 1, #empty do
103 if empty[_index_0] == _val_0 then
104 return true
105 end
106 end
107 return false
108end
109local _anon_func_12 = function(empty)
110 local _val_0 = "test"
111 for _index_0 = 1, #empty do
112 if empty[_index_0] == _val_0 then
113 return true
114 end
115 end
116 return false
117end
118local _anon_func_13 = function(items)
119 local _val_0 = 2
120 for _index_0 = 1, #items do
121 if items[_index_0] == _val_0 then
122 return true
123 end
124 end
125 return false
126end
127local _anon_func_14 = function(items)
128 local _val_0 = 4
129 for _index_0 = 1, #items do
130 if items[_index_0] == _val_0 then
131 return true
132 end
133 end
134 return false
135end
136local _anon_func_15 = function(items)
137 local _val_0 = 2
138 for _index_0 = 1, #items do
139 if items[_index_0] == _val_0 then
140 return true
141 end
142 end
143 return false
144end
145local _anon_func_16 = function(nested)
146 local _val_0 = {
147 1,
148 2
149 }
150 for _index_0 = 1, #nested do
151 if nested[_index_0] == _val_0 then
152 return true
153 end
154 end
155 return false
156end
157local _anon_func_17 = function(nested)
158 local _val_0 = {
159 1,
160 3
161 }
162 for _index_0 = 1, #nested do
163 if nested[_index_0] == _val_0 then
164 return true
165 end
166 end
167 return false
168end
169local _anon_func_18 = function(bools)
170 local _val_0 = true
171 for _index_0 = 1, #bools do
172 if bools[_index_0] == _val_0 then
173 return true
174 end
175 end
176 return false
177end
178local _anon_func_19 = function(bools)
179 local _val_0 = false
180 for _index_0 = 1, #bools do
181 if bools[_index_0] == _val_0 then
182 return true
183 end
184 end
185 return false
186end
187local _anon_func_20 = function(i, items)
188 for _index_0 = 1, #items do
189 if items[_index_0] == i then
190 return true
191 end
192 end
193 return false
194end
195local _anon_func_21 = function(key1, tb)
196 for _index_0 = 1, #tb do
197 if tb[_index_0] == key1 then
198 return true
199 end
200 end
201 return false
202end
203local _anon_func_22 = function(key2, tb)
204 for _index_0 = 1, #tb do
205 if tb[_index_0] == key2 then
206 return true
207 end
208 end
209 return false
210end
211local _anon_func_23 = function(get_items)
212 local _check_0 = get_items()
213 local _val_0 = 2
214 for _index_0 = 1, #_check_0 do
215 if _check_0[_index_0] == _val_0 then
216 return true
217 end
218 end
219 return false
220end
221local _anon_func_24 = function(get_items)
222 local _check_0 = get_items()
223 local _val_0 = 5
224 for _index_0 = 1, #_check_0 do
225 if _check_0[_index_0] == _val_0 then
226 return true
227 end
228 end
229 return false
230end
231local _anon_func_25 = function(items)
232 local _val_0 = nil
233 for _index_0 = 1, #items do
234 if items[_index_0] == _val_0 then
235 return true
236 end
237 end
238 return false
239end
240local _anon_func_26 = function(items)
241 local _val_0 = 1
242 for _index_0 = 1, #items do
243 if items[_index_0] == _val_0 then
244 return true
245 end
246 end
247 return false
248end
249local _anon_func_27 = function(obj)
250 local _val_0 = "name"
251 for _index_0 = 1, #obj do
252 if obj[_index_0] == _val_0 then
253 return true
254 end
255 end
256 return false
257end
258local _anon_func_28 = function(obj)
259 local _val_0 = "value"
260 for _index_0 = 1, #obj do
261 if obj[_index_0] == _val_0 then
262 return true
263 end
264 end
265 return false
266end
267local _anon_func_29 = function(obj)
268 local _val_0 = "missing"
269 for _index_0 = 1, #obj do
270 if obj[_index_0] == _val_0 then
271 return true
272 end
273 end
274 return false
275end
276local _anon_func_30 = function(items)
277 local _val_0 = 2
278 for _index_0 = 1, #items do
279 if items[_index_0] == _val_0 then
280 return true
281 end
282 end
283 return false
284end
285local _anon_func_31 = function(allowed, item)
286 for _index_0 = 1, #allowed do
287 if allowed[_index_0] == item then
288 return true
289 end
290 end
291 return false
292end
293return describe("in expression", function()
294 it("should check value in table", function()
295 local items = {
296 1,
297 2,
298 3,
299 4,
300 5
301 }
302 assert.is_true(_anon_func_0(items))
303 return assert.is_false(_anon_func_1(items))
304 end)
305 it("should work with strings", function()
306 local chars = {
307 "a",
308 "b",
309 "c"
310 }
311 assert.is_true(_anon_func_2(chars))
312 return assert.is_false(_anon_func_3(chars))
313 end)
314 it("should check keys in table", function()
315 local obj = {
316 x = 1,
317 y = 2,
318 z = 3
319 }
320 assert.is_true(_anon_func_4(obj))
321 assert.is_true(_anon_func_5(obj))
322 return assert.is_false(_anon_func_6(obj))
323 end)
324 it("should work with mixed types", function()
325 local items = {
326 1,
327 "two",
328 true,
329 nil
330 }
331 assert.is_true(_anon_func_7(items))
332 assert.is_true(_anon_func_8(items))
333 assert.is_true(_anon_func_9(items))
334 return assert.is_false(_anon_func_10(items))
335 end)
336 it("should handle empty table", function()
337 local empty = { }
338 assert.is_false(_anon_func_11(empty))
339 return assert.is_false(_anon_func_12(empty))
340 end)
341 it("should work in conditional", function()
342 local items = {
343 1,
344 2,
345 3
346 }
347 local result
348 if _anon_func_13(items) then
349 result = "found"
350 else
351 result = "not found"
352 end
353 return assert.same(result, "found")
354 end)
355 it("should support negation", function()
356 local items = {
357 1,
358 2,
359 3
360 }
361 assert.is_true(not (_anon_func_14(items)))
362 return assert.is_false(not (_anon_func_15(items)))
363 end)
364 it("should work with nested tables", function()
365 local nested = {
366 {
367 1,
368 2
369 },
370 {
371 3,
372 4
373 },
374 {
375 5,
376 6
377 }
378 }
379 assert.is_true(_anon_func_16(nested))
380 return assert.is_false(_anon_func_17(nested))
381 end)
382 it("should handle boolean values", function()
383 local bools = {
384 true,
385 false
386 }
387 assert.is_true(_anon_func_18(bools))
388 return assert.is_true(_anon_func_19(bools))
389 end)
390 it("should work in loop", function()
391 local items = {
392 1,
393 2,
394 3,
395 4,
396 5
397 }
398 local count = 0
399 for i = 1, 10 do
400 if (#items > 0 and _anon_func_20(i, items)) then
401 count = count + 1
402 end
403 end
404 return assert.same(count, 5)
405 end)
406 it("should support table as value", function()
407 local key1 = {
408 a = 1
409 }
410 local key2 = {
411 b = 2
412 }
413 local tb = {
414 [key1] = "first",
415 [key2] = "second"
416 }
417 assert.is_true((#tb > 0 and _anon_func_21(key1, tb)))
418 return assert.is_true((#tb > 0 and _anon_func_22(key2, tb)))
419 end)
420 it("should work with function results", function()
421 local get_items
422 get_items = function()
423 return {
424 1,
425 2,
426 3
427 }
428 end
429 assert.is_true(_anon_func_23(get_items))
430 return assert.is_false(_anon_func_24(get_items))
431 end)
432 it("should handle nil in table", function()
433 local items = {
434 1,
435 nil,
436 3
437 }
438 assert.is_true(_anon_func_25(items))
439 return assert.is_true(_anon_func_26(items))
440 end)
441 it("should work with string keys", function()
442 local obj = {
443 name = "test",
444 value = 42
445 }
446 assert.is_true(_anon_func_27(obj))
447 assert.is_true(_anon_func_28(obj))
448 return assert.is_false(_anon_func_29(obj))
449 end)
450 it("should support complex expressions", function()
451 local items = {
452 1,
453 2,
454 3
455 }
456 local result = (_anon_func_30(items)) and "yes" or "no"
457 return assert.same(result, "yes")
458 end)
459 return it("should work in comprehension", function()
460 local source = {
461 1,
462 2,
463 3,
464 4,
465 5
466 }
467 local allowed = {
468 2,
469 4
470 }
471 local result
472 do
473 local _accum_0 = { }
474 local _len_0 = 1
475 for _index_0 = 1, #source do
476 local item = source[_index_0]
477 if (#allowed > 0 and _anon_func_31(allowed, item)) then
478 _accum_0[_len_0] = item
479 _len_0 = _len_0 + 1
480 end
481 end
482 result = _accum_0
483 end
484 return assert.same(result, {
485 2,
486 4
487 })
488 end)
489end)
diff --git a/spec/outputs/test/named_varargs_spec.lua b/spec/outputs/test/named_varargs_spec.lua
new file mode 100644
index 0000000..2a71cea
--- /dev/null
+++ b/spec/outputs/test/named_varargs_spec.lua
@@ -0,0 +1,246 @@
1return describe("named varargs", function()
2 it("should store varargs in named table", function()
3 local f
4 f = function(...)
5 local t = {
6 n = select("#", ...),
7 ...
8 }
9 assert.same(t.n, 3)
10 assert.same(t[1], 1)
11 assert.same(t[2], 2)
12 return assert.same(t[3], 3)
13 end
14 return f(1, 2, 3)
15 end)
16 it("should handle string arguments", function()
17 local f
18 f = function(...)
19 local args = {
20 n = select("#", ...),
21 ...
22 }
23 assert.same(args.n, 3)
24 assert.same(args[1], "a")
25 assert.same(args[2], "b")
26 return assert.same(args[3], "c")
27 end
28 return f("a", "b", "c")
29 end)
30 it("should handle empty varargs", function()
31 local f
32 f = function(...)
33 local t = {
34 n = select("#", ...),
35 ...
36 }
37 assert.same(t.n, 0)
38 return assert.same(#t, 0)
39 end
40 return f()
41 end)
42 it("should preserve nil values", function()
43 local f
44 f = function(...)
45 local args = {
46 n = select("#", ...),
47 ...
48 }
49 assert.same(args.n, 5)
50 assert.same(args[1], 1)
51 assert.same(args[2], nil)
52 assert.same(args[3], 3)
53 assert.same(args[4], nil)
54 return assert.same(args[5], 5)
55 end
56 return f(1, nil, 3, nil, 5)
57 end)
58 it("should work with loop", function()
59 local f
60 f = function(...)
61 local t = {
62 n = select("#", ...),
63 ...
64 }
65 local sum = 0
66 for i = 1, t.n do
67 if type(t[i]) == "number" then
68 sum = sum + t[i]
69 end
70 end
71 return sum
72 end
73 local result = f(1, 2, 3, 4, 5)
74 return assert.same(result, 15)
75 end)
76 it("should handle mixed types", function()
77 local f
78 f = function(...)
79 local args = {
80 n = select("#", ...),
81 ...
82 }
83 local types
84 do
85 local _accum_0 = { }
86 local _len_0 = 1
87 for i = 1, args.n do
88 _accum_0[_len_0] = type(args[i])
89 _len_0 = _len_0 + 1
90 end
91 types = _accum_0
92 end
93 return types
94 end
95 local result = f("string", 123, true, nil, { })
96 return assert.same(result, {
97 "string",
98 "number",
99 "boolean",
100 "nil",
101 "table"
102 })
103 end)
104 it("should work with table access", function()
105 local f
106 f = function(...)
107 local t = {
108 n = select("#", ...),
109 ...
110 }
111 local first = t[1]
112 local last = t[t.n]
113 return {
114 first,
115 last
116 }
117 end
118 local result = f(1, 2, 3, 4, 5)
119 return assert.same(result, {
120 1,
121 5
122 })
123 end)
124 it("should support select with named args", function()
125 local f
126 f = function(...)
127 local args = {
128 n = select("#", ...),
129 ...
130 }
131 local second = select(2, table.unpack(args))
132 return second
133 end
134 local result = f("a", "b", "c")
135 return assert.same(result, "b")
136 end)
137 it("should work with pcall", function()
138 local f
139 f = function(...)
140 local t = {
141 n = select("#", ...),
142 ...
143 }
144 local success = true
145 for i = 1, t.n do
146 if t[i] == nil then
147 success = false
148 end
149 end
150 return success
151 end
152 local result = f(1, nil, 3)
153 return assert.is_false(result)
154 end)
155 it("should handle function results", function()
156 local g
157 g = function()
158 return 1, 2, 3
159 end
160 local f
161 f = function(...)
162 local t = {
163 n = select("#", ...),
164 ...
165 }
166 return t.n
167 end
168 local result = f(g())
169 return assert.same(result, 3)
170 end)
171 it("should work with unpacking", function()
172 local f
173 f = function(...)
174 local args = {
175 n = select("#", ...),
176 ...
177 }
178 return {
179 table.unpack(args)
180 }
181 end
182 local result = f("a", "b", "c")
183 return assert.same(result, {
184 "a",
185 "b",
186 "c"
187 })
188 end)
189 it("should support passing named varargs to another function", function()
190 local outer
191 outer = function(...)
192 local t = {
193 n = select("#", ...),
194 ...
195 }
196 return inner((table.unpack(t)))
197 end
198 local inner
199 inner = function(a, b, c)
200 return {
201 a,
202 b,
203 c
204 }
205 end
206 local result = outer(1, 2, 3)
207 return assert.same(result, {
208 1,
209 2,
210 3
211 })
212 end)
213 it("should work with default parameter", function()
214 local f
215 f = function(x, ...)
216 if x == nil then
217 x = 10
218 end
219 local t = {
220 n = select("#", ...),
221 ...
222 }
223 return x + t[1] or 0
224 end
225 local result = f(5, 15)
226 return assert.same(result, 20)
227 end)
228 return it("should handle single argument", function()
229 local f
230 f = function(...)
231 local t = {
232 n = select("#", ...),
233 ...
234 }
235 return {
236 t.n,
237 t[1]
238 }
239 end
240 local result = f(42)
241 return assert.same(result, {
242 1,
243 42
244 })
245 end)
246end)
diff --git a/spec/outputs/test/prefixed_return_spec.lua b/spec/outputs/test/prefixed_return_spec.lua
new file mode 100644
index 0000000..4a73d81
--- /dev/null
+++ b/spec/outputs/test/prefixed_return_spec.lua
@@ -0,0 +1,105 @@
1return describe("prefixed return", function()
2 it("should return prefixed value with no explicit return", function()
3 local findFirstEven
4 findFirstEven = function(list)
5 for _index_0 = 1, #list do
6 local item = list[_index_0]
7 if type(item) == "table" then
8 for _index_1 = 1, #item do
9 local sub = item[_index_1]
10 if sub % 2 == 0 then
11 return sub
12 end
13 end
14 end
15 end
16 return nil
17 end
18 local result = findFirstEven({
19 1,
20 3,
21 {
22 4,
23 6
24 },
25 5
26 })
27 return assert.same(result, 4)
28 end)
29 it("should return prefixed nil when not found", function()
30 local findValue
31 findValue = function(list)
32 for _index_0 = 1, #list do
33 local item = list[_index_0]
34 if item == 999 then
35 return item
36 end
37 end
38 return nil
39 end
40 local result = findValue({
41 1,
42 2,
43 3
44 })
45 return assert.same(result, nil)
46 end)
47 it("should return prefixed string", function()
48 local findName
49 findName = function(items)
50 for _index_0 = 1, #items do
51 local item = items[_index_0]
52 if item.name == "target" then
53 return item.name
54 end
55 end
56 return "not found"
57 end
58 local result = findName({
59 {
60 name = "a"
61 },
62 {
63 name = "b"
64 }
65 })
66 return assert.same(result, "not found")
67 end)
68 it("should return prefixed number", function()
69 local calculateSum
70 calculateSum = function()
71 local total = 0
72 return 0
73 end
74 local result = calculateSum()
75 return assert.same(result, 0)
76 end)
77 return it("should work with nested logic", function()
78 local findNested
79 findNested = function(data)
80 for _index_0 = 1, #data do
81 local category = data[_index_0]
82 if type(category) == "table" then
83 for _index_1 = 1, #category do
84 local item = category[_index_1]
85 if item == "target" then
86 return "found"
87 end
88 end
89 end
90 end
91 return "missing"
92 end
93 local result = findNested({
94 {
95 1,
96 2
97 },
98 {
99 "target",
100 3
101 }
102 })
103 return assert.same(result, "found")
104 end)
105end)
diff --git a/spec/outputs/test/reverse_index_spec.lua b/spec/outputs/test/reverse_index_spec.lua
new file mode 100644
index 0000000..396c3b9
--- /dev/null
+++ b/spec/outputs/test/reverse_index_spec.lua
@@ -0,0 +1,152 @@
1return describe("reverse index", function()
2 it("should get last element", function()
3 local data = {
4 items = {
5 1,
6 2,
7 3,
8 4,
9 5
10 }
11 }
12 local last
13 do
14 local _item_0 = data.items
15 last = _item_0[#_item_0]
16 end
17 return assert.same(last, 5)
18 end)
19 it("should get second last element", function()
20 local data = {
21 items = {
22 1,
23 2,
24 3,
25 4,
26 5
27 }
28 }
29 local second_last
30 do
31 local _item_0 = data.items
32 second_last = _item_0[#_item_0 - 1]
33 end
34 return assert.same(second_last, 4)
35 end)
36 it("should get third last element", function()
37 local data = {
38 items = {
39 1,
40 2,
41 3,
42 4,
43 5
44 }
45 }
46 local third_last
47 do
48 local _item_0 = data.items
49 third_last = _item_0[#_item_0 - 2]
50 end
51 return assert.same(third_last, 3)
52 end)
53 it("should set last element", function()
54 local data = {
55 items = {
56 1,
57 2,
58 3,
59 4,
60 5
61 }
62 }
63 local _obj_0 = data.items
64 _obj_0[#_obj_0] = 10
65 return assert.same(data.items[5], 10)
66 end)
67 it("should set second last element", function()
68 local data = {
69 items = {
70 1,
71 2,
72 3,
73 4,
74 5
75 }
76 }
77 local _obj_0 = data.items
78 _obj_0[#_obj_0 - 1] = 20
79 return assert.same(data.items[4], 20)
80 end)
81 it("should work with single element", function()
82 local tab = {
83 42
84 }
85 return assert.same(tab[#tab], 42)
86 end)
87 it("should work with empty table", function()
88 local tab = { }
89 return assert.same(tab[#tab], nil)
90 end)
91 it("should work in expressions", function()
92 local tab = {
93 1,
94 2,
95 3,
96 4,
97 5
98 }
99 local result = tab[#tab] + tab[#tab - 1]
100 return assert.same(result, 9)
101 end)
102 it("should support chaining", function()
103 local data = {
104 items = {
105 nested = {
106 1,
107 2,
108 3
109 }
110 }
111 }
112 local last
113 do
114 local _item_0 = data.items.nested
115 last = _item_0[#_item_0]
116 end
117 return assert.same(last, 3)
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()
124 local tab = {
125 1,
126 2,
127 3,
128 4,
129 5
130 }
131 assert.same(tab[#tab - 3], 2)
132 return assert.same(tab[#tab - 4], 1)
133 end)
134 return it("should work in loops", function()
135 local tab = {
136 1,
137 2,
138 3,
139 4,
140 5
141 }
142 local results = { }
143 for i = 0, 2 do
144 table.insert(results, tab[#tab - i])
145 end
146 return assert.same(results, {
147 5,
148 4,
149 3
150 })
151 end)
152end)
diff --git a/spec/outputs/test/table_append_spec.lua b/spec/outputs/test/table_append_spec.lua
new file mode 100644
index 0000000..5ce1156
--- /dev/null
+++ b/spec/outputs/test/table_append_spec.lua
@@ -0,0 +1,160 @@
1return describe("table append", function()
2 it("should append single value", function()
3 local tab = { }
4 tab[#tab + 1] = "Value"
5 assert.same(tab[1], "Value")
6 return assert.same(#tab, 1)
7 end)
8 it("should append multiple values", function()
9 local tab = { }
10 tab[#tab + 1] = 1
11 tab[#tab + 1] = 2
12 tab[#tab + 1] = 3
13 return assert.same(tab, {
14 1,
15 2,
16 3
17 })
18 end)
19 it("should append with spread operator", function()
20 local tbA = {
21 1,
22 2,
23 3
24 }
25 local tbB = {
26 4,
27 5,
28 6
29 }
30 local _len_0 = #tbA + 1
31 for _index_0 = 1, #tbB do
32 local _elm_0 = tbB[_index_0]
33 tbA[_len_0], _len_0 = _elm_0, _len_0 + 1
34 end
35 return assert.same(tbA, {
36 1,
37 2,
38 3,
39 4,
40 5,
41 6
42 })
43 end)
44 it("should append table with single element", function()
45 local tab = {
46 1,
47 2
48 }
49 local tb2 = {
50 3
51 }
52 tab[#tab + 1] = table.unpack(tb2)
53 return assert.same(tab, {
54 1,
55 2,
56 3
57 })
58 end)
59 it("should append empty table", function()
60 local tab = {
61 1,
62 2
63 }
64 local tb2 = { }
65 local _len_0 = #tab + 1
66 for _index_0 = 1, #tb2 do
67 local _elm_0 = tb2[_index_0]
68 tab[_len_0], _len_0 = _elm_0, _len_0 + 1
69 end
70 return assert.same(tab, {
71 1,
72 2
73 })
74 end)
75 it("should append nil values", function()
76 local tab = { }
77 tab[#tab + 1] = nil
78 tab[#tab + 1] = "value"
79 assert.same(tab[1], nil)
80 return assert.same(tab[2], "value")
81 end)
82 it("should work in loop", function()
83 local tab = { }
84 for i = 1, 3 do
85 tab[#tab + 1] = i * 2
86 end
87 return assert.same(tab, {
88 2,
89 4,
90 6
91 })
92 end)
93 it("should append with expressions", function()
94 local tab = { }
95 local x = 10
96 tab[#tab + 1] = x + 5
97 return assert.same(tab[1], 15)
98 end)
99 it("should append mixed types", function()
100 local tab = { }
101 tab[#tab + 1] = "string"
102 tab[#tab + 1] = 123
103 tab[#tab + 1] = true
104 tab[#tab + 1] = nil
105 return assert.same(tab, {
106 "string",
107 123,
108 true,
109 nil
110 })
111 end)
112 it("should append to table with existing elements", function()
113 local tab = {
114 1,
115 2,
116 3
117 }
118 tab[#tab + 1] = 4
119 tab[#tab + 1] = 5
120 return assert.same(tab, {
121 1,
122 2,
123 3,
124 4,
125 5
126 })
127 end)
128 it("should work with nested tables", function()
129 local tab = { }
130 tab[#tab + 1] = {
131 a = 1,
132 b = 2
133 }
134 tab[#tab + 1] = {
135 3,
136 4
137 }
138 assert.same(tab[1], {
139 a = 1,
140 b = 2
141 })
142 return assert.same(tab[2], {
143 3,
144 4
145 })
146 end)
147 return it("should append function results", function()
148 local fn
149 fn = function()
150 return 1, 2, 3
151 end
152 local tab = { }
153 tab[#tab + 1] = fn()
154 return assert.same(tab, {
155 1,
156 2,
157 3
158 })
159 end)
160end)
diff --git a/spec/outputs/test/varargs_assignment_spec.lua b/spec/outputs/test/varargs_assignment_spec.lua
new file mode 100644
index 0000000..60eab29
--- /dev/null
+++ b/spec/outputs/test/varargs_assignment_spec.lua
@@ -0,0 +1,188 @@
1local _anon_func_0 = function(assert, select, _arg_0, ...)
2 local ok = _arg_0
3 local count = select('#', ...)
4 assert.same(count, 5)
5 return assert.same(ok, true)
6end
7local _anon_func_1 = function(assert, select, ...)
8 local first = select(1, ...)
9 local second = select(2, ...)
10 local third = select(3, ...)
11 assert.same(first, 10)
12 assert.same(second, 20)
13 return assert.same(third, 30)
14end
15local _anon_func_2 = function(assert, select, _arg_0, ...)
16 local success = _arg_0
17 assert.is_true(success)
18 return assert.same(select('#', ...), 3)
19end
20local _anon_func_3 = function(assert, select, ...)
21 local count = select('#', ...)
22 return assert.same(count, 0)
23end
24local _anon_func_4 = function(assert, select, _arg_0, ...)
25 local a = _arg_0
26 assert.same(a, "first")
27 return assert.same(select('#', ...), 3)
28end
29local _anon_func_5 = function(assert, select, ...)
30 local count = select('#', ...)
31 assert.same(count, 5)
32 assert.same(select(1, ...), 1)
33 assert.same(select(2, ...), nil)
34 return assert.same(select(3, ...), 2)
35end
36local _anon_func_6 = function(assert, select, ...)
37 local count = select('#', ...)
38 return assert.same(count, 3)
39end
40local _anon_func_7 = function(a, assert, select, _arg_1, ...)
41 local b = _arg_1
42 assert.same(a, 1)
43 assert.same(b, 4)
44 return assert.same(select('#', ...), 2)
45end
46local _anon_func_8 = function(assert, sum, ...)
47 local result = sum(...)
48 return assert.same(result, 15)
49end
50local _anon_func_9 = function(assert, string, ...)
51 local result = string.format("str: %s, num: %d, bool: %s", ...)
52 return assert.same(result, "str: hello, num: 123, bool: true")
53end
54local _anon_func_10 = function(assert, select, ...)
55 local count = select('#', ...)
56 assert.same(count, 1)
57 return assert.same(select(1, ...), 42)
58end
59local _anon_func_11 = function(assert, inner, _arg_0, _arg_1, ...)
60 local a, b = _arg_0, _arg_1
61 local c, d = inner()
62 assert.same(a, 1)
63 assert.same(b, 2)
64 assert.same(c, 4)
65 return assert.same(d, 5)
66end
67return describe("varargs assignment", function()
68 it("should assign varargs from function", function()
69 local list = {
70 1,
71 2,
72 3,
73 4,
74 5
75 }
76 local fn
77 fn = function(ok)
78 return ok, table.unpack(list)
79 end
80 return _anon_func_0(assert, select, fn(true))
81 end)
82 it("should access varargs elements", function()
83 local list = {
84 10,
85 20,
86 30
87 }
88 local fn
89 fn = function()
90 return table.unpack(list)
91 end
92 return _anon_func_1(assert, select, fn())
93 end)
94 it("should work with pcall", function()
95 local fn
96 fn = function()
97 return 1, 2, 3
98 end
99 return _anon_func_2(assert, select, pcall(fn))
100 end)
101 it("should handle empty varargs", function()
102 local fn
103 fn = function() end
104 return _anon_func_3(assert, select, fn())
105 end)
106 it("should work with mixed return values", function()
107 local fn
108 fn = function()
109 return "first", nil, "third", false
110 end
111 return _anon_func_4(assert, select, fn())
112 end)
113 it("should preserve nil values in varargs", function()
114 local fn
115 fn = function()
116 return 1, nil, 2, nil, 3
117 end
118 return _anon_func_5(assert, select, fn())
119 end)
120 it("should work with table.unpack", function()
121 local tb = {
122 a = 1,
123 b = 2,
124 c = 3
125 }
126 local fn
127 fn = function()
128 return table.unpack(tb)
129 end
130 return _anon_func_6(assert, select, fn())
131 end)
132 it("should chain varargs assignment", function()
133 local fn1
134 fn1 = function()
135 return 1, 2, 3
136 end
137 local fn2
138 fn2 = function()
139 return table.unpack({
140 4,
141 5,
142 6
143 })
144 end
145 return (function(_arg_0, ...)
146 local a = _arg_0
147 return _anon_func_7(a, assert, select, fn2())
148 end)(fn1())
149 end)
150 it("should work in expressions", function()
151 local sum
152 sum = function(...)
153 local total = 0
154 for i = 1, select('#', ...) do
155 if type(select(i, ...)) == "number" then
156 total = total + select(i, ...)
157 end
158 end
159 return total
160 end
161 local fn
162 fn = function()
163 return 1, 2, 3, 4, 5
164 end
165 return _anon_func_8(assert, sum, fn())
166 end)
167 it("should work with string.format", function()
168 return _anon_func_9(assert, string, "hello", 123, true)
169 end)
170 it("should handle single return value", function()
171 local fn
172 fn = function()
173 return 42
174 end
175 return _anon_func_10(assert, select, fn())
176 end)
177 return it("should work with nested functions", function()
178 local outer
179 outer = function()
180 return 1, 2, 3
181 end
182 local inner
183 inner = function()
184 return 4, 5
185 end
186 return _anon_func_11(assert, inner, outer())
187 end)
188end)
diff --git a/spec/outputs/test/while_assignment_spec.lua b/spec/outputs/test/while_assignment_spec.lua
new file mode 100644
index 0000000..289e16e
--- /dev/null
+++ b/spec/outputs/test/while_assignment_spec.lua
@@ -0,0 +1,84 @@
1return describe("while assignment", function()
2 it("should loop while value is truthy", function()
3 local counter = 0
4 local get_next
5 get_next = function()
6 if counter < 3 then
7 counter = counter + 1
8 return counter
9 else
10 return nil
11 end
12 end
13 local results = { }
14 repeat
15 local val = get_next()
16 if val then
17 table.insert(results, val)
18 else
19 break
20 end
21 until false
22 return assert.same(results, {
23 1,
24 2,
25 3
26 })
27 end)
28 it("should work with function results", function()
29 local counter = 0
30 local fn
31 fn = function()
32 counter = counter + 1
33 if counter <= 3 then
34 return counter * 10
35 else
36 return nil
37 end
38 end
39 local sum = 0
40 repeat
41 local val = fn()
42 if val then
43 sum = sum + val
44 else
45 break
46 end
47 until false
48 return assert.same(sum, 60)
49 end)
50 it("should exit immediately on nil", function()
51 local get_val
52 get_val = function()
53 return nil
54 end
55 local counter = 0
56 repeat
57 local val = get_val()
58 if val then
59 counter = counter + 1
60 else
61 break
62 end
63 until false
64 return assert.same(counter, 0)
65 end)
66 return it("should support break in loop", function()
67 local items = {
68 1,
69 2,
70 3,
71 4,
72 5
73 }
74 local sum = 0
75 for _index_0 = 1, #items do
76 local item = items[_index_0]
77 sum = sum + item
78 if sum > 6 then
79 break
80 end
81 end
82 return assert.same(sum, 10)
83 end)
84end)
diff --git a/spec/outputs/test/yaml_string_spec.lua b/spec/outputs/test/yaml_string_spec.lua
new file mode 100644
index 0000000..258ab92
--- /dev/null
+++ b/spec/outputs/test/yaml_string_spec.lua
@@ -0,0 +1,99 @@
1return describe("yaml string", function()
2 it("should create basic yaml string", function()
3 local s = "hello\nworld"
4 assert.is_true(s:match("hello"))
5 return assert.is_true(s:match("world"))
6 end)
7 it("should preserve indentation", function()
8 local s = "key1: value1\nkey2: value2"
9 assert.is_true(s:match("key1"))
10 return assert.is_true(s:match("key2"))
11 end)
12 it("should support interpolation", function()
13 local name = "test"
14 local s = "hello " .. tostring(name)
15 return assert.same(s, "hello test")
16 end)
17 it("should handle complex interpolation", function()
18 local x, y = 10, 20
19 local s = "point:\n\tx: " .. tostring(x) .. "\n\ty: " .. tostring(y)
20 assert.is_true(s:match("x: 10"))
21 return assert.is_true(s:match("y: 20"))
22 end)
23 it("should work with expressions", function()
24 local s = "result: " .. tostring(1 + 2)
25 return assert.is_true(s:match("result: 3"))
26 end)
27 it("should support multiline with variables", function()
28 local config = "database:\n\thost: localhost\n\tport: 5432\n\tname: mydb"
29 assert.is_true(config:match("database:"))
30 return assert.is_true(config:match("host:"))
31 end)
32 it("should escape special characters", function()
33 local s = "path: \"C:\\Program Files\\App\"\nnote: 'He said: \"" .. tostring(Hello) .. "!\"'"
34 assert.is_true(s:match("path:"))
35 return assert.is_true(s:match("note:"))
36 end)
37 it("should work in function", function()
38 local fn
39 fn = function()
40 local str = "foo:\n\tbar: baz"
41 return str
42 end
43 local result = fn()
44 assert.is_true(result:match("foo:"))
45 return assert.is_true(result:match("bar:"))
46 end)
47 it("should strip common leading whitespace", function()
48 local fn
49 fn = function()
50 local s = "nested:\n\titem: value"
51 return s
52 end
53 local result = fn()
54 assert.is_true(result:match("nested:"))
55 return assert.is_true(result:match("item:"))
56 end)
57 it("should support empty lines", function()
58 local s = "line1\nline3"
59 assert.is_true(s:match("line1"))
60 return assert.is_true(s:match("line3"))
61 end)
62 it("should work with table access in interpolation", function()
63 local t = {
64 value = 100
65 }
66 local s = "value: " .. tostring(t.value)
67 return assert.is_true(s:match("value: 100"))
68 end)
69 it("should support function calls in interpolation", function()
70 local s = "result: " .. tostring((function()
71 return 42
72 end)())
73 return assert.is_true(s:match("result: 42"))
74 end)
75 it("should handle quotes correctly", function()
76 local s = "\"quoted\"\n'single quoted'"
77 assert.is_true(s:match('"quoted"'))
78 return assert.is_true(s:match("'single quoted'"))
79 end)
80 it("should work with multiple interpolations", function()
81 local a, b, c = 1, 2, 3
82 local s = "values: " .. tostring(a) .. ", " .. tostring(b) .. ", " .. tostring(c)
83 return assert.is_true(s:match("values: 1, 2, 3"))
84 end)
85 return it("should preserve newlines", function()
86 local s = "first line\nsecond line\nthird line"
87 local lines
88 do
89 local _accum_0 = { }
90 local _len_0 = 1
91 for line in s:gmatch("[^\n]+") do
92 _accum_0[_len_0] = line
93 _len_0 = _len_0 + 1
94 end
95 lines = _accum_0
96 end
97 return assert.same(#lines, 3)
98 end)
99end)