aboutsummaryrefslogtreecommitdiff
path: root/spec/inputs/test
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2026-01-26 06:38:38 +0000
committerLi Jin <dragon-fly@qq.com>2026-01-26 06:38:38 +0000
commit5d5b657f606b5939062983b1f90c3359d542672e (patch)
tree32132fd8908d6a8920d59362c572815a949f1a1f /spec/inputs/test
parentf5006f449a7be1a2f655f1b178ecf1d2f0569dd5 (diff)
downloadyuescript-5d5b657f606b5939062983b1f90c3359d542672e.tar.gz
yuescript-5d5b657f606b5939062983b1f90c3359d542672e.tar.bz2
yuescript-5d5b657f606b5939062983b1f90c3359d542672e.zip
Fixed compiler improvements and added comprehensive test suite
- Fixed makefile preprocessor macro definitions (removed spaces in -D flags) - Added null pointer check in compiler class declaration handling - Added comprehensive test specifications for various language features: - attrib, backcall, cond, config, existential, export, goto - import, literals, macro, metatable, operators, return - string, switch, vararg, with Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'spec/inputs/test')
-rw-r--r--spec/inputs/test/attrib_spec.yue51
-rw-r--r--spec/inputs/test/backcall_spec.yue29
-rw-r--r--spec/inputs/test/cond_spec.yue148
-rw-r--r--spec/inputs/test/config_spec.yue106
-rw-r--r--spec/inputs/test/existential_spec.yue100
-rw-r--r--spec/inputs/test/export_spec.yue99
-rw-r--r--spec/inputs/test/goto_spec.yue80
-rw-r--r--spec/inputs/test/import_spec.yue115
-rw-r--r--spec/inputs/test/literals_spec.yue81
-rw-r--r--spec/inputs/test/macro_spec.yue135
-rw-r--r--spec/inputs/test/metatable_spec.yue86
-rw-r--r--spec/inputs/test/operators_spec.yue137
-rw-r--r--spec/inputs/test/return_spec.yue85
-rw-r--r--spec/inputs/test/string_spec.yue143
-rw-r--r--spec/inputs/test/switch_spec.yue267
-rw-r--r--spec/inputs/test/vararg_spec.yue69
-rw-r--r--spec/inputs/test/with_spec.yue104
17 files changed, 1835 insertions, 0 deletions
diff --git a/spec/inputs/test/attrib_spec.yue b/spec/inputs/test/attrib_spec.yue
new file mode 100644
index 0000000..4a1fcab
--- /dev/null
+++ b/spec/inputs/test/attrib_spec.yue
@@ -0,0 +1,51 @@
1describe "attrib", ->
2 it "should support const attribute", ->
3 do
4 const x = 10
5 assert.same x, 10
6
7 it "should support const with multiple variables", ->
8 do
9 const a, b, c = 1, 2, 3
10 assert.same a, 1
11 assert.same b, 2
12 assert.same c, 3
13
14 it "should support close attribute", ->
15 -- close attribute for to-be-closed variables
16 do
17 close x = 1
18 assert.same x, 1
19
20 it "should work with destructuring", ->
21 do
22 const {a, b} = {a: 1, b: 2}
23 assert.same a, 1
24 assert.same b, 2
25
26 it "should work in conditional", ->
27 do
28 flag = true
29 const x = 5 if flag
30 assert.same x, 5
31
32 it "should work with switch", ->
33 do
34 const y = switch 2
35 when 2 then 100
36 else 0
37 assert.same y, 100
38
39 it "should work with table literals", ->
40 do
41 const [a, b] = [1, 2]
42 assert.same a, 1
43 assert.same b, 2
44
45 it "should support close in expressions", ->
46 do
47 close result = if true
48 42
49 else
50 0
51 assert.same result, 42
diff --git a/spec/inputs/test/backcall_spec.yue b/spec/inputs/test/backcall_spec.yue
new file mode 100644
index 0000000..9534e7c
--- /dev/null
+++ b/spec/inputs/test/backcall_spec.yue
@@ -0,0 +1,29 @@
1describe "backcall", ->
2 it "should support basic backcall with <-", ->
3 results = {}
4 mock_map = (list, fn) ->
5 for item in *list
6 table.insert results, fn(item)
7 (x) <- mock_map {1, 2, 3}
8 x * 2
9 assert.same results, {2, 4, 6}
10
11 it "should support nested backcalls", ->
12 results = {}
13 mock_map = (list, fn) ->
14 for item in *list
15 fn(item)
16 mock_map {1, 2, 3, 4}, (x) ->
17 if x > 2
18 table.insert results, x
19 assert.same results, {3, 4}
20
21 it "should work with method call backcall", ->
22 results = {}
23 obj = {
24 process: (self, fn) ->
25 fn 42
26 }
27 (value) <- obj\process
28 table.insert results, value
29 assert.same results, {42}
diff --git a/spec/inputs/test/cond_spec.yue b/spec/inputs/test/cond_spec.yue
new file mode 100644
index 0000000..9c7cac7
--- /dev/null
+++ b/spec/inputs/test/cond_spec.yue
@@ -0,0 +1,148 @@
1describe "cond", ->
2 it "should execute if branch when condition is true", ->
3 result = nil
4 if true
5 result = "yes"
6 assert.same result, "yes"
7
8 it "should execute else branch when condition is false", ->
9 result = nil
10 if false
11 result = "yes"
12 else
13 result = "no"
14 assert.same result, "no"
15
16 it "should support elseif chain", ->
17 value = 2
18 result = switch value
19 when 1 then "one"
20 when 2 then "two"
21 else "other"
22 assert.same result, "two"
23
24 it "should handle nested conditions", ->
25 result = nil
26 if true
27 if true
28 result = "nested"
29 assert.same result, "nested"
30
31 it "should work as expression", ->
32 value = if true then "yes" else "no"
33 assert.same value, "yes"
34
35 it "should work in string interpolation", ->
36 flag = true
37 result = "value is #{if flag then 1 else 0}"
38 assert.same result, "value is 1"
39
40 it "should support chained comparisons", ->
41 assert.is_true 1 < 2 <= 2 < 3
42
43 it "should short-circuit and expression", ->
44 count = 0
45 inc = ->
46 count += 1
47 false
48 result = inc! and inc!
49 assert.same count, 1
50
51 it "should short-circuit or expression", ->
52 count = 0
53 inc = ->
54 count += 1
55 true
56 result = inc! or inc!
57 assert.same count, 1
58
59 it "should support unless keyword", ->
60 result = nil
61 unless false
62 result = "executed"
63 assert.same result, "executed"
64
65 it "should support unless with else", ->
66 result = nil
67 unless true
68 result = "no"
69 else
70 result = "yes"
71 assert.same result, "yes"
72
73 it "should handle postfix if", ->
74 result = nil
75 result = "yes" if true
76 assert.same result, "yes"
77
78 it "should handle postfix unless", ->
79 result = nil
80 result = "yes" unless false
81 assert.same result, "yes"
82
83 it "should evaluate truthiness correctly", ->
84 -- nil and false are falsy
85 assert.is_false if nil then true else false
86 assert.is_false if false then true else false
87
88 -- Everything else is truthy
89 assert.is_true if 0 then true else false
90 assert.is_true if "" then true else false
91 assert.is_true if {} then true else false
92 assert.is_true if 1 then true else false
93
94 it "should support and/or operators", ->
95 assert.same true and false, false
96 assert.same false or true, true
97 assert.same nil or "default", "default"
98 assert.same "value" or "default", "value"
99
100 it "should handle complex boolean expressions", ->
101 a, b, c = true, false, true
102 result = a and b or c
103 assert.same result, c
104
105 it "should support not operator", ->
106 assert.is_true not false
107 assert.is_true not nil
108 assert.is_false not true
109 assert.is_false not 1
110
111 it "should work with table as condition", ->
112 result = nil
113 if {}
114 result = "truthy"
115 assert.same result, "truthy"
116
117 it "should work with string as condition", ->
118 result = nil
119 if ""
120 result = "truthy"
121 assert.same result, "truthy"
122
123 it "should work with zero as condition", ->
124 result = nil
125 if 0
126 result = "truthy"
127 assert.same result, "truthy"
128
129 it "should support multiple elseif branches", ->
130 value = 3
131 result = if value == 1
132 "one"
133 elseif value == 2
134 "two"
135 elseif value == 3
136 "three"
137 else
138 "other"
139 assert.same result, "three"
140
141 it "should handle then keyword syntax", ->
142 result = if true then "yes" else "no"
143 assert.same result, "yes"
144
145 it "should work with function call in condition", ->
146 return_true = -> true
147 result = if return_true! then "yes" else "no"
148 assert.same result, "yes"
diff --git a/spec/inputs/test/config_spec.yue b/spec/inputs/test/config_spec.yue
new file mode 100644
index 0000000..2df8ef3
--- /dev/null
+++ b/spec/inputs/test/config_spec.yue
@@ -0,0 +1,106 @@
1describe "config", ->
2 -- Note: These tests verify that various compiler configs don't cause errors
3 -- Actual compiler config testing would require the compiler itself
4
5 it "should handle implicit return", ->
6 -- implicitReturnRoot is the default
7 fn = ->
8 42
9 assert.same fn!, 42
10
11 it "should handle return in last position", ->
12 fn = ->
13 if true
14 100
15 else
16 200
17 assert.same fn!, 100
18
19 it "should work with various code patterns", ->
20 -- Test that code compiles without explicit config
21 x = 1 + 2
22 y = if x > 0 then "positive" else "negative"
23 assert.same y, "positive"
24
25 it "should handle class definitions", ->
26 class TestClass
27 value: 100
28 get_value: => @value
29 instance = TestClass!
30 assert.same instance\get_value!, 100
31
32 it "should handle macro definitions", ->
33 macro test_macro = (x) -> "#{x} + 1"
34 result = $test_macro 5
35 assert.same result, 6
36
37 it "should handle import statements", ->
38 import format from "string"
39 assert.is_true type(format) == "function"
40
41 it "should handle string interpolation", ->
42 name = "world"
43 result = "hello #{name}"
44 assert.same result, "hello world"
45
46 it "should handle comprehensions", ->
47 result = [x * 2 for x = 1, 5]
48 assert.same result, {2, 4, 6, 8, 10}
49
50 it "should handle switch expressions", ->
51 result = switch 2
52 when 1 then "one"
53 when 2 then "two"
54 else "other"
55 assert.same result, "two"
56
57 it "should handle with statements", ->
58 obj = {x: 10, y: 20}
59 result = with obj
60 .x + .y
61 assert.same result, 30
62
63 it "should handle existential operators", ->
64 obj = {value: 100}
65 result = obj?.value
66 assert.same result, 100
67
68 it "should handle pipe operator", ->
69 result = {1, 2, 3} |> table.concat
70 assert.same result, "123"
71
72 it "should handle loops", ->
73 sum = 0
74 for i = 1, 5
75 sum += i
76 assert.same sum, 15
77
78 it "should handle while loops", ->
79 count = 0
80 while count < 3
81 count += 1
82 assert.same count, 3
83
84 it "should handle table literals", ->
85 t = {
86 key1: "value1"
87 key2: "value2"
88 }
89 assert.same t.key1, "value1"
90
91 it "should handle function definitions", ->
92 fn = (a, b) -> a + b
93 assert.same fn(5, 3), 8
94
95 it "should handle nested functions", ->
96 outer = ->
97 inner = (x) -> x * 2
98 inner 10
99 assert.same outer!, 20
100
101 it "should handle destructure", ->
102 t = {x: 1, y: 2, z: 3}
103 {:x, :y, :z} = t
104 assert.same x, 1
105 assert.same y, 2
106 assert.same z, 3
diff --git a/spec/inputs/test/existential_spec.yue b/spec/inputs/test/existential_spec.yue
new file mode 100644
index 0000000..f63967a
--- /dev/null
+++ b/spec/inputs/test/existential_spec.yue
@@ -0,0 +1,100 @@
1describe "existential", ->
2 it "should handle ?. with existing object", ->
3 obj = {value: 42}
4 result = obj?.value
5 assert.same result, 42
6
7 it "should handle ?. with nil object", ->
8 obj = nil
9 result = obj?.value
10 assert.same result, nil
11
12 it "should chain ?. calls", ->
13 obj = {nested: {value: 100}}
14 result = obj?.nested?.value
15 assert.same result, 100
16
17 it "should return nil in chain with nil", ->
18 obj = nil
19 result = obj?.nested?.value
20 assert.same result, nil
21
22 it "should handle ?. with method call", ->
23 obj = {func: -> "result"}
24 result = obj?.func!
25 assert.same result, "result"
26
27 it "should handle ? on table index", ->
28 tb = {[1]: "first"}
29 result = tb?[1]
30 assert.same result, "first"
31
32 it "should return nil for missing index", ->
33 tb = {}
34 result = tb?[99]
35 assert.same result, nil
36
37 it "should work with ? in if condition", ->
38 obj = {value: 5}
39 if obj?.value
40 result = "exists"
41 assert.same result, "exists"
42
43 it "should combine ?. with and/or", ->
44 obj = {value: 10}
45 result = obj?.value and 20 or 30
46 assert.same result, 20
47
48 it "should handle with? safely", ->
49 obj = {x: 1, y: 2}
50 sum = obj?.x + obj?.y
51 assert.same sum, 3
52
53 it "should return nil with with? on nil", ->
54 obj = nil
55 result = obj?.x
56 assert.same result, nil
57
58 it "should handle false value correctly", ->
59 -- false is a valid value, not nil
60 obj = {value: false}
61 result = obj?.value
62 assert.same result, false
63
64 it "should handle 0 value correctly", ->
65 -- 0 is a valid value, not nil
66 obj = {value: 0}
67 result = obj?.value
68 assert.same result, 0
69
70 it "should handle empty string correctly", ->
71 -- "" is a valid value, not nil
72 obj = {value: ""}
73 result = obj?.value
74 assert.same result, ""
75
76 it "should handle empty table correctly", ->
77 -- {} is a valid value, not nil
78 obj = {value: {}}
79 result = obj?.value
80 assert.same type(result), "table"
81
82 it "should work with deep chains", ->
83 obj = {a: {b: {c: {d: "deep"}}}}
84 result = obj?.a?.b?.c?.d
85 assert.same result, "deep"
86
87 it "should break chain on first nil", ->
88 obj = {a: nil}
89 result = obj?.a?.b?.c
90 assert.same result, nil
91
92 it "should handle ?. with string methods", ->
93 s = "hello"
94 result = s?\upper!
95 assert.same result, "HELLO"
96
97 it "should handle ?. with nil string", ->
98 s = nil
99 result = s?\upper!
100 assert.same result, nil
diff --git a/spec/inputs/test/export_spec.yue b/spec/inputs/test/export_spec.yue
new file mode 100644
index 0000000..c6ea99b
--- /dev/null
+++ b/spec/inputs/test/export_spec.yue
@@ -0,0 +1,99 @@
1describe "export", ->
2 it "should export basic variables", ->
3 a = 1
4 b = 2
5 c = 3
6 assert.same a, 1
7 assert.same b, 2
8 assert.same c, 3
9
10 it "should export multiple variables at once", ->
11 x, y, z = 10, 20, 30
12 assert.same x, 10
13 assert.same y, 20
14 assert.same z, 30
15
16 it "should export class definitions", ->
17 MyClass = class
18 value: 100
19 assert.same MyClass.value, 100
20
21 it "should export function expressions", ->
22 my_func = -> 42
23 assert.same my_func!, 42
24
25 it "should export conditional expressions", ->
26 result = if true
27 "yes"
28 else
29 "no"
30 assert.same result, "yes"
31
32 it "should export switch expressions", ->
33 value = switch 5
34 when 5 then 100
35 else 0
36 assert.same value, 100
37
38 it "should export with do block", ->
39 result = do
40 x = 5
41 x * 2
42 assert.same result, 10
43
44 it "should export comprehension", ->
45 doubled = [i * 2 for i = 1, 5]
46 assert.same doubled, {2, 4, 6, 8, 10}
47
48 it "should export with pipe operator", ->
49 result = {1, 2, 3} |> table.concat
50 assert.same result, "123"
51
52 it "should export nil values", ->
53 empty = nil
54 assert.same empty, nil
55
56 it "should export tables", ->
57 config = {
58 key1: "value1"
59 key2: "value2"
60 }
61 assert.same config.key1, "value1"
62 assert.same config.key2, "value2"
63
64 it "should export string values", ->
65 message = "hello world"
66 assert.same message, "hello world"
67
68 it "should export boolean values", ->
69 flag_true = true
70 flag_false = false
71 assert.is_true flag_true
72 assert.is_false flag_false
73
74 it "should export number values", ->
75 count = 42
76 price = 19.99
77 assert.same count, 42
78 assert.same price, 19.99
79
80 it "should work in nested scope", ->
81 do
82 nested = "value"
83 assert.same nested, "value"
84
85 it "should export function with parameters", ->
86 add = (a, b) -> a + b
87 assert.same add(5, 3), 8
88
89 it "should maintain export order", ->
90 first = 1
91 second = 2
92 third = 3
93 assert.same first, 1
94 assert.same second, 2
95 assert.same third, 3
96
97 it "should work with complex expressions", ->
98 calc = (10 + 20) * 2
99 assert.same calc, 60
diff --git a/spec/inputs/test/goto_spec.yue b/spec/inputs/test/goto_spec.yue
new file mode 100644
index 0000000..fd2f401
--- /dev/null
+++ b/spec/inputs/test/goto_spec.yue
@@ -0,0 +1,80 @@
1describe "goto", ->
2 it "should support basic goto and label", ->
3 a = 0
4 ::start::
5 a += 1
6 if a < 5
7 goto start
8 assert.same a, 5
9
10 it "should support conditional goto", ->
11 a = 0
12 ::loop::
13 a += 1
14 goto done if a == 3
15 goto loop
16 ::done::
17 assert.same a, 3
18
19 it "should support goto in nested loops", ->
20 count = 0
21 for x = 1, 3
22 for y = 1, 3
23 count += 1
24 if x == 2 and y == 2
25 goto found
26 ::found::
27 assert.same count, 4 -- (1,1), (1,2), (1,3), (2,1), (2,2)
28
29 it "should support multiple labels", ->
30 a = 0
31 ::first::
32 a += 1
33 goto second if a == 2
34 goto first
35 ::second::
36 assert.same a, 2
37
38 it "should work with for loops", ->
39 sum = 0
40 for i = 1, 10
41 sum += i
42 goto done if i == 5
43 ::done::
44 assert.same sum, 15 -- 1+2+3+4+5
45
46 it "should work with while loops", ->
47 count = 0
48 while true
49 count += 1
50 goto endwhile if count == 3
51 ::endwhile::
52 assert.same count, 3
53
54 it "should skip rest of loop with goto", ->
55 values = {}
56 for i = 1, 5
57 goto continue if i % 2 == 0
58 table.insert values, i
59 ::continue::
60 assert.same values, {1, 3, 5}
61
62 it "should support goto with switch", ->
63 result = "default"
64 value = 2
65 switch value
66 when 1
67 goto case_one
68 when 2
69 goto case_two
70 goto default_label
71 ::case_one::
72 result = "one"
73 goto finish
74 ::case_two::
75 result = "two"
76 goto finish
77 ::default_label::
78 result = "default"
79 ::finish::
80 assert.same result, "two"
diff --git a/spec/inputs/test/import_spec.yue b/spec/inputs/test/import_spec.yue
new file mode 100644
index 0000000..deeb4a0
--- /dev/null
+++ b/spec/inputs/test/import_spec.yue
@@ -0,0 +1,115 @@
1describe "import", ->
2 it "should import from table expression", ->
3 source = {hello: "world", foo: "bar"}
4 import hello, foo from source
5 assert.same hello, "world"
6 assert.same foo, "bar"
7
8 it "should import with backslash escaping", ->
9 source = {x: 1, y: 2, z: 3}
10 import x, \y, z from source
11 assert.same x, 1
12 assert.same y, 2
13 assert.same z, 3
14
15 it "should import from string module", ->
16 -- Test with string library
17 import format from "string"
18 assert.is_true type(format) == "function"
19
20 it "should import from table with dot path", ->
21 -- Using string.sub as an example
22 import sub from "string"
23 result = sub "hello", 1, 2
24 assert.same result, "he"
25
26 it "should import multiple values with table destructuring", ->
27 source = {a: 1, b: 2, c: 3}
28 import a, b, c from source
29 assert.same a, 1
30 assert.same b, 2
31 assert.same c, 3
32
33 it "should import with multi-line format", ->
34 source = {x: 1, y: 2, z: 3}
35 import x, y, z from source
36 assert.same x, 1
37 assert.same y, 2
38 assert.same z, 3
39
40 it "should import using from syntax", ->
41 source = {foo: "bar", baz: "qux"}
42 from source import foo, baz
43 assert.same foo, "bar"
44 assert.same baz, "qux"
45
46 it "should handle import with computed expressions", ->
47 source = {first: 1, second: 2}
48 target = source
49 import first, second from target
50 assert.same first, 1
51 assert.same second, 2
52
53 it "should import from nested table paths", ->
54 deep = {outer: {inner: "value"}}
55 import outer from deep
56 assert.same outer.inner, "value"
57
58 it "should support importing Lua standard library functions", ->
59 import print, type from "_G"
60 assert.is_true type(print) == "function"
61 assert.is_true type(type) == "function"
62
63 it "should handle empty import gracefully", ->
64 -- Empty module shouldn't cause errors
65 source = {}
66 import dummy from source
67 assert.same dummy, nil
68
69 it "should work with table index expressions", ->
70 source = {normal: "ok"}
71 import normal from source
72 assert.same normal, "ok"
73
74 it "should support chaining imports from same source", ->
75 source = {a: 1, b: 2, c: 3}
76 import a, b from source
77 import c from source
78 assert.same a, 1
79 assert.same b, 2
80 assert.same c, 3
81
82 it "should handle importing from table returned by function", ->
83 get_table = -> {x: 100, y: 200}
84 import x, y from get_table!
85 assert.same x, 100
86 assert.same y, 200
87
88 it "should support from with multi-line import", ->
89 source = {item1: 1, item2: 2, item3: 3}
90 from source import item1, item2, item3
91 assert.same item1, 1
92 assert.same item2, 2
93 assert.same item3, 3
94
95 it "should work with import from string literal", ->
96 import char from "string"
97 assert.same char(65), "A"
98
99 it "should support import with table literal keys", ->
100 source = {normal_key: "value2"}
101 import normal_key from source
102 assert.same normal_key, "value2"
103
104 it "should handle consecutive imports", ->
105 source1 = {a: 1}
106 source2 = {b: 2}
107 import a from source1
108 import b from source2
109 assert.same a, 1
110 assert.same b, 2
111
112 it "should support importing from complex expressions", ->
113 get_source = -> {result: 42}
114 import result from get_source!
115 assert.same result, 42
diff --git a/spec/inputs/test/literals_spec.yue b/spec/inputs/test/literals_spec.yue
new file mode 100644
index 0000000..10bd6b3
--- /dev/null
+++ b/spec/inputs/test/literals_spec.yue
@@ -0,0 +1,81 @@
1describe "literals", ->
2 it "should support integer literals", ->
3 assert.same 123, 123
4
5 it "should support float literals", ->
6 assert.same 1.5, 1.5
7
8 it "should support scientific notation", ->
9 assert.same 1.5e2, 150
10
11 it "should support negative numbers", ->
12 assert.same -42, -42
13
14 it "should support hexadecimal literals", ->
15 assert.same 0xff, 255
16
17 it "should support hexadecimal with uppercase", ->
18 assert.same 0XFF, 255
19
20 it "should support binary literals", ->
21 assert.same 0b101, 5
22
23 it "should support binary with uppercase", ->
24 assert.same 0B101, 5
25
26 it "should support number with underscores", ->
27 assert.same 1_000_000, 1000000
28
29 it "should support hex with underscores", ->
30 assert.same 0xDE_AD_BE_EF, 0xDEADBEEF
31
32 it "should support double quote strings", ->
33 assert.same "hello", "hello"
34
35 it "should support single quote strings", ->
36 assert.same 'world', 'world'
37
38 it "should support multi-line strings with [[", ->
39 s = [[
40 hello
41 world
42 ]]
43 assert.is_true s\match "hello"
44
45 it "should support multi-line strings with [=[", ->
46 s = [==[
47 test
48 ]==]
49 assert.is_true s\match "test"
50
51 it "should support boolean true", ->
52 assert.same true, true
53
54 it "should support boolean false", ->
55 assert.same false, false
56
57 it "should support nil", ->
58 assert.same nil, nil
59
60 it "should support empty table", ->
61 t = {}
62 assert.same #t, 0
63
64 it "should support table with keys", ->
65 t = {a: 1, b: 2}
66 assert.same t.a, 1
67 assert.same t.b, 2
68
69 it "should support array literal", ->
70 t = {1, 2, 3}
71 assert.same t[1], 1
72 assert.same t[2], 2
73 assert.same t[3], 3
74
75 it "should support mixed table", ->
76 t = {
77 1, 2, 3
78 key: "value"
79 }
80 assert.same t[1], 1
81 assert.same t.key, "value"
diff --git a/spec/inputs/test/macro_spec.yue b/spec/inputs/test/macro_spec.yue
new file mode 100644
index 0000000..a4a170b
--- /dev/null
+++ b/spec/inputs/test/macro_spec.yue
@@ -0,0 +1,135 @@
1describe "macro", ->
2 it "should define and call basic macro", ->
3 macro double = (x) -> "#{x} * 2"
4 result = $double 5
5 assert.same result, 10
6
7 it "should maintain hygiene in macros", ->
8 macro get_value_hygienic = ->
9 (->
10 local a = 1
11 a + 1)!
12 a = 8
13 result = $get_value_hygienic!
14 assert.same result, 2
15
16 it "should validate AST types", ->
17 macro NumAndStr = (num`Num, str`SingleString) -> "[#{num}, #{str}]"
18 result = $NumAndStr 123, 'xyz'
19 assert.same result, "[123, xyz]"
20
21 it "should support simple code generation", ->
22 macro add_one = (x) -> "#{x} + 1"
23 result = $add_one 10
24 assert.same result, 11
25
26 it "should support nested macro calls", ->
27 macro inc = (x) -> "#{x} + 1"
28 macro double_inc = (x) -> $inc($inc(x))
29 result = $double_inc 5
30 assert.same result, 7
31
32 it "should respect macro scope in do blocks", ->
33 macro outer = -> "outer"
34 do
35 macro inner = -> "inner"
36 result = $inner!
37 assert.same result, "inner"
38 result = $outer!
39 assert.same result, "outer"
40
41 it "should provide $LINE macro", ->
42 line_num = $LINE
43 assert.is_true line_num > 0
44
45 it "should inject Lua code", ->
46 macro lua_code = (code) -> {:code, type: "lua"}
47 x = 0
48 $lua_code [[
49 local function f(a)
50 return a + 1
51 end
52 x = x + f(3)
53 ]]
54 assert.same x, 4
55
56 it "should work in conditional compilation", ->
57 macro if_debug = (debug_code) ->
58 if $LINE > 0
59 debug_code
60 else
61 ""
62 result = $if_debug "debug mode"
63 assert.same result, "debug mode"
64
65 it "should work with class system", ->
66 class Thing
67 value: 100
68 get_value: => @value
69 instance = Thing!
70 assert.same instance\get_value!, 100
71
72 it "should handle macro in switch expressions", ->
73 macro to_value = (x) -> x
74 result = switch $to_value "test"
75 when "test"
76 "matched"
77 else
78 "no match"
79 assert.same result, "matched"
80
81 it "should support macro in expression context", ->
82 macro triple = (x) -> "#{x} * 3"
83 result = 5 + $triple 2
84 assert.same result, 11
85
86 it "should handle $is_ast for type checking", ->
87 macro check_num = (x) ->
88 unless $is_ast(Num, x)
89 error "expected number"
90 x
91 result = $check_num 42
92 assert.same result, 42
93
94 it "should work with string interpolation", ->
95 macro format_result = (name, value) -> "#{name}: #{value}"
96 result = $format_result "test", 123
97 assert.same result, "test: 123"
98
99 it "should support function call syntax", ->
100 macro my_func = (x, y) -> "#{x} + #{y}"
101 result = $my_func(5, 10)
102 assert.same result, 15
103
104 it "should handle empty macro return", ->
105 macro skip = -> ""
106 a = 1
107 $skip
108 a = 2
109 assert.same a, 2
110
111 it "should work with table literals", ->
112 macro make_point = (x, y) -> "{x: #{x}, y: #{y}}"
113 point = $make_point 10, 20
114 assert.same point.x, 10
115 assert.same point.y, 20
116
117 it "should support conditional expressions in macro", ->
118 macro add_one = (x) -> "#{x} + 1"
119 result = $add_one 5
120 assert.same result, 6
121
122 it "should work with comprehension", ->
123 macro doubled_list = (items) -> "[_ * 2 for _ in *#{items}]"
124 result = $doubled_list {1, 2, 3}
125 assert.same result, {2, 4, 6}
126
127 it "should support complex expression macros", ->
128 macro calc = (a, b, c) -> "#{a} + #{b} * #{c}"
129 result = $calc 1, 2, 3
130 assert.same result, 7
131
132 it "should work with string literals", ->
133 macro greet = (name) -> '"Hello, #{name}"'
134 result = $greet "World"
135 assert.same result, "Hello, World"
diff --git a/spec/inputs/test/metatable_spec.yue b/spec/inputs/test/metatable_spec.yue
new file mode 100644
index 0000000..9a2ae6a
--- /dev/null
+++ b/spec/inputs/test/metatable_spec.yue
@@ -0,0 +1,86 @@
1describe "metatable", ->
2 it "should get metatable with <> syntax", ->
3 obj = setmetatable {value: 42}, {__index: {extra: "data"}}
4 mt = obj.<>
5 assert.is_true mt ~= nil
6
7 it "should set metatable with <>", ->
8 obj = {}
9 obj.<> = {__index: {value: 100}}
10 assert.same obj.value, 100
11
12 it "should access metatable with <>", ->
13 obj = setmetatable {}, {__index: {value: 50}}
14 result = obj.<>.__index.value
15 assert.same result, 50
16
17 it "should work with <index> metamethod", ->
18 obj = setmetatable {}, {
19 __index: (self, key) ->
20 if key == "computed"
21 return "computed_value"
22 }
23 assert.same obj.computed, "computed_value"
24
25 it "should work with <newindex> metamethod", ->
26 obj = setmetatable {}, {
27 __newindex: (self, key, value) ->
28 rawset self, "stored_" .. key, value
29 }
30 obj.test = 123
31 assert.same obj.stored_test, 123
32
33 it "should work with <add> metamethod", ->
34 obj = setmetatable({value: 10}, {
35 __add: (a, b) -> a.value + b.value
36 })
37 obj2 = setmetatable({value: 20}, {
38 __add: (a, b) -> a.value + b.value
39 })
40 result = obj + obj2
41 assert.same result, 30
42
43 it "should work with <call> metamethod", ->
44 obj = setmetatable {}, {
45 __call: (self, x) -> x * 2
46 }
47 result = obj 5
48 assert.same result, 10
49
50 it "should work with <tostring> metamethod", ->
51 obj = setmetatable {value: 42}, {
52 __tostring: (self) -> "Value: #{self.value}"
53 }
54 result = tostring obj
55 assert.same result, "Value: 42"
56
57 it "should work with <eq> metamethod", ->
58 obj1 = setmetatable({id: 1}, {
59 __eq: (a, b) -> a.id == b.id
60 })
61 obj2 = setmetatable({id: 1}, {
62 __eq: (a, b) -> a.id == b.id
63 })
64 assert.is_true obj1 == obj2
65
66 it "should destructure metatable", ->
67 obj = setmetatable {}, {
68 new: -> "new result"
69 update: -> "update result"
70 }
71 {:new, :update} = obj.<>
72 assert.is_true type(new) == "function"
73 assert.is_true type(update) == "function"
74
75 it "should check if two objects have same metatable", ->
76 mt = {value: 100}
77 obj1 = setmetatable {}, mt
78 obj2 = setmetatable {}, mt
79 assert.is_true obj1.<> == obj2.<>
80
81 it "should work with <concat> metamethod", ->
82 obj = setmetatable {value: "hello"}, {
83 __concat: (a, b) -> a.value .. b
84 }
85 result = obj .. " world"
86 assert.same result, "hello world"
diff --git a/spec/inputs/test/operators_spec.yue b/spec/inputs/test/operators_spec.yue
new file mode 100644
index 0000000..9b5585b
--- /dev/null
+++ b/spec/inputs/test/operators_spec.yue
@@ -0,0 +1,137 @@
1describe "operators", ->
2 it "should support addition", ->
3 assert.same 1 + 2, 3
4
5 it "should support subtraction", ->
6 assert.same 5 - 3, 2
7
8 it "should support multiplication", ->
9 assert.same 4 * 3, 12
10
11 it "should support division", ->
12 assert.same 10 / 2, 5
13
14 it "should support modulo", ->
15 assert.same 10 % 3, 1
16
17 it "should support exponentiation", ->
18 assert.same 2 ^ 3, 8
19
20 it "should support unary minus", ->
21 assert.same -5, -5
22
23 it "should support equality comparison", ->
24 assert.is_true 1 == 1
25 assert.is_false 1 == 2
26
27 it "should support inequality comparison", ->
28 assert.is_true 1 ~= 2
29 assert.is_false 1 ~= 1
30
31 it "should support less than", ->
32 assert.is_true 1 < 2
33 assert.is_false 2 < 1
34
35 it "should support greater than", ->
36 assert.is_true 2 > 1
37 assert.is_false 1 > 2
38
39 it "should support less than or equal", ->
40 assert.is_true 1 <= 2
41 assert.is_true 2 <= 2
42 assert.is_false 3 <= 2
43
44 it "should support greater than or equal", ->
45 assert.is_true 2 >= 1
46 assert.is_true 2 >= 2
47 assert.is_false 1 >= 2
48
49 it "should support logical and", ->
50 assert.same true and false, false
51 assert.same true and true, true
52 assert.same false and true, false
53
54 it "should support logical or", ->
55 assert.same true or false, true
56 assert.same false or true, true
57 assert.same false or false, false
58
59 it "should support logical not", ->
60 assert.same not true, false
61 assert.same not false, true
62 assert.same not nil, true
63
64 it "should support bitwise and", ->
65 assert.same 5 & 3, 1 -- 101 & 011 = 001
66
67 it "should support bitwise or", ->
68 assert.same 5 | 3, 7 -- 101 | 011 = 111
69
70 it "should support bitwise xor", ->
71 assert.same 5 ~ 3, 6 -- 101 ~ 011 = 110
72
73 it "should support left shift", ->
74 assert.same 2 << 3, 16
75
76 it "should support right shift", ->
77 assert.same 16 >> 2, 4
78
79 it "should support string concatenation", ->
80 assert.same "hello" .. " world", "hello world"
81
82 it "should support length operator", ->
83 assert.same #"hello", 5
84 assert.same #{1, 2, 3}, 3
85
86 it "should respect operator precedence", ->
87 assert.same 1 + 2 * 3, 7 -- multiplication before addition
88 assert.same (1 + 2) * 3, 9 -- parentheses first
89
90 it "should support compound assignment", ->
91 x = 10
92 x += 5
93 assert.same x, 15
94
95 it "should support compound subtraction", ->
96 x = 10
97 x -= 3
98 assert.same x, 7
99
100 it "should support compound multiplication", ->
101 x = 5
102 x *= 2
103 assert.same x, 10
104
105 it "should support compound division", ->
106 x = 20
107 x /= 4
108 assert.same x, 5
109
110 it "should handle division by zero", ->
111 -- Lua returns inf or nan
112 result = pcall(->
113 x = 10 / 0
114 )
115 assert.is_true result -- doesn't error in Lua
116
117 it "should handle very large numbers", ->
118 big = 1e100
119 assert.is_true big > 0
120
121 it "should handle very small numbers", ->
122 small = 1e-100
123 assert.is_true small > 0
124
125 it "should support negation", ->
126 assert.same -10, -10
127 assert.same --5, 5
128
129 it "should work with complex expressions", ->
130 result = (1 + 2) * (3 + 4) / 2
131 assert.same result, 10.5
132
133 it "should support power with decimal", ->
134 assert.same 4 ^ 0.5, 2
135
136 it "should handle modulo with negative numbers", ->
137 assert.same -10 % 3, 2 -- Lua's modulo behavior
diff --git a/spec/inputs/test/return_spec.yue b/spec/inputs/test/return_spec.yue
new file mode 100644
index 0000000..3bf0bed
--- /dev/null
+++ b/spec/inputs/test/return_spec.yue
@@ -0,0 +1,85 @@
1describe "return", ->
2 it "should return from comprehension", ->
3 fn = ->
4 return [x * 2 for x = 1, 5]
5 result = fn!
6 assert.same result, {2, 4, 6, 8, 10}
7
8 it "should return from table comprehension", ->
9 fn = ->
10 return {k, v for k, v in pairs {a: 1, b: 2}}
11 result = fn!
12 assert.same type(result), "table"
13
14 it "should return from nested if", ->
15 fn = (a, b) ->
16 if a
17 if b
18 return "both"
19 else
20 return "only a"
21 else
22 return "neither"
23 assert.same fn(true, true), "both"
24 assert.same fn(true, false), "only a"
25 assert.same fn(false, false), "neither"
26
27 it "should return from switch", ->
28 fn = (value) ->
29 return switch value
30 when 1 then "one"
31 when 2 then "two"
32 else "other"
33 assert.same fn(1), "one"
34 assert.same fn(2), "two"
35 assert.same fn(3), "other"
36
37 it "should return table literal", ->
38 fn = ->
39 return
40 value: 42
41 name: "test"
42 result = fn!
43 assert.same result.value, 42
44 assert.same result.name, "test"
45
46 it "should return array literal", ->
47 fn = ->
48 return
49 * 1
50 * 2
51 * 3
52 result = fn!
53 assert.same result, {1, 2, 3}
54
55 it "should return from with statement", ->
56 fn = (obj) ->
57 result = obj.value
58 return result
59 assert.same fn({value: 100}), 100
60
61 it "should return nil implicitly", ->
62 fn -> print "no return"
63 assert.same fn!, nil
64
65 it "should return multiple values", ->
66 fn -> 1, 2, 3
67 a, b, c = fn!
68 assert.same a, 1
69 assert.same b, 2
70 assert.same c, 3
71
72 it "should return from function call", ->
73 fn = ->
74 inner = -> 42
75 return inner!
76 assert.same fn!, 42
77
78 it "should handle return in expression context", ->
79 fn = (cond) ->
80 if cond
81 return "yes"
82 else
83 return "no"
84 assert.same fn(true), "yes"
85 assert.same fn(false), "no"
diff --git a/spec/inputs/test/string_spec.yue b/spec/inputs/test/string_spec.yue
new file mode 100644
index 0000000..b790518
--- /dev/null
+++ b/spec/inputs/test/string_spec.yue
@@ -0,0 +1,143 @@
1describe "string", ->
2 it "should support single quote strings", ->
3 s = 'hello'
4 assert.same s, "hello"
5
6 it "should support double quote strings", ->
7 s = "world"
8 assert.same s, "world"
9
10 it "should support escape sequences", ->
11 s = "hello\nworld"
12 assert.is_true s\match("\n") ~= nil
13
14 it "should support escaped quotes", ->
15 s = "he said \"hello\""
16 assert.same s, 'he said "hello"'
17
18 it "should support backslash escape", ->
19 s = "\\"
20 assert.same s, "\\"
21
22 it "should support multi-line strings with [[ ]]", ->
23 s = [[
24 hello
25 world
26 ]]
27 assert.is_true s\match("hello") ~= nil
28 assert.is_true s\match("world") ~= nil
29
30 it "should support multi-line strings with [=[ ]=]", ->
31 s = [==[
32 hello
33 world
34 ]==]
35 assert.is_true s\match("hello") ~= nil
36 assert.is_true s\match("world") ~= nil
37
38 it "should support string interpolation with double quotes", ->
39 name = "world"
40 s = "hello #{name}"
41 assert.same s, "hello world"
42
43 it "should support expression interpolation", ->
44 a, b = 1, 2
45 s = "#{a} + #{b} = #{a + b}"
46 assert.same s, "1 + 2 = 3"
47
48 it "should not interpolate in single quotes", ->
49 name = "world"
50 s = 'hello #{name}'
51 assert.same s, "hello #{name}"
52
53 it "should escape interpolation with \\#", ->
54 name = "world"
55 s = "hello \\#{name}"
56 assert.same s, "hello #{name}"
57
58 it "should support method calls on string literals", ->
59 result = "hello"\upper!
60 assert.same result, "HELLO"
61
62 it "should support chained method calls", ->
63 result = "hello world"\upper!\match "HELLO"
64 assert.same result, "HELLO"
65
66 it "should support YAML style strings", ->
67 s = |
68 hello
69 world
70 assert.is_true s\match("hello") ~= nil
71 assert.is_true s\match("world") ~= nil
72
73 it "should support YAML style with interpolation", ->
74 name = "test"
75 s = |
76 hello #{name}
77 assert.same s, "hello test\n"
78
79 it "should support string concatenation", ->
80 s = "hello" .. " " .. "world"
81 assert.same s, "hello world"
82
83 it "should handle empty strings", ->
84 s = ""
85 assert.same s, ""
86
87 it "should support Unicode characters", ->
88 s = "hello 世界"
89 assert.is_true s\match("世界") ~= nil
90
91 it "should support string length", ->
92 s = "hello"
93 assert.same #s, 5
94
95 it "should support multi-line YAML with complex content", ->
96 config = |
97 key1: value1
98 key2: value2
99 key3: value3
100 assert.is_true config\match("key1") ~= nil
101
102 it "should support interpolation in YAML strings", ->
103 x, y = 10, 20
104 s = |
105 point:
106 x: #{x}
107 y: #{y}
108 assert.is_true s\match("x: 10") ~= nil
109 assert.is_true s\match("y: 20") ~= nil
110
111 it "should support function call in interpolation", ->
112 s = "result: #{-> 42}"
113 assert.same s, "result: 42"
114
115 it "should support table indexing in interpolation", ->
116 t = {value: 100}
117 s = "value: #{t.value}"
118 assert.same s, "value: 100"
119
120 it "should handle escaped characters correctly", ->
121 s = "tab:\t, newline:\n, return:\r"
122 assert.is_true s\match("\t") ~= nil
123 assert.is_true s\match("\n") ~= nil
124
125 it "should support string methods with colon syntax", ->
126 s = "hello"
127 assert.same s\sub(1, 2), "he"
128
129 it "should work in expressions", ->
130 result = "hello" .. " world"
131 assert.same result, "hello world"
132
133 it "should support octal escape", ->
134 s = "\65"
135 assert.same s, "A"
136
137 it "should support hex escape", ->
138 s = "\x41"
139 assert.same s, "A"
140
141 it "should support unicode escape", ->
142 s = "\u{4e16}"
143 assert.same s, "世"
diff --git a/spec/inputs/test/switch_spec.yue b/spec/inputs/test/switch_spec.yue
new file mode 100644
index 0000000..3696cbe
--- /dev/null
+++ b/spec/inputs/test/switch_spec.yue
@@ -0,0 +1,267 @@
1describe "switch", ->
2 it "should match single value", ->
3 value = "cool"
4 result = switch value
5 when "cool"
6 "matched"
7 else
8 "not matched"
9 assert.same result, "matched"
10
11 it "should match multiple values with or", ->
12 hi = "world"
13 matched = false
14 switch hi
15 when "one", "two"
16 matched = true
17 assert.is_false matched
18
19 hi = "one"
20 switch hi
21 when "one", "two"
22 matched = true
23 assert.is_true matched
24
25 it "should execute else branch when no match", ->
26 value = "other"
27 result = switch value
28 when "cool"
29 "matched cool"
30 when "yeah"
31 "matched yeah"
32 else
33 "else branch"
34 assert.same result, "else branch"
35
36 it "should destructure table with single key", ->
37 tb = {x: 100}
38 result = switch tb
39 when :x
40 x
41 else
42 "no match"
43 assert.same result, 100
44
45 it "should destructure table with multiple keys", ->
46 tb = {x: 100, y: 200}
47 result = switch tb
48 when :x, :y
49 x + y
50 else
51 "no match"
52 assert.same result, 300
53
54 it "should destructure table with default values", ->
55 tb = {a: 1}
56 switch tb
57 when {:a = 1, :b = 2}
58 assert.same a, 1
59 assert.same b, 2
60
61 it "should destructure nested tables", ->
62 dict = {
63 {}
64 {1, 2, 3}
65 a: b: c: 1
66 x: y: z: 1
67 }
68 matched = false
69 switch dict
70 when {
71 first
72 {one, two, three}
73 a: b: :c
74 x: y: :z
75 }
76 matched = first == {} and one == 1 and two == 2 and three == 3 and c == 1 and z == 1
77 assert.is_true matched
78
79 it "should destructure arrays with exact match", ->
80 tb = {1, 2, 3}
81 result = switch tb
82 when [1, 2, 3]
83 "exact match"
84 else
85 "no match"
86 assert.same result, "exact match"
87
88 it "should destructure arrays with variables", ->
89 tb = {1, "b", 3}
90 result = switch tb
91 when [1, b, 3]
92 b
93 else
94 "no match"
95 assert.same result, "b"
96
97 it "should destructure arrays with defaults", ->
98 tb = {1, 2}
99 result = switch tb
100 when [1, 2, b = 3]
101 b
102 else
103 "no match"
104 assert.same result, 3
105
106 it "should match pattern with __class", ->
107 class ClassA
108 class ClassB
109 item = ClassA!
110 result = switch item
111 when __class: ClassA
112 "Object A"
113 when __class: ClassB
114 "Object B"
115 else
116 "unknown"
117 assert.same result, "Object A"
118
119 it "should match pattern with metatable", ->
120 tb = setmetatable {}, {__mode: "v"}
121 metatable_matched = false
122 switch tb
123 when <>: mt
124 metatable_matched = mt ~= nil
125 assert.is_true metatable_matched
126
127 it "should use switch as expression in assignment", ->
128 tb = {x: "abc"}
129 matched = switch tb
130 when 1
131 "1"
132 when :x
133 x
134 when false
135 "false"
136 else
137 nil
138 assert.same matched, "abc"
139
140 it "should use switch in return statement", ->
141 fn = (tb) ->
142 switch tb
143 when nil
144 "invalid"
145 when :a, :b
146 "#{a + b}"
147 when 1, 2, 3, 4, 5
148 "number 1 - 5"
149 else
150 "should not reach here"
151 assert.same fn({a: 1, b: 2}), "3"
152 assert.same fn(3), "number 1 - 5"
153 assert.same fn(nil), "invalid"
154
155 it "should support pattern matching assignment with :=", ->
156 v = "hello"
157 matched = false
158 switch v := "hello"
159 when "hello"
160 matched = true
161 else
162 matched = false
163 assert.is_true matched
164 assert.same v, "hello"
165
166 it "should match with computed expressions", ->
167 hi = 4
168 matched = false
169 switch hi
170 when 3+1, (-> 4)!, 5-1
171 matched = true
172 assert.is_true matched
173
174 it "should handle nested array destructuring", ->
175 tb = {
176 {a: 1, b: 2}
177 {a: 3, b: 4}
178 {a: 5, b: 6}
179 "fourth"
180 }
181 result = switch tb
182 when [
183 {a: 1, b: 2}
184 {a: 3, b: 4}
185 {a: 5, b: 6}
186 fourth
187 ]
188 fourth
189 else
190 "no match"
191 assert.same result, "fourth"
192
193 it "should match combined patterns", ->
194 tb = {success: true, result: "data"}
195 result = switch tb
196 when success: true, :result
197 {"success", result}
198 when success: false
199 {"failed", result}
200 else
201 {"invalid"}
202 assert.same result, {"success", "data"}
203
204 it "should match type discriminated patterns", ->
205 tb = {type: "success", content: "data"}
206 result = switch tb
207 when {type: "success", :content}
208 {"success", content}
209 when {type: "error", :content}
210 {"error", content}
211 else
212 {"invalid"}
213 assert.same result, {"success", "data"}
214
215 it "should match with wildcard array capture", ->
216 clientData = {"Meta", "CUST_1001", "CHK123"}
217 metadata = nil
218 customerId = nil
219 checksum = nil
220 switch clientData
221 when [...capturedMetadata, customerId, checksum]
222 metadata = capturedMetadata
223 assert.same metadata, {"Meta"}
224 assert.same customerId, "CUST_1001"
225 assert.same checksum, "CHK123"
226
227 it "should work with complex tuple patterns", ->
228 handlePath = (segments) ->
229 switch segments
230 when [..._, resource, action]
231 {"Resource: #{resource}", "Action: #{action}"}
232 else
233 {"no match"}
234 result = handlePath {"admin", "logs", "view"}
235 assert.same result, {"Resource: logs", "Action: view"}
236
237 it "should match boolean false correctly", ->
238 items = {
239 {x: 100, y: 200}
240 {width: 300, height: 400}
241 false
242 }
243 results = {}
244 for item in *items
245 switch item
246 when :x, :y
247 table.insert results, "Vec2"
248 when :width, :height
249 table.insert results, "Size"
250 when false
251 table.insert results, "None"
252 assert.same results, {"Vec2", "Size", "None"}
253
254 it "should handle switch with then syntax", ->
255 value = "cool"
256 result = switch value
257 when "cool" then "matched cool"
258 else "else branch"
259 assert.same result, "matched cool"
260
261 it "should handle switch in function call", ->
262 getValue = ->
263 switch something
264 when 1 then "yes"
265 else "no"
266 something = 1
267 assert.same getValue!, "yes"
diff --git a/spec/inputs/test/vararg_spec.yue b/spec/inputs/test/vararg_spec.yue
new file mode 100644
index 0000000..4d2557f
--- /dev/null
+++ b/spec/inputs/test/vararg_spec.yue
@@ -0,0 +1,69 @@
1describe "vararg", ->
2 it "should pass varargs to function", ->
3 sum = (...) ->
4 total = 0
5 for i = 1, select("#", ...)
6 if type(select(i, ...)) == "number"
7 total += select(i, ...)
8 total
9 result = sum 1, 2, 3, 4, 5
10 assert.same result, 15
11
12 it "should handle empty varargs", ->
13 fn = (...) -> select "#", ...
14 result = fn!
15 assert.same result, 0
16
17 it "should spread varargs in function call", ->
18 receiver = (a, b, c) -> {a, b, c}
19 source = -> 1, 2, 3
20 result = receiver source!
21 assert.same result, {1, 2, 3}
22
23 it "should use varargs in table", ->
24 fn = (...) -> {...}
25 result = fn 1, 2, 3
26 assert.same result, {1, 2, 3}
27
28 it "should forward varargs", ->
29 middle = (fn, ...) -> fn(...)
30 inner = (a, b, c) -> a + b + c
31 result = middle inner, 1, 2, 3
32 assert.same result, 6
33
34 it "should count varargs with select", ->
35 fn = (...) -> select "#", ...
36 assert.same fn(1, 2, 3), 3
37 assert.same fn("a", "b"), 2
38 assert.same fn!, 0
39
40 it "should select from varargs", ->
41 fn = (...) -> select 2, ...
42 result = fn 1, 2, 3
43 assert.same result, 2
44
45 it "should work with named parameters and varargs", ->
46 fn = (first, ...) ->
47 {first, select("#", ...)}
48 result = fn "first", "second", "third"
49 assert.same result, {"first", 2}
50
51 it "should handle nil in varargs", ->
52 fn = (...) ->
53 count = select "#", ...
54 has_nil = false
55 for i = 1, count
56 has_nil = true if select(i, ...) == nil
57 {count, has_nil}
58 result = fn 1, nil, 3
59 assert.same result, {3, true}
60
61 it "should work with table unpack", ->
62 fn = (...) -> {...}
63 result = fn table.unpack {1, 2, 3}
64 assert.same result, {1, 2, 3}
65
66 it "should work with varargs in comprehension", ->
67 fn = (...) -> [x * 2 for x in *{...}]
68 result = fn 1, 2, 3, 4, 5
69 assert.same result, {2, 4, 6, 8, 10}
diff --git a/spec/inputs/test/with_spec.yue b/spec/inputs/test/with_spec.yue
new file mode 100644
index 0000000..c3b8428
--- /dev/null
+++ b/spec/inputs/test/with_spec.yue
@@ -0,0 +1,104 @@
1describe "with", ->
2 it "should access property with . syntax", ->
3 obj = {value: 42}
4 with obj
5 result = .value
6 assert.same result, 42
7
8 it "should call method with : syntax", ->
9 obj = {func: -> "result"}
10 with obj
11 result = \func!
12 assert.same result, "result"
13
14 it "should work as statement", ->
15 obj = {x: 10, y: 20}
16 with obj
17 .sum = .x + .y
18 assert.same obj.sum, 30
19
20 it "should support nested with", ->
21 outer = {inner: {value: 100}}
22 with outer.inner
23 result = .value
24 assert.same result, 100
25
26 it "should work with? safely", ->
27 obj = {x: 5}
28 with obj
29 result = .x
30 assert.same result, 5
31
32 it "should work with if inside with", ->
33 obj = {x: 10, y: 20}
34 with obj
35 if .x > 5
36 result = .x + .y
37 assert.same result, 30
38
39 it "should work with switch inside with", ->
40 obj = {type: "add", a: 5, b: 3}
41 with obj
42 result = switch .type
43 when "add" then .a + .b
44 else 0
45 assert.same result, 8
46
47 it "should work with loop inside with", ->
48 obj = {items: {1, 2, 3}}
49 sum = 0
50 with obj
51 for item in *.items
52 sum += item
53 assert.same sum, 6
54
55 it "should work with destructure", ->
56 obj = {x: 1, y: 2, z: 3}
57 with obj
58 {x, y, z} = obj
59 assert.same x, 1
60 assert.same y, 2
61 assert.same z, 3
62
63 it "should handle simple with body", ->
64 obj = {value: 42}
65 with obj
66 .value2 = 100
67 assert.same obj.value2, 100
68
69 it "should work with return inside", ->
70 obj = {value: 100}
71 fn = ->
72 with obj
73 return .value
74 assert.same fn!, 100
75
76 it "should work with break inside", ->
77 sum = 0
78 for i = 1, 5
79 obj = {value: i}
80 with obj
81 if .value == 3
82 break
83 sum += .value
84 assert.same sum, 3 -- 1 + 2
85
86 it "should chain property access", ->
87 obj = {a: {b: {c: 42}}}
88 with obj.a.b
89 result = .c
90 assert.same result, 42
91
92 it "should work with multiple statements", ->
93 obj = {x: 1, y: 2}
94 sum = 0
95 with obj
96 sum += .x
97 sum += .y
98 assert.same sum, 3
99
100 it "should preserve object reference", ->
101 obj = {value: 42}
102 with obj
103 .value = 100
104 assert.same obj.value, 100