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