From e5f145bfbd5d96b015771e42539a2ff95ee6c8c5 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 06:24:09 -0600 Subject: [PATCH 01/11] updated assert to handle return values --- core/global.d.ts | 6 ++- test/__snapshots__/global.spec.ts.snap | 60 ++++++++++++++++++++++++++ test/global.spec.ts | 26 +++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/core/global.d.ts b/core/global.d.ts index 23efda4..d4d37bc 100644 --- a/core/global.d.ts +++ b/core/global.d.ts @@ -25,7 +25,11 @@ declare const _G: typeof globalThis; * otherwise, returns all its arguments. In case of error, `message` is the * error object; when absent, it defaults to "assertion failed!" */ -declare function assert(v: any, message?: string): asserts v; +declare function assert(v: V): Exclude; +declare function assert( + v: V, + ...args: A +): LuaMultiReturn<[Exclude, ...A]>; /** * This function is a generic interface to the garbage collector. It performs diff --git a/test/__snapshots__/global.spec.ts.snap b/test/__snapshots__/global.spec.ts.snap index d84335f..62c50db 100644 --- a/test/__snapshots__/global.spec.ts.snap +++ b/test/__snapshots__/global.spec.ts.snap @@ -4,6 +4,18 @@ exports[`Lua version 5.1 / global assert 1`] = `"assert({bla = \\"not false\\"}) exports[`Lua version 5.1 / global assert 2`] = `"assert(false, \\"assert message\\")"`; +exports[`Lua version 5.1 / global assert with multi-return 1`] = ` +"v, a, b = assert({bla = \\"not false\\"}, {foo = \\"FOO\\"}, {bar = \\"BAR\\"}) +bla = v.bla +foo = a.foo +bar = b.bar" +`; + +exports[`Lua version 5.1 / global assert with return 1`] = ` +"v = assert({bla = \\"not false\\"}) +bla = v.bla" +`; + exports[`Lua version 5.1 / global getmetatable 1`] = ` "metatable = getmetatable({}) add = metatable.__add" @@ -64,6 +76,18 @@ exports[`Lua version 5.2 / global assert 1`] = `"assert({bla = \\"not false\\"}) exports[`Lua version 5.2 / global assert 2`] = `"assert(false, \\"assert message\\")"`; +exports[`Lua version 5.2 / global assert with multi-return 1`] = ` +"v, a, b = assert({bla = \\"not false\\"}, {foo = \\"FOO\\"}, {bar = \\"BAR\\"}) +bla = v.bla +foo = a.foo +bar = b.bar" +`; + +exports[`Lua version 5.2 / global assert with return 1`] = ` +"v = assert({bla = \\"not false\\"}) +bla = v.bla" +`; + exports[`Lua version 5.2 / global getmetatable 1`] = ` "metatable = getmetatable({}) add = metatable.__add" @@ -124,6 +148,18 @@ exports[`Lua version 5.3 / global assert 1`] = `"assert({bla = \\"not false\\"}) exports[`Lua version 5.3 / global assert 2`] = `"assert(false, \\"assert message\\")"`; +exports[`Lua version 5.3 / global assert with multi-return 1`] = ` +"v, a, b = assert({bla = \\"not false\\"}, {foo = \\"FOO\\"}, {bar = \\"BAR\\"}) +bla = v.bla +foo = a.foo +bar = b.bar" +`; + +exports[`Lua version 5.3 / global assert with return 1`] = ` +"v = assert({bla = \\"not false\\"}) +bla = v.bla" +`; + exports[`Lua version 5.3 / global getmetatable 1`] = ` "metatable = getmetatable({}) add = metatable.__add" @@ -184,6 +220,18 @@ exports[`Lua version 5.4 / global assert 1`] = `"assert({bla = \\"not false\\"}) exports[`Lua version 5.4 / global assert 2`] = `"assert(false, \\"assert message\\")"`; +exports[`Lua version 5.4 / global assert with multi-return 1`] = ` +"v, a, b = assert({bla = \\"not false\\"}, {foo = \\"FOO\\"}, {bar = \\"BAR\\"}) +bla = v.bla +foo = a.foo +bar = b.bar" +`; + +exports[`Lua version 5.4 / global assert with return 1`] = ` +"v = assert({bla = \\"not false\\"}) +bla = v.bla" +`; + exports[`Lua version 5.4 / global getmetatable 1`] = ` "metatable = getmetatable({}) add = metatable.__add" @@ -244,6 +292,18 @@ exports[`Lua version JIT / global assert 1`] = `"assert({bla = \\"not false\\"}) exports[`Lua version JIT / global assert 2`] = `"assert(false, \\"assert message\\")"`; +exports[`Lua version JIT / global assert with multi-return 1`] = ` +"v, a, b = assert({bla = \\"not false\\"}, {foo = \\"FOO\\"}, {bar = \\"BAR\\"}) +bla = v.bla +foo = a.foo +bar = b.bar" +`; + +exports[`Lua version JIT / global assert with return 1`] = ` +"v = assert({bla = \\"not false\\"}) +bla = v.bla" +`; + exports[`Lua version JIT / global getmetatable 1`] = ` "metatable = getmetatable({}) add = metatable.__add" diff --git a/test/global.spec.ts b/test/global.spec.ts index f74e8a2..68ed1ef 100644 --- a/test/global.spec.ts +++ b/test/global.spec.ts @@ -12,6 +12,32 @@ describeForEachLuaTarget('global', (target) => { expect(lua).toMatchSnapshot(); }); + test('assert with return', () => { + const lua = tstl( + target, + ` + const v = assert({ bla: "not false"}); + const bla = v.bla; + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('assert with multi-return', () => { + const lua = tstl( + target, + ` + const [v, a, b] = assert({ bla: "not false"}, { foo: "FOO" }, { bar: "BAR" }); + const bla = v.bla; + const foo = a.foo; + const bar = b.bar; + ` + ); + + expect(lua).toMatchSnapshot(); + }); + test('assert', () => { const lua = tstl( target, From d1662025cf09b2758627babdfb0a2385a2e13a76 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 06:48:26 -0600 Subject: [PATCH 02/11] updated getmetatable to allow any type as input, including strings which have a metatable --- core/global.d.ts | 2 +- test/__snapshots__/global.spec.ts.snap | 25 +++++++++++++++++++++++++ test/global.spec.ts | 12 ++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/core/global.d.ts b/core/global.d.ts index d4d37bc..4704d7e 100644 --- a/core/global.d.ts +++ b/core/global.d.ts @@ -113,7 +113,7 @@ declare function error(message: string, level?: number): never; * metatable has a __metatable field, returns the associated value. Otherwise, * returns the metatable of the given object. */ -declare function getmetatable(object: T): LuaMetatable | undefined; +declare function getmetatable(object: T): LuaMetatable | undefined; /** * Returns three values (an iterator function, the table t, and 0) so that the diff --git a/test/__snapshots__/global.spec.ts.snap b/test/__snapshots__/global.spec.ts.snap index 62c50db..9b602ff 100644 --- a/test/__snapshots__/global.spec.ts.snap +++ b/test/__snapshots__/global.spec.ts.snap @@ -21,6 +21,11 @@ exports[`Lua version 5.1 / global getmetatable 1`] = ` add = metatable.__add" `; +exports[`Lua version 5.1 / global getmetatable on string 1`] = ` +"metatable = getmetatable(\\"foo\\") +index = metatable.__index" +`; + exports[`Lua version 5.1 / global ipairs 1`] = ` "for i, v in ipairs({1, 2, 3}) do print(i, v) @@ -93,6 +98,11 @@ exports[`Lua version 5.2 / global getmetatable 1`] = ` add = metatable.__add" `; +exports[`Lua version 5.2 / global getmetatable on string 1`] = ` +"metatable = getmetatable(\\"foo\\") +index = metatable.__index" +`; + exports[`Lua version 5.2 / global ipairs 1`] = ` "for i, v in ipairs({1, 2, 3}) do print(i, v) @@ -165,6 +175,11 @@ exports[`Lua version 5.3 / global getmetatable 1`] = ` add = metatable.__add" `; +exports[`Lua version 5.3 / global getmetatable on string 1`] = ` +"metatable = getmetatable(\\"foo\\") +index = metatable.__index" +`; + exports[`Lua version 5.3 / global ipairs 1`] = ` "for i, v in ipairs({1, 2, 3}) do print(i, v) @@ -237,6 +252,11 @@ exports[`Lua version 5.4 / global getmetatable 1`] = ` add = metatable.__add" `; +exports[`Lua version 5.4 / global getmetatable on string 1`] = ` +"metatable = getmetatable(\\"foo\\") +index = metatable.__index" +`; + exports[`Lua version 5.4 / global ipairs 1`] = ` "for i, v in ipairs({1, 2, 3}) do print(i, v) @@ -309,6 +329,11 @@ exports[`Lua version JIT / global getmetatable 1`] = ` add = metatable.__add" `; +exports[`Lua version JIT / global getmetatable on string 1`] = ` +"metatable = getmetatable(\\"foo\\") +index = metatable.__index" +`; + exports[`Lua version JIT / global ipairs 1`] = ` "for i, v in ipairs({1, 2, 3}) do print(i, v) diff --git a/test/global.spec.ts b/test/global.spec.ts index 68ed1ef..58a1550 100644 --- a/test/global.spec.ts +++ b/test/global.spec.ts @@ -61,6 +61,18 @@ describeForEachLuaTarget('global', (target) => { expect(lua).toMatchSnapshot(); }); + test('getmetatable on string', () => { + const lua = tstl( + target, + ` + const metatable = getmetatable("foo"); + const index = metatable!.__index; + ` + ); + + expect(lua).toMatchSnapshot(); + }); + test('ipairs', () => { const lua = tstl( target, From c379220018a0a2761df6eb7f67fff59949ae4979 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 07:56:03 -0600 Subject: [PATCH 03/11] fixed setmetatable index metamethod handling --- core/global.d.ts | 13 ++- core/metatable.d.ts | 4 +- test/__snapshots__/global.spec.ts.snap | 105 +++++++++++++++++++++++++ test/global.spec.ts | 37 +++++++++ 4 files changed, 154 insertions(+), 5 deletions(-) diff --git a/core/global.d.ts b/core/global.d.ts index 4704d7e..c3dcb57 100644 --- a/core/global.d.ts +++ b/core/global.d.ts @@ -238,10 +238,17 @@ declare function select(index: '#', ...args: T[]): number; * * This function returns table. */ -declare function setmetatable( +declare function setmetatable< + T extends object, + TIndex extends object | ((this: T, key: any) => any) | undefined = undefined +>( table: T, - metatable: LuaMetatable | null | undefined -): T & TIndex; + metatable?: LuaMetatable | null +): TIndex extends (this: T, key: infer TKey) => infer TValue + ? T & { [K in TKey & string]: TValue } + : TIndex extends object + ? T & TIndex + : T; /** * When called with no base, tonumber tries to convert its argument to a number. diff --git a/core/metatable.d.ts b/core/metatable.d.ts index fb411e5..7636dea 100644 --- a/core/metatable.d.ts +++ b/core/metatable.d.ts @@ -1,6 +1,6 @@ // Based on https://www.lua.org/manual/5.3/manual.html#2.4 -interface LuaMetatable { +interface LuaMetatable any) | undefined> { /** * the addition (+) operation. If any operand for an addition is not a number * (nor a string coercible to a number), Lua will try to call a metamethod. @@ -102,7 +102,7 @@ interface LuaMetatable { * this table with key. (This indexing is regular, not raw, and therefore can * trigger another metamethod.) */ - __index?: TIndex | ((this: T, key: any, value: any) => any); + __index?: TIndex; /** * The indexing assignment table[key] = value. Like the index event, this diff --git a/test/__snapshots__/global.spec.ts.snap b/test/__snapshots__/global.spec.ts.snap index 9b602ff..9c12b7a 100644 --- a/test/__snapshots__/global.spec.ts.snap +++ b/test/__snapshots__/global.spec.ts.snap @@ -69,6 +69,27 @@ exports[`Lua version 5.1 / global select destructured 1`] = `"b, c = select(2, \ exports[`Lua version 5.1 / global select with # 1`] = `"count = select(\\"#\\", \\"a\\", \\"b\\", \\"c\\")"`; +exports[`Lua version 5.1 / global setmetatable with function index 1`] = ` +"tbl = setmetatable( + {}, + { + __index = function(____, key) return tostring(key) .. \\"bar\\" end + } +) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + +exports[`Lua version 5.1 / global setmetatable with no index 1`] = `"tbl = setmetatable({})"`; + +exports[`Lua version 5.1 / global setmetatable with table index 1`] = ` +"tbl = setmetatable({}, {__index = {foo = \\"bar\\"}}) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + exports[`Lua version 5.1 / global tonumber 1`] = `"number = tonumber(\\"213.4\\")"`; exports[`Lua version 5.1 / global tonumber with base 1`] = `"number = tonumber(\\"213.4\\", 5)"`; @@ -146,6 +167,27 @@ exports[`Lua version 5.2 / global select destructured 1`] = `"b, c = select(2, \ exports[`Lua version 5.2 / global select with # 1`] = `"count = select(\\"#\\", \\"a\\", \\"b\\", \\"c\\")"`; +exports[`Lua version 5.2 / global setmetatable with function index 1`] = ` +"tbl = setmetatable( + {}, + { + __index = function(____, key) return tostring(key) .. \\"bar\\" end + } +) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + +exports[`Lua version 5.2 / global setmetatable with no index 1`] = `"tbl = setmetatable({})"`; + +exports[`Lua version 5.2 / global setmetatable with table index 1`] = ` +"tbl = setmetatable({}, {__index = {foo = \\"bar\\"}}) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + exports[`Lua version 5.2 / global tonumber 1`] = `"number = tonumber(\\"213.4\\")"`; exports[`Lua version 5.2 / global tonumber with base 1`] = `"number = tonumber(\\"213.4\\", 5)"`; @@ -223,6 +265,27 @@ exports[`Lua version 5.3 / global select destructured 1`] = `"b, c = select(2, \ exports[`Lua version 5.3 / global select with # 1`] = `"count = select(\\"#\\", \\"a\\", \\"b\\", \\"c\\")"`; +exports[`Lua version 5.3 / global setmetatable with function index 1`] = ` +"tbl = setmetatable( + {}, + { + __index = function(____, key) return tostring(key) .. \\"bar\\" end + } +) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + +exports[`Lua version 5.3 / global setmetatable with no index 1`] = `"tbl = setmetatable({})"`; + +exports[`Lua version 5.3 / global setmetatable with table index 1`] = ` +"tbl = setmetatable({}, {__index = {foo = \\"bar\\"}}) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + exports[`Lua version 5.3 / global tonumber 1`] = `"number = tonumber(\\"213.4\\")"`; exports[`Lua version 5.3 / global tonumber with base 1`] = `"number = tonumber(\\"213.4\\", 5)"`; @@ -300,6 +363,27 @@ exports[`Lua version 5.4 / global select destructured 1`] = `"b, c = select(2, \ exports[`Lua version 5.4 / global select with # 1`] = `"count = select(\\"#\\", \\"a\\", \\"b\\", \\"c\\")"`; +exports[`Lua version 5.4 / global setmetatable with function index 1`] = ` +"tbl = setmetatable( + {}, + { + __index = function(____, key) return tostring(key) .. \\"bar\\" end + } +) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + +exports[`Lua version 5.4 / global setmetatable with no index 1`] = `"tbl = setmetatable({})"`; + +exports[`Lua version 5.4 / global setmetatable with table index 1`] = ` +"tbl = setmetatable({}, {__index = {foo = \\"bar\\"}}) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + exports[`Lua version 5.4 / global tonumber 1`] = `"number = tonumber(\\"213.4\\")"`; exports[`Lua version 5.4 / global tonumber with base 1`] = `"number = tonumber(\\"213.4\\", 5)"`; @@ -377,6 +461,27 @@ exports[`Lua version JIT / global select destructured 1`] = `"b, c = select(2, \ exports[`Lua version JIT / global select with # 1`] = `"count = select(\\"#\\", \\"a\\", \\"b\\", \\"c\\")"`; +exports[`Lua version JIT / global setmetatable with function index 1`] = ` +"tbl = setmetatable( + {}, + { + __index = function(____, key) return tostring(key) .. \\"bar\\" end + } +) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + +exports[`Lua version JIT / global setmetatable with no index 1`] = `"tbl = setmetatable({})"`; + +exports[`Lua version JIT / global setmetatable with table index 1`] = ` +"tbl = setmetatable({}, {__index = {foo = \\"bar\\"}}) +takesStr = function(____, s) +end +takesStr(_G, tbl.foo)" +`; + exports[`Lua version JIT / global tonumber 1`] = `"number = tonumber(\\"213.4\\")"`; exports[`Lua version JIT / global tonumber with base 1`] = `"number = tonumber(\\"213.4\\", 5)"`; diff --git a/test/global.spec.ts b/test/global.spec.ts index 58a1550..e209eca 100644 --- a/test/global.spec.ts +++ b/test/global.spec.ts @@ -187,6 +187,43 @@ describeForEachLuaTarget('global', (target) => { expect(lua).toMatchSnapshot(); }); + test('setmetatable with table index', () => { + const lua = tstl( + target, + ` + const tbl = setmetatable({}, {__index: {foo: "bar"}}); + const takesStr = (s: string) => {}; + takesStr(tbl.foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('setmetatable with function index', () => { + const lua = tstl( + target, + ` + const tbl = setmetatable({}, {__index: (key: string) => key + "bar"}); + const takesStr = (s: string) => {}; + takesStr(tbl.foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('setmetatable with no index', () => { + const lua = tstl( + target, + ` + const tbl = setmetatable({}); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + test('tonumber', () => { const lua = tstl( target, From 5cfaff1475f39497afccba12aa90d5088b73c7aa Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 08:03:27 -0600 Subject: [PATCH 04/11] added support for LuaTables to pairs --- core/global.d.ts | 3 ++ test/__snapshots__/global.spec.ts.snap | 60 ++++++++++++++++++++++++++ test/global.spec.ts | 18 ++++++++ 3 files changed, 81 insertions(+) diff --git a/core/global.d.ts b/core/global.d.ts index c3dcb57..fe56b5d 100644 --- a/core/global.d.ts +++ b/core/global.d.ts @@ -157,6 +157,9 @@ declare function next(table: object, index?: any): LuaMultiReturn<[any, any] | [ * See function next for the caveats of modifying the table during its * traversal. */ +declare function pairs( + t: LuaTable +): LuaIterable>; declare function pairs(t: T): LuaIterable>; /** diff --git a/test/__snapshots__/global.spec.ts.snap b/test/__snapshots__/global.spec.ts.snap index 9c12b7a..ecc346b 100644 --- a/test/__snapshots__/global.spec.ts.snap +++ b/test/__snapshots__/global.spec.ts.snap @@ -42,6 +42,18 @@ exports[`Lua version 5.1 / global pairs 1`] = ` end" `; +exports[`Lua version 5.1 / global pairs with LuaTable 1`] = ` +"tbl = {} +tbl.foo = \\"bar\\" +tbl.baz = \\"bur\\" +takesStr = function(____, str) +end +for k, v in pairs(tbl) do + takesStr(_G, k) + takesStr(_G, v) +end" +`; + exports[`Lua version 5.1 / global pcall 1`] = ` "success, resultOrMessage = pcall( function(a) return true end, @@ -140,6 +152,18 @@ exports[`Lua version 5.2 / global pairs 1`] = ` end" `; +exports[`Lua version 5.2 / global pairs with LuaTable 1`] = ` +"tbl = {} +tbl.foo = \\"bar\\" +tbl.baz = \\"bur\\" +takesStr = function(____, str) +end +for k, v in pairs(tbl) do + takesStr(_G, k) + takesStr(_G, v) +end" +`; + exports[`Lua version 5.2 / global pcall 1`] = ` "success, resultOrMessage = pcall( function(a) return true end, @@ -238,6 +262,18 @@ exports[`Lua version 5.3 / global pairs 1`] = ` end" `; +exports[`Lua version 5.3 / global pairs with LuaTable 1`] = ` +"tbl = {} +tbl.foo = \\"bar\\" +tbl.baz = \\"bur\\" +takesStr = function(____, str) +end +for k, v in pairs(tbl) do + takesStr(_G, k) + takesStr(_G, v) +end" +`; + exports[`Lua version 5.3 / global pcall 1`] = ` "success, resultOrMessage = pcall( function(a) return true end, @@ -336,6 +372,18 @@ exports[`Lua version 5.4 / global pairs 1`] = ` end" `; +exports[`Lua version 5.4 / global pairs with LuaTable 1`] = ` +"tbl = {} +tbl.foo = \\"bar\\" +tbl.baz = \\"bur\\" +takesStr = function(____, str) +end +for k, v in pairs(tbl) do + takesStr(_G, k) + takesStr(_G, v) +end" +`; + exports[`Lua version 5.4 / global pcall 1`] = ` "success, resultOrMessage = pcall( function(a) return true end, @@ -434,6 +482,18 @@ exports[`Lua version JIT / global pairs 1`] = ` end" `; +exports[`Lua version JIT / global pairs with LuaTable 1`] = ` +"tbl = {} +tbl.foo = \\"bar\\" +tbl.baz = \\"bur\\" +takesStr = function(____, str) +end +for k, v in pairs(tbl) do + takesStr(_G, k) + takesStr(_G, v) +end" +`; + exports[`Lua version JIT / global pcall 1`] = ` "success, resultOrMessage = pcall( function(a) return true end, diff --git a/test/global.spec.ts b/test/global.spec.ts index e209eca..7b55c96 100644 --- a/test/global.spec.ts +++ b/test/global.spec.ts @@ -121,6 +121,24 @@ describeForEachLuaTarget('global', (target) => { expect(lua).toMatchSnapshot(); }); + test('pairs with LuaTable', () => { + const lua = tstl( + target, + ` + const tbl = new LuaTable(); + tbl.set("foo", "bar"); + tbl.set("baz", "bur"); + const takesStr = (str: string) => {}; + for (const [k, v] of pairs(tbl)) { + takesStr(k); + takesStr(v); + } + ` + ); + + expect(lua).toMatchSnapshot(); + }); + test('pcall', () => { const lua = tstl( target, From c9269dddb1a784424ed9618ef4ccfb7e281a523a Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 08:15:42 -0600 Subject: [PATCH 05/11] added missing string.rep function --- core/string.d.ts | 5 +++++ test/__snapshots__/string.spec.ts.snap | 10 ++++++++++ test/string.spec.ts | 11 +++++++++++ 3 files changed, 26 insertions(+) diff --git a/core/string.d.ts b/core/string.d.ts index 5310dad..0a10e5d 100644 --- a/core/string.d.ts +++ b/core/string.d.ts @@ -179,6 +179,11 @@ declare namespace string { */ function match(s: string, pattern: string, init?: number): LuaMultiReturn; + /** + * Returns a string that is the concatenation of `n` copies of the string `s`. + */ + function rep(s: string, n: number): string; + /** * Returns a string that is the string s reversed. */ diff --git a/test/__snapshots__/string.spec.ts.snap b/test/__snapshots__/string.spec.ts.snap index 8b0631e..38517fc 100644 --- a/test/__snapshots__/string.spec.ts.snap +++ b/test/__snapshots__/string.spec.ts.snap @@ -70,6 +70,8 @@ exports[`Lua version 5.1 / string string.match 1`] = ` exports[`Lua version 5.1 / string string.match destructured 1`] = `"match1, match2 = string.match(\\"hello world\\", \\"l\\")"`; +exports[`Lua version 5.1 / string string.rep 1`] = `"str = string.rep(\\"foo\\", 3)"`; + exports[`Lua version 5.2 / string string.byte 1`] = `"b = string.byte(\\"d\\")"`; exports[`Lua version 5.2 / string string.byte multiple 1`] = `"a, b, c, d = string.byte(\\"abcd\\", 1, 4)"`; @@ -140,6 +142,8 @@ exports[`Lua version 5.2 / string string.match 1`] = ` exports[`Lua version 5.2 / string string.match destructured 1`] = `"match1, match2 = string.match(\\"hello world\\", \\"l\\")"`; +exports[`Lua version 5.2 / string string.rep 1`] = `"str = string.rep(\\"foo\\", 3)"`; + exports[`Lua version 5.3 / string string.byte 1`] = `"b = string.byte(\\"d\\")"`; exports[`Lua version 5.3 / string string.byte multiple 1`] = `"a, b, c, d = string.byte(\\"abcd\\", 1, 4)"`; @@ -210,6 +214,8 @@ exports[`Lua version 5.3 / string string.match 1`] = ` exports[`Lua version 5.3 / string string.match destructured 1`] = `"match1, match2 = string.match(\\"hello world\\", \\"l\\")"`; +exports[`Lua version 5.3 / string string.rep 1`] = `"str = string.rep(\\"foo\\", 3)"`; + exports[`Lua version 5.4 / string string.byte 1`] = `"b = string.byte(\\"d\\")"`; exports[`Lua version 5.4 / string string.byte multiple 1`] = `"a, b, c, d = string.byte(\\"abcd\\", 1, 4)"`; @@ -280,6 +286,8 @@ exports[`Lua version 5.4 / string string.match 1`] = ` exports[`Lua version 5.4 / string string.match destructured 1`] = `"match1, match2 = string.match(\\"hello world\\", \\"l\\")"`; +exports[`Lua version 5.4 / string string.rep 1`] = `"str = string.rep(\\"foo\\", 3)"`; + exports[`Lua version JIT / string string.byte 1`] = `"b = string.byte(\\"d\\")"`; exports[`Lua version JIT / string string.byte multiple 1`] = `"a, b, c, d = string.byte(\\"abcd\\", 1, 4)"`; @@ -349,3 +357,5 @@ exports[`Lua version JIT / string string.match 1`] = ` `; exports[`Lua version JIT / string string.match destructured 1`] = `"match1, match2 = string.match(\\"hello world\\", \\"l\\")"`; + +exports[`Lua version JIT / string string.rep 1`] = `"str = string.rep(\\"foo\\", 3)"`; diff --git a/test/string.spec.ts b/test/string.spec.ts index 5854b71..e02341a 100644 --- a/test/string.spec.ts +++ b/test/string.spec.ts @@ -182,4 +182,15 @@ describeForEachLuaTarget('string', (target) => { expect(lua).toMatchSnapshot(); }); + + test('string.rep', () => { + const lua = tstl( + target, + ` + const str = string.rep("foo", 3); + ` + ); + + expect(lua).toMatchSnapshot(); + }); }); From 93f3366f9f7b6a42174ad543ff8e311881277540 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Apr 2021 09:09:21 -0600 Subject: [PATCH 06/11] added tests for io and file --- test/__snapshots__/io.spec.ts.snap | 361 +++++++++++++++++++++++++++++ test/io.spec.ts | 333 ++++++++++++++++++++++++++ 2 files changed, 694 insertions(+) create mode 100644 test/__snapshots__/io.spec.ts.snap create mode 100644 test/io.spec.ts diff --git a/test/__snapshots__/io.spec.ts.snap b/test/__snapshots__/io.spec.ts.snap new file mode 100644 index 0000000..cdb83f3 --- /dev/null +++ b/test/__snapshots__/io.spec.ts.snap @@ -0,0 +1,361 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Lua version 5.1 / file close 1`] = `"file:close()"`; + +exports[`Lua version 5.1 / file flush 1`] = `"file:flush()"`; + +exports[`Lua version 5.1 / file lines 1`] = ` +"for line in file:lines() do + print(line) +end" +`; + +exports[`Lua version 5.1 / file read 1`] = `"foo = file:read()"`; + +exports[`Lua version 5.1 / file seek 1`] = `"pos, err = file:seek()"`; + +exports[`Lua version 5.1 / file seek offset 1`] = `"pos, err = file:seek(\\"cur\\", 1)"`; + +exports[`Lua version 5.1 / file seek whence 1`] = `"pos, err = file:seek(\\"cur\\")"`; + +exports[`Lua version 5.1 / file setvbuf 1`] = `"file:setvbuf(\\"no\\")"`; + +exports[`Lua version 5.1 / file setvbuf with size 1`] = `"file:setvbuf(\\"line\\", 10)"`; + +exports[`Lua version 5.1 / file write 1`] = `"f, err = file:write(\\"foo\\", \\"bar\\")"`; + +exports[`Lua version 5.1 / io close 1`] = `"io.close()"`; + +exports[`Lua version 5.1 / io close file 1`] = `"io.close(file)"`; + +exports[`Lua version 5.1 / io flush 1`] = `"io.flush()"`; + +exports[`Lua version 5.1 / io input 1`] = `"inp = io.input()"`; + +exports[`Lua version 5.1 / io input with file handle 1`] = `"inp = io.input(file)"`; + +exports[`Lua version 5.1 / io input with filename 1`] = `"inp = io.input(\\"foo.bar\\")"`; + +exports[`Lua version 5.1 / io lines 1`] = ` +"for line in io.lines() do + print(line) +end" +`; + +exports[`Lua version 5.1 / io lines with filename 1`] = ` +"for line in io.lines(\\"foo.bar\\") do + print(line) +end" +`; + +exports[`Lua version 5.1 / io open 1`] = `"f, err = io.open(\\"foo.bar\\")"`; + +exports[`Lua version 5.1 / io open with mode flag 1`] = `"f, err = io.open(\\"foo.bar\\", \\"r\\")"`; + +exports[`Lua version 5.1 / io output 1`] = `"inp = io.output()"`; + +exports[`Lua version 5.1 / io output with file handle 1`] = `"inp = io.output(file)"`; + +exports[`Lua version 5.1 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; + +exports[`Lua version 5.1 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; + +exports[`Lua version 5.1 / io read 1`] = `"foo = io:read()"`; + +exports[`Lua version 5.1 / io tmpfile 1`] = `"file = io.tmpfile()"`; + +exports[`Lua version 5.1 / io type 1`] = ` +"print( + io.type(file) +)" +`; + +exports[`Lua version 5.1 / io write 1`] = `"f, err = io.write(\\"foobar\\")"`; + +exports[`Lua version 5.2 / file close 1`] = `"file:close()"`; + +exports[`Lua version 5.2 / file flush 1`] = `"file:flush()"`; + +exports[`Lua version 5.2 / file lines 1`] = ` +"for line in file:lines() do + print(line) +end" +`; + +exports[`Lua version 5.2 / file read 1`] = `"foo = file:read()"`; + +exports[`Lua version 5.2 / file seek 1`] = `"pos, err = file:seek()"`; + +exports[`Lua version 5.2 / file seek offset 1`] = `"pos, err = file:seek(\\"cur\\", 1)"`; + +exports[`Lua version 5.2 / file seek whence 1`] = `"pos, err = file:seek(\\"cur\\")"`; + +exports[`Lua version 5.2 / file setvbuf 1`] = `"file:setvbuf(\\"no\\")"`; + +exports[`Lua version 5.2 / file setvbuf with size 1`] = `"file:setvbuf(\\"line\\", 10)"`; + +exports[`Lua version 5.2 / file write 1`] = `"f, err = file:write(\\"foo\\", \\"bar\\")"`; + +exports[`Lua version 5.2 / io close 1`] = `"io.close()"`; + +exports[`Lua version 5.2 / io close file 1`] = `"io.close(file)"`; + +exports[`Lua version 5.2 / io flush 1`] = `"io.flush()"`; + +exports[`Lua version 5.2 / io input 1`] = `"inp = io.input()"`; + +exports[`Lua version 5.2 / io input with file handle 1`] = `"inp = io.input(file)"`; + +exports[`Lua version 5.2 / io input with filename 1`] = `"inp = io.input(\\"foo.bar\\")"`; + +exports[`Lua version 5.2 / io lines 1`] = ` +"for line in io.lines() do + print(line) +end" +`; + +exports[`Lua version 5.2 / io lines with filename 1`] = ` +"for line in io.lines(\\"foo.bar\\") do + print(line) +end" +`; + +exports[`Lua version 5.2 / io open 1`] = `"f, err = io.open(\\"foo.bar\\")"`; + +exports[`Lua version 5.2 / io open with mode flag 1`] = `"f, err = io.open(\\"foo.bar\\", \\"r\\")"`; + +exports[`Lua version 5.2 / io output 1`] = `"inp = io.output()"`; + +exports[`Lua version 5.2 / io output with file handle 1`] = `"inp = io.output(file)"`; + +exports[`Lua version 5.2 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; + +exports[`Lua version 5.2 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; + +exports[`Lua version 5.2 / io read 1`] = `"foo = io:read()"`; + +exports[`Lua version 5.2 / io tmpfile 1`] = `"file = io.tmpfile()"`; + +exports[`Lua version 5.2 / io type 1`] = ` +"print( + io.type(file) +)" +`; + +exports[`Lua version 5.2 / io write 1`] = `"f, err = io.write(\\"foobar\\")"`; + +exports[`Lua version 5.3 / file close 1`] = `"file:close()"`; + +exports[`Lua version 5.3 / file flush 1`] = `"file:flush()"`; + +exports[`Lua version 5.3 / file lines 1`] = ` +"for line in file:lines() do + print(line) +end" +`; + +exports[`Lua version 5.3 / file read 1`] = `"foo = file:read()"`; + +exports[`Lua version 5.3 / file seek 1`] = `"pos, err = file:seek()"`; + +exports[`Lua version 5.3 / file seek offset 1`] = `"pos, err = file:seek(\\"cur\\", 1)"`; + +exports[`Lua version 5.3 / file seek whence 1`] = `"pos, err = file:seek(\\"cur\\")"`; + +exports[`Lua version 5.3 / file setvbuf 1`] = `"file:setvbuf(\\"no\\")"`; + +exports[`Lua version 5.3 / file setvbuf with size 1`] = `"file:setvbuf(\\"line\\", 10)"`; + +exports[`Lua version 5.3 / file write 1`] = `"f, err = file:write(\\"foo\\", \\"bar\\")"`; + +exports[`Lua version 5.3 / io close 1`] = `"io.close()"`; + +exports[`Lua version 5.3 / io close file 1`] = `"io.close(file)"`; + +exports[`Lua version 5.3 / io flush 1`] = `"io.flush()"`; + +exports[`Lua version 5.3 / io input 1`] = `"inp = io.input()"`; + +exports[`Lua version 5.3 / io input with file handle 1`] = `"inp = io.input(file)"`; + +exports[`Lua version 5.3 / io input with filename 1`] = `"inp = io.input(\\"foo.bar\\")"`; + +exports[`Lua version 5.3 / io lines 1`] = ` +"for line in io.lines() do + print(line) +end" +`; + +exports[`Lua version 5.3 / io lines with filename 1`] = ` +"for line in io.lines(\\"foo.bar\\") do + print(line) +end" +`; + +exports[`Lua version 5.3 / io open 1`] = `"f, err = io.open(\\"foo.bar\\")"`; + +exports[`Lua version 5.3 / io open with mode flag 1`] = `"f, err = io.open(\\"foo.bar\\", \\"r\\")"`; + +exports[`Lua version 5.3 / io output 1`] = `"inp = io.output()"`; + +exports[`Lua version 5.3 / io output with file handle 1`] = `"inp = io.output(file)"`; + +exports[`Lua version 5.3 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; + +exports[`Lua version 5.3 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; + +exports[`Lua version 5.3 / io read 1`] = `"foo = io:read()"`; + +exports[`Lua version 5.3 / io tmpfile 1`] = `"file = io.tmpfile()"`; + +exports[`Lua version 5.3 / io type 1`] = ` +"print( + io.type(file) +)" +`; + +exports[`Lua version 5.3 / io write 1`] = `"f, err = io.write(\\"foobar\\")"`; + +exports[`Lua version 5.4 / file close 1`] = `"file:close()"`; + +exports[`Lua version 5.4 / file flush 1`] = `"file:flush()"`; + +exports[`Lua version 5.4 / file lines 1`] = ` +"for line in file:lines() do + print(line) +end" +`; + +exports[`Lua version 5.4 / file read 1`] = `"foo = file:read()"`; + +exports[`Lua version 5.4 / file seek 1`] = `"pos, err = file:seek()"`; + +exports[`Lua version 5.4 / file seek offset 1`] = `"pos, err = file:seek(\\"cur\\", 1)"`; + +exports[`Lua version 5.4 / file seek whence 1`] = `"pos, err = file:seek(\\"cur\\")"`; + +exports[`Lua version 5.4 / file setvbuf 1`] = `"file:setvbuf(\\"no\\")"`; + +exports[`Lua version 5.4 / file setvbuf with size 1`] = `"file:setvbuf(\\"line\\", 10)"`; + +exports[`Lua version 5.4 / file write 1`] = `"f, err = file:write(\\"foo\\", \\"bar\\")"`; + +exports[`Lua version 5.4 / io close 1`] = `"io.close()"`; + +exports[`Lua version 5.4 / io close file 1`] = `"io.close(file)"`; + +exports[`Lua version 5.4 / io flush 1`] = `"io.flush()"`; + +exports[`Lua version 5.4 / io input 1`] = `"inp = io.input()"`; + +exports[`Lua version 5.4 / io input with file handle 1`] = `"inp = io.input(file)"`; + +exports[`Lua version 5.4 / io input with filename 1`] = `"inp = io.input(\\"foo.bar\\")"`; + +exports[`Lua version 5.4 / io lines 1`] = ` +"for line in io.lines() do + print(line) +end" +`; + +exports[`Lua version 5.4 / io lines with filename 1`] = ` +"for line in io.lines(\\"foo.bar\\") do + print(line) +end" +`; + +exports[`Lua version 5.4 / io open 1`] = `"f, err = io.open(\\"foo.bar\\")"`; + +exports[`Lua version 5.4 / io open with mode flag 1`] = `"f, err = io.open(\\"foo.bar\\", \\"r\\")"`; + +exports[`Lua version 5.4 / io output 1`] = `"inp = io.output()"`; + +exports[`Lua version 5.4 / io output with file handle 1`] = `"inp = io.output(file)"`; + +exports[`Lua version 5.4 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; + +exports[`Lua version 5.4 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; + +exports[`Lua version 5.4 / io read 1`] = `"foo = io:read()"`; + +exports[`Lua version 5.4 / io tmpfile 1`] = `"file = io.tmpfile()"`; + +exports[`Lua version 5.4 / io type 1`] = ` +"print( + io.type(file) +)" +`; + +exports[`Lua version 5.4 / io write 1`] = `"f, err = io.write(\\"foobar\\")"`; + +exports[`Lua version JIT / file close 1`] = `"file:close()"`; + +exports[`Lua version JIT / file flush 1`] = `"file:flush()"`; + +exports[`Lua version JIT / file lines 1`] = ` +"for line in file:lines() do + print(line) +end" +`; + +exports[`Lua version JIT / file read 1`] = `"foo = file:read()"`; + +exports[`Lua version JIT / file seek 1`] = `"pos, err = file:seek()"`; + +exports[`Lua version JIT / file seek offset 1`] = `"pos, err = file:seek(\\"cur\\", 1)"`; + +exports[`Lua version JIT / file seek whence 1`] = `"pos, err = file:seek(\\"cur\\")"`; + +exports[`Lua version JIT / file setvbuf 1`] = `"file:setvbuf(\\"no\\")"`; + +exports[`Lua version JIT / file setvbuf with size 1`] = `"file:setvbuf(\\"line\\", 10)"`; + +exports[`Lua version JIT / file write 1`] = `"f, err = file:write(\\"foo\\", \\"bar\\")"`; + +exports[`Lua version JIT / io close 1`] = `"io.close()"`; + +exports[`Lua version JIT / io close file 1`] = `"io.close(file)"`; + +exports[`Lua version JIT / io flush 1`] = `"io.flush()"`; + +exports[`Lua version JIT / io input 1`] = `"inp = io.input()"`; + +exports[`Lua version JIT / io input with file handle 1`] = `"inp = io.input(file)"`; + +exports[`Lua version JIT / io input with filename 1`] = `"inp = io.input(\\"foo.bar\\")"`; + +exports[`Lua version JIT / io lines 1`] = ` +"for line in io.lines() do + print(line) +end" +`; + +exports[`Lua version JIT / io lines with filename 1`] = ` +"for line in io.lines(\\"foo.bar\\") do + print(line) +end" +`; + +exports[`Lua version JIT / io open 1`] = `"f, err = io.open(\\"foo.bar\\")"`; + +exports[`Lua version JIT / io open with mode flag 1`] = `"f, err = io.open(\\"foo.bar\\", \\"r\\")"`; + +exports[`Lua version JIT / io output 1`] = `"inp = io.output()"`; + +exports[`Lua version JIT / io output with file handle 1`] = `"inp = io.output(file)"`; + +exports[`Lua version JIT / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; + +exports[`Lua version JIT / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; + +exports[`Lua version JIT / io read 1`] = `"foo = io:read()"`; + +exports[`Lua version JIT / io tmpfile 1`] = `"file = io.tmpfile()"`; + +exports[`Lua version JIT / io type 1`] = ` +"print( + io.type(file) +)" +`; + +exports[`Lua version JIT / io write 1`] = `"f, err = io.write(\\"foobar\\")"`; diff --git a/test/io.spec.ts b/test/io.spec.ts new file mode 100644 index 0000000..0e33d87 --- /dev/null +++ b/test/io.spec.ts @@ -0,0 +1,333 @@ +import { describeForEachLuaTarget, tstl } from './test-utils'; + +describeForEachLuaTarget('io', (target) => { + test('close', () => { + const lua = tstl( + target, + ` + io.close(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('close file', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + io.close(file); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('flush', () => { + const lua = tstl( + target, + ` + io.flush(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('input', () => { + const lua = tstl( + target, + ` + const inp = io.input(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('input with filename', () => { + const lua = tstl( + target, + ` + const inp = io.input("foo.bar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('input with file handle', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const inp = io.input(file); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('lines', () => { + const lua = tstl( + target, + ` + for (const [line] of io.lines()) { + print(line); + } + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('lines with filename', () => { + const lua = tstl( + target, + ` + for (const [line] of io.lines("foo.bar")) { + print(line); + } + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('open', () => { + const lua = tstl( + target, + ` + const [f, err] = io.open("foo.bar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('open with mode flag', () => { + const lua = tstl( + target, + ` + const [f, err] = io.open("foo.bar", "r"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('output', () => { + const lua = tstl( + target, + ` + const inp = io.output(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('output with filename', () => { + const lua = tstl( + target, + ` + const inp = io.output("foo.bar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('output with file handle', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const inp = io.output(file); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('popen', () => { + const lua = tstl( + target, + ` + const proc = io.popen("echo foobar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read', () => { + const lua = tstl( + target, + ` + const [foo] = io.read(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('tmpfile', () => { + const lua = tstl( + target, + ` + const file = io.tmpfile(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('type', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + print(io.type(file)); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('write', () => { + const lua = tstl( + target, + ` + const [f, err] = io.write("foobar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); +}); + +describeForEachLuaTarget('file', (target) => { + test('close', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + file.close(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('flush', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + file.flush(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('lines', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + for (const [line] of file.lines()) { + print(line); + } + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [foo] = file.read(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('seek', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [pos, err] = file.seek(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('seek whence', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [pos, err] = file.seek("cur"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('seek offset', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [pos, err] = file.seek("cur", 1); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('setvbuf', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + file.setvbuf("no"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('setvbuf with size', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + file.setvbuf("line", 10); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('write', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [f, err] = file.write("foo", "bar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); +}); From 38dacce905a4c94c8f8fa51ba49394d77ca6f4bc Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 4 Apr 2021 06:05:29 -0600 Subject: [PATCH 07/11] fixed popen return values --- core/io.d.ts | 2 +- test/__snapshots__/io.spec.ts.snap | 10 +++++----- test/io.spec.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/io.d.ts b/core/io.d.ts index 9edabba..8993b98 100644 --- a/core/io.d.ts +++ b/core/io.d.ts @@ -100,7 +100,7 @@ declare namespace io { * you can use to read data from this program (if mode is "r", the default) or * to write data to this program (if mode is "w"). */ - function popen(prog: string, mode?: 'r' | 'w'): LuaFile; + function popen(prog: string, mode?: 'r' | 'w'): LuaMultiReturn<[LuaFile] | [undefined, string]>; /** * Equivalent to io.input():read(···). diff --git a/test/__snapshots__/io.spec.ts.snap b/test/__snapshots__/io.spec.ts.snap index cdb83f3..2d8565d 100644 --- a/test/__snapshots__/io.spec.ts.snap +++ b/test/__snapshots__/io.spec.ts.snap @@ -58,7 +58,7 @@ exports[`Lua version 5.1 / io output with file handle 1`] = `"inp = io.output(fi exports[`Lua version 5.1 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; -exports[`Lua version 5.1 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; +exports[`Lua version 5.1 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; exports[`Lua version 5.1 / io read 1`] = `"foo = io:read()"`; @@ -130,7 +130,7 @@ exports[`Lua version 5.2 / io output with file handle 1`] = `"inp = io.output(fi exports[`Lua version 5.2 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; -exports[`Lua version 5.2 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; +exports[`Lua version 5.2 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; exports[`Lua version 5.2 / io read 1`] = `"foo = io:read()"`; @@ -202,7 +202,7 @@ exports[`Lua version 5.3 / io output with file handle 1`] = `"inp = io.output(fi exports[`Lua version 5.3 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; -exports[`Lua version 5.3 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; +exports[`Lua version 5.3 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; exports[`Lua version 5.3 / io read 1`] = `"foo = io:read()"`; @@ -274,7 +274,7 @@ exports[`Lua version 5.4 / io output with file handle 1`] = `"inp = io.output(fi exports[`Lua version 5.4 / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; -exports[`Lua version 5.4 / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; +exports[`Lua version 5.4 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; exports[`Lua version 5.4 / io read 1`] = `"foo = io:read()"`; @@ -346,7 +346,7 @@ exports[`Lua version JIT / io output with file handle 1`] = `"inp = io.output(fi exports[`Lua version JIT / io output with filename 1`] = `"inp = io.output(\\"foo.bar\\")"`; -exports[`Lua version JIT / io popen 1`] = `"proc = io.popen(\\"echo foobar\\")"`; +exports[`Lua version JIT / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; exports[`Lua version JIT / io read 1`] = `"foo = io:read()"`; diff --git a/test/io.spec.ts b/test/io.spec.ts index 0e33d87..fa0806d 100644 --- a/test/io.spec.ts +++ b/test/io.spec.ts @@ -155,7 +155,7 @@ describeForEachLuaTarget('io', (target) => { const lua = tstl( target, ` - const proc = io.popen("echo foobar"); + const [proc, err] = io.popen("echo foobar"); ` ); From 2414c7f8f37a60b5813bf4b418c256a7004d6972 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 4 Apr 2021 07:13:28 -0600 Subject: [PATCH 08/11] fixes to io read functions --- core/io.d.ts | 24 +++-- special/5.1-only.d.ts | 6 +- special/5.2-or-jit.d.ts | 6 +- special/5.3-plus.d.ts | 6 +- test/__snapshots__/io.spec.ts.snap | 160 +++++++++++++++++++++++++++-- test/io.spec.ts | 111 +++++++++++++++++--- 6 files changed, 280 insertions(+), 33 deletions(-) diff --git a/core/io.d.ts b/core/io.d.ts index 8993b98..4587416 100644 --- a/core/io.d.ts +++ b/core/io.d.ts @@ -100,12 +100,18 @@ declare namespace io { * you can use to read data from this program (if mode is "r", the default) or * to write data to this program (if mode is "w"). */ - function popen(prog: string, mode?: 'r' | 'w'): LuaMultiReturn<[LuaFile] | [undefined, string]>; + function popen(prog: string, mode?: 'r' | 'w'): LuaMultiReturn<[LuaFile] | [undefined, string]>; /** * Equivalent to io.input():read(···). */ - const read: LuaFile['read']; + function read( + ...formats: T + ): T extends { length: 0 } + ? io.FileReadFormatToType + : T extends { length: 1 } + ? io.FileReadFormatToType + : LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; /** * In case of success, returns a handle for a temporary file. This file is @@ -125,6 +131,8 @@ declare namespace io { * Equivalent to io.output():write(···). */ function write(...args: (string | number)[]): LuaMultiReturn<[LuaFile] | [undefined, string]>; + + type FileReadFormatToType = (T extends FileReadNumberFormat ? number : string) | undefined; } interface LuaFile { @@ -160,9 +168,7 @@ interface LuaFile { lines( ...formats: T ): LuaIterable< - LuaMultiReturn< - [] extends T ? [string] : { [P in keyof T]: T[P] extends 'n' ? number : string } - > + LuaMultiReturn<[] extends T ? [string] : { [P in keyof T]: io.FileReadFormatToType }> >; /** @@ -193,9 +199,13 @@ interface LuaFile { * * The formats "l" and "L" should be used only for text files. */ - read( + read( ...formats: T - ): LuaMultiReturn<{ [P in keyof T]?: T[P] extends 'n' ? number : string }>; + ): T extends { length: 0 } + ? io.FileReadFormatToType + : T extends { length: 1 } + ? io.FileReadFormatToType + : LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; /** * Sets and geionts the file position, measured from the beginning of the diff --git a/special/5.1-only.d.ts b/special/5.1-only.d.ts index ef13f0f..aeeadce 100644 --- a/special/5.1-only.d.ts +++ b/special/5.1-only.d.ts @@ -96,4 +96,8 @@ declare namespace debug { ): LuaMultiReturn<[string, any]>; } -type FileReadFormat = '*n' | '*a' | '*l' | number; +declare namespace io { + type FileReadNumberFormat = '*n'; + type FileReadLineFormat = '*l'; + type FileReadFormat = FileReadNumberFormat | FileReadLineFormat | '*a' | number; +} diff --git a/special/5.2-or-jit.d.ts b/special/5.2-or-jit.d.ts index c2c8b88..5d3e3b8 100644 --- a/special/5.2-or-jit.d.ts +++ b/special/5.2-or-jit.d.ts @@ -1 +1,5 @@ -type FileReadFormat = '*n' | '*a' | '*l' | '*L' | number; +declare namespace io { + type FileReadNumberFormat = '*n'; + type FileReadLineFormat = '*l'; + type FileReadFormat = FileReadNumberFormat | FileReadLineFormat | '*a' | '*L' | number; +} diff --git a/special/5.3-plus.d.ts b/special/5.3-plus.d.ts index aec91af..802a43b 100644 --- a/special/5.3-plus.d.ts +++ b/special/5.3-plus.d.ts @@ -227,4 +227,8 @@ interface LuaMetatable { __shr?(this: T, operand: any): any; } -type FileReadFormat = 'n' | 'a' | 'l' | 'L' | number; +declare namespace io { + type FileReadNumberFormat = 'n'; + type FileReadLineFormat = 'l'; + type FileReadFormat = FileReadNumberFormat | FileReadLineFormat | 'a' | 'L' | number; +} diff --git a/test/__snapshots__/io.spec.ts.snap b/test/__snapshots__/io.spec.ts.snap index 2d8565d..6d4e302 100644 --- a/test/__snapshots__/io.spec.ts.snap +++ b/test/__snapshots__/io.spec.ts.snap @@ -10,7 +10,21 @@ exports[`Lua version 5.1 / file lines 1`] = ` end" `; -exports[`Lua version 5.1 / file read 1`] = `"foo = file:read()"`; +exports[`Lua version 5.1 / file read multi 1`] = ` +"foo, bar = file:read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.1 / file read one 1`] = ` +"foo = file:read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.1 / file read zero 1`] = ` +"foo = file:read() +takesString(_G, foo)" +`; exports[`Lua version 5.1 / file seek 1`] = `"pos, err = file:seek()"`; @@ -60,7 +74,21 @@ exports[`Lua version 5.1 / io output with filename 1`] = `"inp = io.output(\\"fo exports[`Lua version 5.1 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; -exports[`Lua version 5.1 / io read 1`] = `"foo = io:read()"`; +exports[`Lua version 5.1 / io read multi 1`] = ` +"foo, bar = io.read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.1 / io read one 1`] = ` +"foo = io.read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.1 / io read zero 1`] = ` +"foo = io.read() +takesString(_G, foo)" +`; exports[`Lua version 5.1 / io tmpfile 1`] = `"file = io.tmpfile()"`; @@ -82,7 +110,21 @@ exports[`Lua version 5.2 / file lines 1`] = ` end" `; -exports[`Lua version 5.2 / file read 1`] = `"foo = file:read()"`; +exports[`Lua version 5.2 / file read multi 1`] = ` +"foo, bar = file:read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.2 / file read one 1`] = ` +"foo = file:read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.2 / file read zero 1`] = ` +"foo = file:read() +takesString(_G, foo)" +`; exports[`Lua version 5.2 / file seek 1`] = `"pos, err = file:seek()"`; @@ -132,7 +174,21 @@ exports[`Lua version 5.2 / io output with filename 1`] = `"inp = io.output(\\"fo exports[`Lua version 5.2 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; -exports[`Lua version 5.2 / io read 1`] = `"foo = io:read()"`; +exports[`Lua version 5.2 / io read multi 1`] = ` +"foo, bar = io.read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.2 / io read one 1`] = ` +"foo = io.read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.2 / io read zero 1`] = ` +"foo = io.read() +takesString(_G, foo)" +`; exports[`Lua version 5.2 / io tmpfile 1`] = `"file = io.tmpfile()"`; @@ -154,7 +210,21 @@ exports[`Lua version 5.3 / file lines 1`] = ` end" `; -exports[`Lua version 5.3 / file read 1`] = `"foo = file:read()"`; +exports[`Lua version 5.3 / file read multi 1`] = ` +"foo, bar = file:read(\\"l\\", \\"n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.3 / file read one 1`] = ` +"foo = file:read(\\"l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.3 / file read zero 1`] = ` +"foo = file:read() +takesString(_G, foo)" +`; exports[`Lua version 5.3 / file seek 1`] = `"pos, err = file:seek()"`; @@ -204,7 +274,21 @@ exports[`Lua version 5.3 / io output with filename 1`] = `"inp = io.output(\\"fo exports[`Lua version 5.3 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; -exports[`Lua version 5.3 / io read 1`] = `"foo = io:read()"`; +exports[`Lua version 5.3 / io read multi 1`] = ` +"foo, bar = io.read(\\"l\\", \\"n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.3 / io read one 1`] = ` +"foo = io.read(\\"l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.3 / io read zero 1`] = ` +"foo = io.read() +takesString(_G, foo)" +`; exports[`Lua version 5.3 / io tmpfile 1`] = `"file = io.tmpfile()"`; @@ -226,7 +310,21 @@ exports[`Lua version 5.4 / file lines 1`] = ` end" `; -exports[`Lua version 5.4 / file read 1`] = `"foo = file:read()"`; +exports[`Lua version 5.4 / file read multi 1`] = ` +"foo, bar = file:read(\\"l\\", \\"n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.4 / file read one 1`] = ` +"foo = file:read(\\"l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.4 / file read zero 1`] = ` +"foo = file:read() +takesString(_G, foo)" +`; exports[`Lua version 5.4 / file seek 1`] = `"pos, err = file:seek()"`; @@ -276,7 +374,21 @@ exports[`Lua version 5.4 / io output with filename 1`] = `"inp = io.output(\\"fo exports[`Lua version 5.4 / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; -exports[`Lua version 5.4 / io read 1`] = `"foo = io:read()"`; +exports[`Lua version 5.4 / io read multi 1`] = ` +"foo, bar = io.read(\\"l\\", \\"n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version 5.4 / io read one 1`] = ` +"foo = io.read(\\"l\\") +takesString(_G, foo)" +`; + +exports[`Lua version 5.4 / io read zero 1`] = ` +"foo = io.read() +takesString(_G, foo)" +`; exports[`Lua version 5.4 / io tmpfile 1`] = `"file = io.tmpfile()"`; @@ -298,7 +410,21 @@ exports[`Lua version JIT / file lines 1`] = ` end" `; -exports[`Lua version JIT / file read 1`] = `"foo = file:read()"`; +exports[`Lua version JIT / file read multi 1`] = ` +"foo, bar = file:read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version JIT / file read one 1`] = ` +"foo = file:read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version JIT / file read zero 1`] = ` +"foo = file:read() +takesString(_G, foo)" +`; exports[`Lua version JIT / file seek 1`] = `"pos, err = file:seek()"`; @@ -348,7 +474,21 @@ exports[`Lua version JIT / io output with filename 1`] = `"inp = io.output(\\"fo exports[`Lua version JIT / io popen 1`] = `"proc, err = io.popen(\\"echo foobar\\")"`; -exports[`Lua version JIT / io read 1`] = `"foo = io:read()"`; +exports[`Lua version JIT / io read multi 1`] = ` +"foo, bar = io.read(\\"*l\\", \\"*n\\") +takesString(_G, foo) +takesNumber(_G, bar)" +`; + +exports[`Lua version JIT / io read one 1`] = ` +"foo = io.read(\\"*l\\") +takesString(_G, foo)" +`; + +exports[`Lua version JIT / io read zero 1`] = ` +"foo = io.read() +takesString(_G, foo)" +`; exports[`Lua version JIT / io tmpfile 1`] = `"file = io.tmpfile()"`; diff --git a/test/io.spec.ts b/test/io.spec.ts index fa0806d..5313824 100644 --- a/test/io.spec.ts +++ b/test/io.spec.ts @@ -1,3 +1,4 @@ +import { LuaTarget } from 'typescript-to-lua'; import { describeForEachLuaTarget, tstl } from './test-utils'; describeForEachLuaTarget('io', (target) => { @@ -162,11 +163,52 @@ describeForEachLuaTarget('io', (target) => { expect(lua).toMatchSnapshot(); }); - test('read', () => { + test('read zero', () => { const lua = tstl( target, ` - const [foo] = io.read(); + const foo = io.read(); + declare function takesString(str: string): void; + takesString(foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read one', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` + const foo = io.read("${lineFormat}"); + declare function takesString(str: string): void; + takesString(foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read multi', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const numberFormat = useOldFormat ? '*n' : 'n'; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` + const [foo, bar] = io.read("${lineFormat}", "${numberFormat}"); + declare function takesString(str: string): void; + declare function takesNumber(num: number): void; + takesString(foo); + takesNumber(bar); ` ); @@ -247,17 +289,60 @@ describeForEachLuaTarget('file', (target) => { expect(lua).toMatchSnapshot(); }); - test('read', () => { - const lua = tstl( - target, - ` - declare const file: LuaFile; - const [foo] = file.read(); - ` - ); - - expect(lua).toMatchSnapshot(); - }); + test('read zero', () => { + const lua = tstl( + target, + ` + declare const file: LuaFile; + const foo = file.read(); + declare function takesString(str: string): void; + takesString(foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read one', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` + declare const file: LuaFile; + const foo = file.read("${lineFormat}"); + declare function takesString(str: string): void; + takesString(foo); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read multi', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const numberFormat = useOldFormat ? '*n' : 'n'; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` + declare const file: LuaFile; + const [foo, bar] = file.read("${lineFormat}", "${numberFormat}"); + declare function takesString(str: string): void; + declare function takesNumber(num: number): void; + takesString(foo); + takesNumber(bar); + ` + ); + + expect(lua).toMatchSnapshot(); + }); test('seek', () => { const lua = tstl( From f993ae5c53b5564fef6cac08001e5338cb28280e Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 4 Apr 2021 08:48:21 -0600 Subject: [PATCH 09/11] improved declarations for io read --- core/io.d.ts | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/core/io.d.ts b/core/io.d.ts index 4587416..28583fd 100644 --- a/core/io.d.ts +++ b/core/io.d.ts @@ -61,9 +61,7 @@ declare namespace io { filename?: string, ...formats: T ): LuaIterable< - LuaMultiReturn< - [] extends T ? [string] : { [P in keyof T]: T[P] extends 'n' ? number : string } - > + LuaMultiReturn<[] extends T ? [string] : { [P in keyof T]: FileReadFormatToType }> >; /** @@ -105,13 +103,11 @@ declare namespace io { /** * Equivalent to io.input():read(···). */ + function read(): io.FileReadFormatToType | undefined; + function read(format: T): io.FileReadFormatToType | undefined; function read( ...formats: T - ): T extends { length: 0 } - ? io.FileReadFormatToType - : T extends { length: 1 } - ? io.FileReadFormatToType - : LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; + ): LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; /** * In case of success, returns a handle for a temporary file. This file is @@ -132,7 +128,7 @@ declare namespace io { */ function write(...args: (string | number)[]): LuaMultiReturn<[LuaFile] | [undefined, string]>; - type FileReadFormatToType = (T extends FileReadNumberFormat ? number : string) | undefined; + type FileReadFormatToType = T extends FileReadNumberFormat ? number : string; } interface LuaFile { @@ -199,13 +195,11 @@ interface LuaFile { * * The formats "l" and "L" should be used only for text files. */ + read(): io.FileReadFormatToType | undefined; + read(format: T): io.FileReadFormatToType | undefined; read( ...formats: T - ): T extends { length: 0 } - ? io.FileReadFormatToType - : T extends { length: 1 } - ? io.FileReadFormatToType - : LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; + ): LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; /** * Sets and geionts the file position, measured from the beginning of the From b550ca3312a57d9e36f9f06f17a1d00fbe6a5971 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 4 Apr 2021 08:57:23 -0600 Subject: [PATCH 10/11] added standard stream handles to io --- core/io.d.ts | 15 +++++ test/__snapshots__/io.spec.ts.snap | 30 +++++++++ test/io.spec.ts | 103 +++++++++++++++++++---------- 3 files changed, 113 insertions(+), 35 deletions(-) diff --git a/core/io.d.ts b/core/io.d.ts index 28583fd..60a6de1 100644 --- a/core/io.d.ts +++ b/core/io.d.ts @@ -109,6 +109,21 @@ declare namespace io { ...formats: T ): LuaMultiReturn<{ [P in keyof T]?: io.FileReadFormatToType }>; + /** + * Predefined file handle for standard error stream. The I/O library never closes this file. + */ + const stderr: LuaFile; + + /** + * Predefined file handle for standard input stream. The I/O library never closes this file. + */ + const stdin: LuaFile; + + /** + * Predefined file handle for standard output stream. The I/O library never closes this file. + */ + const stdout: LuaFile; + /** * In case of success, returns a handle for a temporary file. This file is * opened in update mode and it is automatically removed when the program diff --git a/test/__snapshots__/io.spec.ts.snap b/test/__snapshots__/io.spec.ts.snap index 6d4e302..e44aaf4 100644 --- a/test/__snapshots__/io.spec.ts.snap +++ b/test/__snapshots__/io.spec.ts.snap @@ -90,6 +90,12 @@ exports[`Lua version 5.1 / io read zero 1`] = ` takesString(_G, foo)" `; +exports[`Lua version 5.1 / io stderr 1`] = `"io.stderr:write(\\"foobar\\")"`; + +exports[`Lua version 5.1 / io stdin 1`] = `"input = io.stdin:read()"`; + +exports[`Lua version 5.1 / io stdout 1`] = `"io.stdout:write(\\"foobar\\")"`; + exports[`Lua version 5.1 / io tmpfile 1`] = `"file = io.tmpfile()"`; exports[`Lua version 5.1 / io type 1`] = ` @@ -190,6 +196,12 @@ exports[`Lua version 5.2 / io read zero 1`] = ` takesString(_G, foo)" `; +exports[`Lua version 5.2 / io stderr 1`] = `"io.stderr:write(\\"foobar\\")"`; + +exports[`Lua version 5.2 / io stdin 1`] = `"input = io.stdin:read()"`; + +exports[`Lua version 5.2 / io stdout 1`] = `"io.stdout:write(\\"foobar\\")"`; + exports[`Lua version 5.2 / io tmpfile 1`] = `"file = io.tmpfile()"`; exports[`Lua version 5.2 / io type 1`] = ` @@ -290,6 +302,12 @@ exports[`Lua version 5.3 / io read zero 1`] = ` takesString(_G, foo)" `; +exports[`Lua version 5.3 / io stderr 1`] = `"io.stderr:write(\\"foobar\\")"`; + +exports[`Lua version 5.3 / io stdin 1`] = `"input = io.stdin:read()"`; + +exports[`Lua version 5.3 / io stdout 1`] = `"io.stdout:write(\\"foobar\\")"`; + exports[`Lua version 5.3 / io tmpfile 1`] = `"file = io.tmpfile()"`; exports[`Lua version 5.3 / io type 1`] = ` @@ -390,6 +408,12 @@ exports[`Lua version 5.4 / io read zero 1`] = ` takesString(_G, foo)" `; +exports[`Lua version 5.4 / io stderr 1`] = `"io.stderr:write(\\"foobar\\")"`; + +exports[`Lua version 5.4 / io stdin 1`] = `"input = io.stdin:read()"`; + +exports[`Lua version 5.4 / io stdout 1`] = `"io.stdout:write(\\"foobar\\")"`; + exports[`Lua version 5.4 / io tmpfile 1`] = `"file = io.tmpfile()"`; exports[`Lua version 5.4 / io type 1`] = ` @@ -490,6 +514,12 @@ exports[`Lua version JIT / io read zero 1`] = ` takesString(_G, foo)" `; +exports[`Lua version JIT / io stderr 1`] = `"io.stderr:write(\\"foobar\\")"`; + +exports[`Lua version JIT / io stdin 1`] = `"input = io.stdin:read()"`; + +exports[`Lua version JIT / io stdout 1`] = `"io.stdout:write(\\"foobar\\")"`; + exports[`Lua version JIT / io tmpfile 1`] = `"file = io.tmpfile()"`; exports[`Lua version JIT / io type 1`] = ` diff --git a/test/io.spec.ts b/test/io.spec.ts index 5313824..be52338 100644 --- a/test/io.spec.ts +++ b/test/io.spec.ts @@ -215,6 +215,39 @@ describeForEachLuaTarget('io', (target) => { expect(lua).toMatchSnapshot(); }); + test('stderr', () => { + const lua = tstl( + target, + ` + io.stderr.write("foobar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('stdin', () => { + const lua = tstl( + target, + ` + const input = io.stdin.read(); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('stdout', () => { + const lua = tstl( + target, + ` + io.stdout.write("foobar"); + ` + ); + + expect(lua).toMatchSnapshot(); + }); + test('tmpfile', () => { const lua = tstl( target, @@ -290,48 +323,48 @@ describeForEachLuaTarget('file', (target) => { }); test('read zero', () => { - const lua = tstl( - target, - ` + const lua = tstl( + target, + ` declare const file: LuaFile; const foo = file.read(); declare function takesString(str: string): void; takesString(foo); ` - ); - - expect(lua).toMatchSnapshot(); - }); - - test('read one', () => { - const useOldFormat = - [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( - target - ) >= 0; - const lineFormat = useOldFormat ? '*l' : 'l'; - const lua = tstl( - target, - ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read one', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` declare const file: LuaFile; const foo = file.read("${lineFormat}"); declare function takesString(str: string): void; takesString(foo); ` - ); - - expect(lua).toMatchSnapshot(); - }); - - test('read multi', () => { - const useOldFormat = - [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( - target - ) >= 0; - const numberFormat = useOldFormat ? '*n' : 'n'; - const lineFormat = useOldFormat ? '*l' : 'l'; - const lua = tstl( - target, - ` + ); + + expect(lua).toMatchSnapshot(); + }); + + test('read multi', () => { + const useOldFormat = + [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal].indexOf( + target + ) >= 0; + const numberFormat = useOldFormat ? '*n' : 'n'; + const lineFormat = useOldFormat ? '*l' : 'l'; + const lua = tstl( + target, + ` declare const file: LuaFile; const [foo, bar] = file.read("${lineFormat}", "${numberFormat}"); declare function takesString(str: string): void; @@ -339,10 +372,10 @@ describeForEachLuaTarget('file', (target) => { takesString(foo); takesNumber(bar); ` - ); + ); - expect(lua).toMatchSnapshot(); - }); + expect(lua).toMatchSnapshot(); + }); test('seek', () => { const lua = tstl( From 3835852ee02d1c5d054ba0fcef590e0ba421d633 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 5 Apr 2021 05:51:08 -0600 Subject: [PATCH 11/11] fixed mistake in file.lines --- core/io.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/io.d.ts b/core/io.d.ts index 60a6de1..9c35097 100644 --- a/core/io.d.ts +++ b/core/io.d.ts @@ -176,7 +176,7 @@ interface LuaFile { * In case of errors this function raises the error, instead of returning an * error code. */ - lines( + lines( ...formats: T ): LuaIterable< LuaMultiReturn<[] extends T ? [string] : { [P in keyof T]: io.FileReadFormatToType }>