_G.set("a", aaa);
newenv.set("a", eee);
// function tests
{
LuaFunction f = new ZeroArgFunction(_G) { public LuaValue call() { return env.get("a");}};
assertEquals( aaa, f.call() );
f.setfenv(newenv);
assertEquals( newenv, f.getfenv() );
assertEquals( eee, f.call() );
}
// closure tests
{
Prototype p = createPrototype( "return a\n", "closuretester" );
LuaClosure c = new LuaClosure(p, _G);
assertEquals( aaa, c.call() );
c.setfenv(newenv);
assertEquals( newenv, c.getfenv() );
assertEquals( eee, c.call() );
}
// thread tests, functions created in threads inherit the thread's environment initially
// those closures created not in any other function get the thread's enviroment
Prototype p2 = createPrototype( "return loadstring('return a')", "threadtester" );
{
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( aaa, f.call() );
assertEquals( _G, f.getfenv() );
}
{
// change the thread environment after creation!
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
t.setfenv(newenv);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( eee, f.call() );
assertEquals( newenv, f.getfenv() );
}
{
// let the closure have a different environment from the thread
Prototype p3 = createPrototype( "return function() return a end", "envtester" );
LuaThread t = new LuaThread(new LuaClosure(p3,newenv), _G);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( eee, f.call() );
assertEquals( newenv, f.getfenv() );
}
}