use luaify::luaify; use pretty_assertions::assert_eq; #[test] fn raw_ident() { assert_eq!(luaify!(r#ref), r#"ref"#); assert_eq!(luaify!(x.r#ref), r#"x.ref"#); assert_eq!(luaify!(r#mut::r#ref), r#"mut.ref"#); assert_eq!(luaify!(x.r#ref()), r#"x:ref()"#); assert_eq!(luaify!(r#mut.r#ref()), r#"mut:ref()"#); assert_eq!(luaify!(r#mut::r#ref()), r#"mut.ref()"#); } #[test] fn escape() { assert_eq!(luaify!("\nmy\tstring\x00a"), r#""\nmy\tstring\x00a""#); assert_eq!(luaify!(r#" "raw string" "#), r#"" \"raw string\" ""#); } #[test] fn indexing() { assert_eq!(luaify!(table.0), r#"table[0]"#); assert_eq!(luaify!(table[0]), r#"table[0]"#); assert_eq!(luaify!(table["0"]), r#"table["0"]"#); assert_eq!(luaify!(table.field), r#"table.field"#); assert_eq!(luaify!(table.field.nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field.nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field::nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field["nested"]), r#"table.field["nested"]"#); assert_eq!(luaify!(table.0.nested), r#"table[0].nested"#); assert_eq!(luaify!(table.0["nested"]), r#"table[0]["nested"]"#); assert_eq!(luaify!(table[0].nested), r#"table[0].nested"#); assert_eq!(luaify!(table[0]["nested"]), r#"table[0]["nested"]"#); assert_eq!(luaify!(table["field"].nested), r#"table["field"].nested"#); assert_eq!(luaify!(table[field]), r#"table[field]"#); assert_eq!(luaify!(table[x.y]), r#"table[x.y]"#); assert_eq!(luaify!(table[x.1.y.2]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x.1.y[2]]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x[1].y.2]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x[1].y[2]]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!((x.y)[z.w]), r#"(x.y)[z.w]"#); assert_eq!(luaify!((x[y])[z.w]), r#"(x[y])[z.w]"#); assert_eq!(luaify!((x["y"])[z.w]), r#"(x["y"])[z.w]"#); } #[test] fn locals() { assert_eq!( luaify!(|| { let x = 30; }), r#"function()local x=30;end"# ); assert_eq!( luaify!(|| { let (x, y, z) = (1, 2, 3); }), r#"function()local x,y,z=1,2,3;end"# ); assert_eq!( luaify!(|| { let (a, b, c) = (1, call(), call2(), 4); return (a, b, c); }), r#"function()local a,b,c=1,call(),call2(),4;return a,b,c;end"# ); } #[test] fn local_fn() { assert_eq!( luaify!(|a, b| { fn inner(c: _, d: _) {} inner }), r#"function(a,b)local function inner(c,d)end;return inner;end"# ); assert_eq!( luaify!(|| { fn check(self: string, arg: number) {} inner }), r#"function()local function check(self,arg)do if type(self)=="number"then self=tostring(self);else assert(type(self)=="string","string expected in \'self\', got "..type(self));end;end;do local __arg=arg;arg=tonumber(arg);assert(arg~=nil,"number expected in \'arg\', got "..type(__arg));end;end;return inner;end"# ); } #[test] fn call() { assert_eq!(luaify!(table.field()), r#"table:field()"#); assert_eq!(luaify!(table::field()), r#"table.field()"#); assert_eq!(luaify!(table[field]()), r#"table[field]()"#); assert_eq!(luaify!(a::b.c.field()), r#"a.b.c:field()"#); assert_eq!(luaify!(a::b::c.field()), r#"a.b.c:field()"#); assert_eq!(luaify!(a::b::c::field()), r#"a.b.c.field()"#); assert_eq!( luaify!(coroutine::r#yield("string")), r#"coroutine.yield("string")"# ); assert_eq!(luaify!(call(a(), (b)(), c.d())), r#"call(a(),(b)(),c:d())"#); } #[test] fn closure() { assert_eq!(luaify!(|| hello), r#"function()return hello;end"#); assert_eq!(luaify!(|| { hello }), r#"function()return hello;end"#); assert_eq!( luaify!(|| { return hello; }), r#"function()return hello;end"# ); assert_eq!( luaify!(|| { { hello } }), r#"function()do return hello;end;end"# ); assert_eq!( luaify!(|a, b| |c, d| hello), r#"function(a,b)return function(c,d)return hello;end;end"# ); } #[test] fn labels() { assert_eq!( luaify!(|| { 'label: { break 'label; a(); b() } }), r#"function()do goto label_brk;a();return b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { 'label: { continue 'label; a(); b() } }), r#"function()do goto label_cnt;a();return b();::label_cnt::end::label_brk::;end"# ); } #[test] fn loops() { assert_eq!( luaify!(|| { loop { break; } }), r#"function()while true do break;end;end"# ); assert_eq!( luaify!(|| { 'label: loop { break; break 'label; continue 'label; a(); b() } }), r#"function()while true do break;goto label_brk;goto label_cnt;a();b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { while cond {} }), r#"function()while cond do end;end"# ); assert_eq!( luaify!(|| { 'label: while cond { continue 'label; break 'label; a(); b() } }), r#"function()while cond do goto label_cnt;goto label_brk;a();b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { for (k, v) in pairs(table) { print(k, v); a(); b() } }), r#"function()for k,v in pairs(table)do print(k,v);a();b();end;end"# ); assert_eq!( luaify!(|| { for i in 0..=5 { print(i) } for i in ..10 { print(i) } }), r#"function()for i=0,5 do print(i);end;for i=0,10-1 do print(i);end;end"# ); } #[test] fn type_checks() { assert_eq!(luaify!(|s| {}), r#"function(s)end"#); assert_eq!( luaify!(|s: table| {}), r#"function(s)do assert(type(s)=="table","table expected in \'s\', got "..type(s));end;end"# ); assert_eq!( luaify!(|s| { s as string }), r#"function(s)do if type(s)=="number"then s=tostring(s);else assert(type(s)=="string","string expected in \'s\', got "..type(s));end;end;end"# ); assert_eq!( luaify!(|s| { s as number }), r#"function(s)do local __s=s;s=tonumber(s);assert(s~=nil,"number expected in \'s\', got "..type(__s));end;end"# ); assert_eq!( luaify!(|s| { s as nil }), r#"function(s)do assert(s==nil,"nil expected in \'s\', got "..type(s));end;end"# ); assert_eq!(luaify!(|s| { s as any }), r#"function(s)do end;end"#); assert_eq!( luaify!(|s| { let (ok, res) = coroutine::r#yield(thread); ok as boolean; res as nil; }), r#"function(s)local ok,res=coroutine.yield(thread);do assert(type(ok)=="boolean","boolean expected in \'ok\', got "..type(ok));end;do assert(res==nil,"nil expected in \'res\', got "..type(res));end;end"# ); } #[test] fn concat() { assert_eq!(luaify!(concat!(a)), r#"a"#); assert_eq!(luaify!(concat!(a, b)), r#"a..b"#); assert_eq!(luaify!(concat!(a, b, c)), r#"a..b..c"#); assert_eq!( luaify!(|a, b, c| concat!(a, b, c)), r#"function(a,b,c)return a..b..c;end"# ); } #[test] fn blocks() { assert_eq!( luaify!(|| { { "result" } }), r#"function()do return"result";end;end"# ); assert_eq!( luaify!(|| { {} { "result" } }), r#"function()do end;do return"result";end;end"# ); assert_eq!( luaify!(|| { { { { "result" } } } }), r#"function()do do do return"result";end;end;end;end"# ); } #[test] fn ops() { assert_eq!(luaify!(|| a = b), r#"function()a=b;end"#); assert_eq!(luaify!(|| a + b), r#"function()return a+b;end"#); assert_eq!(luaify!(|| a += b), r#"function()a=a+b;end"#); assert_eq!(luaify!(|| a - b), r#"function()return a-b;end"#); assert_eq!(luaify!(|| a -= b), r#"function()a=a-b;end"#); assert_eq!(luaify!(|| a * b), r#"function()return a*b;end"#); assert_eq!(luaify!(|| a *= b), r#"function()a=a*b;end"#); assert_eq!(luaify!(|| a / b), r#"function()return a/b;end"#); assert_eq!(luaify!(|| a /= b), r#"function()a=a/b;end"#); assert_eq!(luaify!(|| a = b % c), r#"function()a=__fmod(b,c);end"#); assert_eq!(luaify!(|| a = b << c), r#"function()a=__blshift(b,c);end"#); assert_eq!( luaify!(|| a <<= b << c), r#"function()a=__blshift(a,__blshift(b,c));end"# ); assert_eq!(luaify!(|| a = b >> c), r#"function()a=__barshift(b,c);end"#); assert_eq!( luaify!(|| a >>= b >> c), r#"function()a=__barshift(a,__barshift(b,c));end"# ); assert_eq!(luaify!(|| a && b), r#"function()return a and b;end"#); assert_eq!(luaify!(|| a || b), r#"function()return a or b;end"#); assert_eq!( luaify!(|| (a && b) || c), r#"function()return(a and b)or c;end"# ); assert_eq!( luaify!(|| (a || b) && c), r#"function()return(a or b)and c;end"# ); assert_eq!( luaify!(|| a && (b || c)), r#"function()return a and(b or c);end"# ); assert_eq!( luaify!(|| a || (b && c)), r#"function()return a or(b and c);end"# ); assert_eq!( luaify!(|| -a || !--b && c >> d), r#"function()return-a or not-(-b)and __barshift(c,d);end"# ); assert_eq!( luaify!(|| -a || !(--b && c) >> d), r#"function()return-a or __barshift(not(-(-b)and c),d);end"# ); assert_eq!( luaify!(|| a >> b << c >> d), r#"function()return __barshift(__blshift(__barshift(a,b),c),d);end"# ); } #[test] fn ifs() { assert_eq!( luaify!(|| { if a == b { c } }), r#"function()if a==b then return c;end;end"# ); assert_eq!( luaify!(|| { if a == b { c } else { d } }), r#"function()if a==b then return c;else return d;end;end"# ); assert_eq!( luaify!(|| { if a == b { c() } else if b == c { a() } else { d() }; }), r#"function()if a==b then c();elseif b==c then a();else d();end;end"# ); assert_eq!( luaify!(|| { if a == b { c() } else if b == c { a() } else { d() } }), r#"function()if a==b then return c();elseif b==c then return a();else return d();end;end"# ); assert_eq!( luaify!(|| { if a == b { c(); } else if b == c { a() } else { d(); } }), r#"function()if a==b then c();elseif b==c then return a();else d();end;end"# ); } #[test] fn variadic() { assert_eq!(luaify!(|a, b, variadic!()| {}), r#"function(a,b,...)end"#); assert_eq!( luaify!(|variadic!()| { let (a, b) = variadic!(); }), r#"function(...)local a,b=...;end"# ); assert_eq!( luaify!(|a, variadic!()| { let (a, b) = (a, b, c, variadic!()); func(a, b, (c, (d, variadic!()))) }), r#"function(a,...)local a,b=a,b,c,...;return func(a,b,c,d,...);end"# ); } #[test] fn length() { assert_eq!(luaify!(len!(a)), r#"#a"#); assert_eq!( luaify!({ let (a, b, c) = (len!(a), len!(b), len!(c)); }), r#"local a,b,c=#a,#b,#c;"# ); }