Add tests for metatag operations.
This commit is contained in:
@@ -75,7 +75,7 @@ public class LuaDouble extends LuaNumber {
|
|||||||
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
|
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
|
||||||
|
|
||||||
// arithmetic equality
|
// arithmetic equality
|
||||||
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v)? TRUE: FALSE; }
|
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; }
|
||||||
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
|
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
|
||||||
public boolean eq_b( double rhs ) { return v == rhs; }
|
public boolean eq_b( double rhs ) { return v == rhs; }
|
||||||
public boolean eq_b( int rhs ) { return v == rhs; }
|
public boolean eq_b( int rhs ) { return v == rhs; }
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class LuaInteger extends LuaNumber {
|
|||||||
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
|
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
|
||||||
|
|
||||||
// arithmetic equality
|
// arithmetic equality
|
||||||
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v)? TRUE: FALSE; }
|
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; }
|
||||||
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
|
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
|
||||||
public boolean eq_b( double rhs ) { return v == rhs; }
|
public boolean eq_b( double rhs ) { return v == rhs; }
|
||||||
public boolean eq_b( int rhs ) { return v == rhs; }
|
public boolean eq_b( int rhs ) { return v == rhs; }
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ public class LuaString extends LuaValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean eq_b( LuaValue val ) {
|
public boolean eq_b( LuaValue val ) {
|
||||||
return val.eq_b( this );
|
return val == this || (val.type()==TSTRING && val.eq_b(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) {
|
public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) {
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ public class LuaValue extends Varargs {
|
|||||||
protected LuaValue aritherror(String fun) { throw new LuaError("attempt to perform arithmetic '"+fun+"' on "+typename()); }
|
protected LuaValue aritherror(String fun) { throw new LuaError("attempt to perform arithmetic '"+fun+"' on "+typename()); }
|
||||||
protected LuaValue compareerror(String rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs); }
|
protected LuaValue compareerror(String rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs); }
|
||||||
protected LuaValue compareerror(LuaValue rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs.typename()); }
|
protected LuaValue compareerror(LuaValue rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs.typename()); }
|
||||||
protected LuaValue concaterror() { throw new LuaError("attempt to concatenate "+typename()); }
|
|
||||||
|
|
||||||
// table operations
|
// table operations
|
||||||
public LuaValue get( LuaValue key ) { return gettable(this,key); }
|
public LuaValue get( LuaValue key ) { return gettable(this,key); }
|
||||||
@@ -257,8 +256,8 @@ public class LuaValue extends Varargs {
|
|||||||
public boolean equals(Object obj) { return this == obj; }
|
public boolean equals(Object obj) { return this == obj; }
|
||||||
|
|
||||||
// arithmetic equality
|
// arithmetic equality
|
||||||
public LuaValue eq( LuaValue val ) { return eq_b(val)? TRUE: FALSE; }
|
public LuaValue eq( LuaValue val ) { return this == val || eq_b(val)? TRUE: FALSE; }
|
||||||
public boolean eq_b( LuaValue val ) { return this == val; }
|
public boolean eq_b( LuaValue val ) { return this == val || (type() == val.type() && eqmt_b(val)); }
|
||||||
public boolean eq_b( LuaTable val ) { return false; }
|
public boolean eq_b( LuaTable val ) { return false; }
|
||||||
public boolean eq_b( LuaUserdata val ) { return false; }
|
public boolean eq_b( LuaUserdata val ) { return false; }
|
||||||
public boolean eq_b( LuaString val ) { return false; }
|
public boolean eq_b( LuaString val ) { return false; }
|
||||||
@@ -300,8 +299,11 @@ public class LuaValue extends Varargs {
|
|||||||
public LuaValue modFrom(double lhs) { return aritherror("modFrom"); }
|
public LuaValue modFrom(double lhs) { return aritherror("modFrom"); }
|
||||||
protected LuaValue arithmt(LuaValue tag, LuaValue op2) {
|
protected LuaValue arithmt(LuaValue tag, LuaValue op2) {
|
||||||
LuaValue h = this.metatag(tag);
|
LuaValue h = this.metatag(tag);
|
||||||
|
if ( h.isnil() ) {
|
||||||
|
h = op2.metatag(tag);
|
||||||
if ( h.isnil() )
|
if ( h.isnil() )
|
||||||
h = op2.checkmetatag(tag, "attempt to perform arithmetic on ");
|
error( "attempt to perform arithmetic "+tag+" on "+typename()+" and "+op2.typename() );
|
||||||
|
}
|
||||||
return h.call( this, op2 );
|
return h.call( this, op2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +338,7 @@ public class LuaValue extends Varargs {
|
|||||||
if ( !h.isnil() && h == op1.metatag(tag) )
|
if ( !h.isnil() && h == op1.metatag(tag) )
|
||||||
return h.call(this, op1);
|
return h.call(this, op1);
|
||||||
}
|
}
|
||||||
return error("attempt to compare "+typename());
|
return error("attempt to compare "+tag+" on "+typename()+" and "+op1.typename());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,7 +356,7 @@ public class LuaValue extends Varargs {
|
|||||||
public LuaValue concatmt(LuaValue rhs) {
|
public LuaValue concatmt(LuaValue rhs) {
|
||||||
LuaValue h=metatag(CONCAT);
|
LuaValue h=metatag(CONCAT);
|
||||||
if ( h.isnil() && (h=rhs.metatag(CONCAT)).isnil())
|
if ( h.isnil() && (h=rhs.metatag(CONCAT)).isnil())
|
||||||
return (isstring()? rhs: this).concaterror();
|
error("attempt to concatenate "+typename()+" and "+rhs.typename());
|
||||||
return h.call(this,rhs);
|
return h.call(this,rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -271,8 +271,7 @@ public class WeakTable extends LuaTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int type() {
|
public int type() {
|
||||||
illegal("type","weak entry");
|
return TNONE;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String typename() {
|
public String typename() {
|
||||||
@@ -293,6 +292,10 @@ public class WeakTable extends LuaTable {
|
|||||||
return weakkey.eq_b(rhs);
|
return weakkey.eq_b(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean eq_b( LuaString rhs ) { return false; }
|
||||||
|
public boolean eq_b( double val ) { return false; }
|
||||||
|
public boolean eq_b( int val ) { return false; }
|
||||||
|
|
||||||
public boolean isweaknil() {
|
public boolean isweaknil() {
|
||||||
return weakkey.isweaknil() || weakvalue.isweaknil();
|
return weakkey.isweaknil() || weakvalue.isweaknil();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,12 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2;
|
package org.luaj.vm2;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaDouble;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import org.luaj.vm2.LuaInteger;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.luaj.vm2.lib.TwoArgFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests of basic unary and binary operators on main value types.
|
* Tests of basic unary and binary operators on main value types.
|
||||||
*/
|
*/
|
||||||
@@ -212,6 +210,123 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
assertEquals(LuaValue.NIL.eq(da),LuaValue.FALSE);
|
assertEquals(LuaValue.NIL.eq(da),LuaValue.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final TwoArgFunction RETURN_NIL = new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final TwoArgFunction RETURN_ONE = new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return ONE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public void testEqualsMetatag() {
|
||||||
|
LuaValue tru = LuaValue.TRUE;
|
||||||
|
LuaValue fal = LuaValue.FALSE;
|
||||||
|
LuaValue zer = LuaValue.ZERO;
|
||||||
|
LuaValue one = LuaValue.ONE;
|
||||||
|
LuaValue abc = LuaValue.valueOf("abcdef").substring(0,3);
|
||||||
|
LuaValue def = LuaValue.valueOf("abcdef").substring(3,6);
|
||||||
|
LuaValue pi = LuaValue.valueOf(Math.PI);
|
||||||
|
LuaValue ee = LuaValue.valueOf(Math.E);
|
||||||
|
LuaValue tbl = new LuaTable();
|
||||||
|
LuaValue tbl2 = new LuaTable();
|
||||||
|
LuaValue tbl3 = new LuaTable();
|
||||||
|
LuaValue nilb = LuaValue.valueOf( LuaValue.NIL.toboolean() );
|
||||||
|
LuaValue oneb = LuaValue.valueOf( LuaValue.ONE.toboolean() );
|
||||||
|
assertEquals( LuaValue.FALSE, nilb );
|
||||||
|
assertEquals( LuaValue.TRUE, oneb );
|
||||||
|
LuaValue smt = LuaString.s_metatable;
|
||||||
|
try {
|
||||||
|
// always return nil0
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } );
|
||||||
|
LuaNumber.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } );
|
||||||
|
LuaString.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } );
|
||||||
|
tbl.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } ));
|
||||||
|
tbl2.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } ));
|
||||||
|
// diff metatag function
|
||||||
|
tbl3.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } ));
|
||||||
|
|
||||||
|
// same type, same value, does not invoke metatag op
|
||||||
|
assertEquals( tru, tru.eq(tru) );
|
||||||
|
assertEquals( tru, tbl.eq(tbl) );
|
||||||
|
assertEquals( tru, one.eq(one) );
|
||||||
|
// same type, different value, same metatag op. comparabile via metatag op
|
||||||
|
assertEquals( nilb, tbl.eq(tbl2) );
|
||||||
|
assertEquals( nilb, tbl2.eq(tbl) );
|
||||||
|
assertEquals( nilb, tru.eq(fal) );
|
||||||
|
assertEquals( nilb, fal.eq(tru) );
|
||||||
|
assertEquals( nilb, zer.eq(one) );
|
||||||
|
assertEquals( nilb, one.eq(zer) );
|
||||||
|
assertEquals( nilb, pi.eq(ee) );
|
||||||
|
assertEquals( nilb, ee.eq(pi) );
|
||||||
|
assertEquals( nilb, pi.eq(one) );
|
||||||
|
assertEquals( nilb, one.eq(pi) );
|
||||||
|
assertEquals( nilb, abc.eq(def) );
|
||||||
|
assertEquals( nilb, def.eq(abc) );
|
||||||
|
// different types. not comparable
|
||||||
|
assertEquals( fal, fal.eq(tbl) );
|
||||||
|
assertEquals( fal, tbl.eq(fal) );
|
||||||
|
assertEquals( fal, tbl.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(tbl) );
|
||||||
|
assertEquals( fal, fal.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(fal) );
|
||||||
|
assertEquals( fal, abc.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(abc) );
|
||||||
|
// same type, different metatag ops. not comparable
|
||||||
|
assertEquals( fal, tbl.eq(tbl3) );
|
||||||
|
assertEquals( fal, tbl3.eq(tbl) );
|
||||||
|
|
||||||
|
// always use right argument
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } );
|
||||||
|
LuaNumber.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } );
|
||||||
|
LuaString.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } );
|
||||||
|
tbl.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } ));
|
||||||
|
tbl2.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_ONE, } ));
|
||||||
|
// diff metatag function
|
||||||
|
tbl3.setmetatable(LuaValue.tableOf( new LuaValue[] { LuaValue.EQ, RETURN_NIL, } ));
|
||||||
|
|
||||||
|
// same type, same value, does not invoke metatag op
|
||||||
|
assertEquals( tru, tru.eq(tru) );
|
||||||
|
assertEquals( tru, tbl.eq(tbl) );
|
||||||
|
assertEquals( tru, one.eq(one) );
|
||||||
|
// same type, different value, same metatag op. comparabile via metatag op
|
||||||
|
assertEquals( oneb, tbl.eq(tbl2) );
|
||||||
|
assertEquals( oneb, tbl2.eq(tbl) );
|
||||||
|
assertEquals( oneb, tru.eq(fal) );
|
||||||
|
assertEquals( oneb, fal.eq(tru) );
|
||||||
|
assertEquals( oneb, zer.eq(one) );
|
||||||
|
assertEquals( oneb, one.eq(zer) );
|
||||||
|
assertEquals( oneb, pi.eq(ee) );
|
||||||
|
assertEquals( oneb, ee.eq(pi) );
|
||||||
|
assertEquals( oneb, pi.eq(one) );
|
||||||
|
assertEquals( oneb, one.eq(pi) );
|
||||||
|
assertEquals( oneb, abc.eq(def) );
|
||||||
|
assertEquals( oneb, def.eq(abc) );
|
||||||
|
// different types. not comparable
|
||||||
|
assertEquals( fal, fal.eq(tbl) );
|
||||||
|
assertEquals( fal, tbl.eq(fal) );
|
||||||
|
assertEquals( fal, tbl.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(tbl) );
|
||||||
|
assertEquals( fal, fal.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(fal) );
|
||||||
|
assertEquals( fal, abc.eq(one) );
|
||||||
|
assertEquals( fal, one.eq(abc) );
|
||||||
|
// same type, different metatag ops. not comparable
|
||||||
|
assertEquals( fal, tbl.eq(tbl3) );
|
||||||
|
assertEquals( fal, tbl3.eq(tbl) );
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
LuaBoolean.s_metatable = null;
|
||||||
|
LuaNumber.s_metatable = null;
|
||||||
|
LuaString.s_metatable = smt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testAdd() {
|
public void testAdd() {
|
||||||
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||||
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||||
@@ -338,6 +453,155 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
assertEquals(luaMod(1.5,.25), sa.mod(da).todouble());
|
assertEquals(luaMod(1.5,.25), sa.mod(da).todouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testArithErrors() {
|
||||||
|
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||||
|
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||||
|
LuaValue sa=LuaValue.valueOf("22.125"), sb=LuaValue.valueOf("7.25");
|
||||||
|
|
||||||
|
String[] ops = { "add", "sub", "mul", "div", "mod", "pow" };
|
||||||
|
LuaValue[] vals = { LuaValue.NIL, LuaValue.TRUE, LuaValue.tableOf() };
|
||||||
|
LuaValue[] numerics = { LuaValue.valueOf(111), LuaValue.valueOf(55.25), LuaValue.valueOf("22.125") };
|
||||||
|
for ( int i=0; i<ops.length; i++ ) {
|
||||||
|
for ( int j=0; j<vals.length; j++ ) {
|
||||||
|
for ( int k=0; k<numerics.length; k++ ) {
|
||||||
|
checkArithError( vals[j], numerics[k], ops[i], vals[j].typename() );
|
||||||
|
checkArithError( numerics[k], vals[j], ops[i], vals[j].typename() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkArithError(LuaValue a, LuaValue b, String op, String type) {
|
||||||
|
try {
|
||||||
|
LuaValue.class.getMethod(op, new Class[] { LuaValue.class }).invoke(a, new Object[] { b });
|
||||||
|
} catch ( InvocationTargetException ite ) {
|
||||||
|
String actual = ite.getTargetException().getMessage();
|
||||||
|
if ( (!actual.startsWith("attempt to perform arithmetic")) || actual.indexOf(type)<0 )
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") reported '"+actual+"'" );
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") threw "+e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final TwoArgFunction RETURN_LHS = new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final TwoArgFunction RETURN_RHS = new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void testArithMetatag() {
|
||||||
|
LuaValue tru = LuaValue.TRUE;
|
||||||
|
LuaValue fal = LuaValue.FALSE;
|
||||||
|
LuaValue tbl = new LuaTable();
|
||||||
|
LuaValue tbl2 = new LuaTable();
|
||||||
|
try {
|
||||||
|
try { tru.add(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.mul(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.div(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.pow(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.mod(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
// always use left argument
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.ADD, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.add(fal) );
|
||||||
|
assertEquals( tru, tru.add(tbl) );
|
||||||
|
assertEquals( tbl, tbl.add(tru) );
|
||||||
|
try { tbl.add(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.SUB, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.sub(fal) );
|
||||||
|
assertEquals( tru, tru.sub(tbl) );
|
||||||
|
assertEquals( tbl, tbl.sub(tru) );
|
||||||
|
try { tbl.sub(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.add(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.MUL, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.mul(fal) );
|
||||||
|
assertEquals( tru, tru.mul(tbl) );
|
||||||
|
assertEquals( tbl, tbl.mul(tru) );
|
||||||
|
try { tbl.mul(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.DIV, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.div(fal) );
|
||||||
|
assertEquals( tru, tru.div(tbl) );
|
||||||
|
assertEquals( tbl, tbl.div(tru) );
|
||||||
|
try { tbl.div(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.POW, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.pow(fal) );
|
||||||
|
assertEquals( tru, tru.pow(tbl) );
|
||||||
|
assertEquals( tbl, tbl.pow(tru) );
|
||||||
|
try { tbl.pow(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.MOD, RETURN_LHS, } );
|
||||||
|
assertEquals( tru, tru.mod(fal) );
|
||||||
|
assertEquals( tru, tru.mod(tbl) );
|
||||||
|
assertEquals( tbl, tbl.mod(tru) );
|
||||||
|
try { tbl.mod(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
|
||||||
|
// always use right argument
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.ADD, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.add(fal) );
|
||||||
|
assertEquals( tbl, tru.add(tbl) );
|
||||||
|
assertEquals( tru, tbl.add(tru) );
|
||||||
|
try { tbl.add(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.SUB, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.sub(fal) );
|
||||||
|
assertEquals( tbl, tru.sub(tbl) );
|
||||||
|
assertEquals( tru, tbl.sub(tru) );
|
||||||
|
try { tbl.sub(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.add(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.MUL, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.mul(fal) );
|
||||||
|
assertEquals( tbl, tru.mul(tbl) );
|
||||||
|
assertEquals( tru, tbl.mul(tru) );
|
||||||
|
try { tbl.mul(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.DIV, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.div(fal) );
|
||||||
|
assertEquals( tbl, tru.div(tbl) );
|
||||||
|
assertEquals( tru, tbl.div(tru) );
|
||||||
|
try { tbl.div(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.POW, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.pow(fal) );
|
||||||
|
assertEquals( tbl, tru.pow(tbl) );
|
||||||
|
assertEquals( tru, tbl.pow(tru) );
|
||||||
|
try { tbl.pow(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.MOD, RETURN_RHS, } );
|
||||||
|
assertEquals( fal, tru.mod(fal) );
|
||||||
|
assertEquals( tbl, tru.mod(tbl) );
|
||||||
|
assertEquals( tru, tbl.mod(tru) );
|
||||||
|
try { tbl.mod(tbl2); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.sub(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
LuaBoolean.s_metatable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testCompareStrings() {
|
public void testCompareStrings() {
|
||||||
// these are lexical compare!
|
// these are lexical compare!
|
||||||
LuaValue sa=LuaValue.valueOf("-1.5");
|
LuaValue sa=LuaValue.valueOf("-1.5");
|
||||||
@@ -459,6 +723,90 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
assertEquals(1.5!=.25, sa.neq_b(da));
|
assertEquals(1.5!=.25, sa.neq_b(da));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testCompareErrors() {
|
||||||
|
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||||
|
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||||
|
LuaValue sa=LuaValue.valueOf("22.125"), sb=LuaValue.valueOf("7.25");
|
||||||
|
|
||||||
|
String[] ops = { "lt", "lteq", };
|
||||||
|
LuaValue[] vals = { LuaValue.NIL, LuaValue.TRUE, LuaValue.tableOf() };
|
||||||
|
LuaValue[] numerics = { LuaValue.valueOf(111), LuaValue.valueOf(55.25), LuaValue.valueOf("22.125") };
|
||||||
|
for ( int i=0; i<ops.length; i++ ) {
|
||||||
|
for ( int j=0; j<vals.length; j++ ) {
|
||||||
|
for ( int k=0; k<numerics.length; k++ ) {
|
||||||
|
checkCompareError( vals[j], numerics[k], ops[i], vals[j].typename() );
|
||||||
|
checkCompareError( numerics[k], vals[j], ops[i], vals[j].typename() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCompareError(LuaValue a, LuaValue b, String op, String type) {
|
||||||
|
try {
|
||||||
|
LuaValue.class.getMethod(op, new Class[] { LuaValue.class }).invoke(a, new Object[] { b });
|
||||||
|
} catch ( InvocationTargetException ite ) {
|
||||||
|
String actual = ite.getTargetException().getMessage();
|
||||||
|
if ( (!actual.startsWith("attempt to compare")) || actual.indexOf(type)<0 )
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") reported '"+actual+"'" );
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") threw "+e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCompareMetatag() {
|
||||||
|
LuaValue tru = LuaValue.TRUE;
|
||||||
|
LuaValue fal = LuaValue.FALSE;
|
||||||
|
LuaValue tbl = new LuaTable();
|
||||||
|
LuaValue tbl2 = new LuaTable();
|
||||||
|
LuaValue tbl3 = new LuaTable();
|
||||||
|
try {
|
||||||
|
// always use left argument
|
||||||
|
LuaValue mt = LuaValue.tableOf( new LuaValue[] {
|
||||||
|
LuaValue.LT, RETURN_LHS,
|
||||||
|
LuaValue.LE, RETURN_RHS,
|
||||||
|
} );
|
||||||
|
LuaBoolean.s_metatable = mt;
|
||||||
|
tbl.setmetatable(mt);
|
||||||
|
tbl2.setmetatable(mt);
|
||||||
|
assertEquals( tru, tru.lt(fal) );
|
||||||
|
assertEquals( fal, fal.lt(tru) );
|
||||||
|
assertEquals( tbl, tbl.lt(tbl2) );
|
||||||
|
assertEquals( tbl2, tbl2.lt(tbl) );
|
||||||
|
try { tbl.lt(tbl3); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tbl3.lt(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
assertEquals( fal, tru.lteq(fal) );
|
||||||
|
assertEquals( tru, fal.lteq(tru) );
|
||||||
|
assertEquals( tbl2, tbl.lteq(tbl2) );
|
||||||
|
assertEquals( tbl, tbl2.lteq(tbl) );
|
||||||
|
try { tbl.lteq(tbl3); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tbl3.lteq(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
// always use right argument
|
||||||
|
mt = LuaValue.tableOf( new LuaValue[] {
|
||||||
|
LuaValue.LT, RETURN_RHS,
|
||||||
|
LuaValue.LE, RETURN_LHS } );
|
||||||
|
LuaBoolean.s_metatable = mt;
|
||||||
|
tbl.setmetatable(mt);
|
||||||
|
tbl2.setmetatable(mt);
|
||||||
|
assertEquals( fal, tru.lt(fal) );
|
||||||
|
assertEquals( tru, fal.lt(tru) );
|
||||||
|
assertEquals( tbl2, tbl.lt(tbl2) );
|
||||||
|
assertEquals( tbl, tbl2.lt(tbl) );
|
||||||
|
try { tbl.lt(tbl3); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tbl3.lt(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
assertEquals( tru, tru.lteq(fal) );
|
||||||
|
assertEquals( fal, fal.lteq(tru) );
|
||||||
|
assertEquals( tbl, tbl.lteq(tbl2) );
|
||||||
|
assertEquals( tbl2, tbl2.lteq(tbl) );
|
||||||
|
try { tbl.lteq(tbl3); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tbl3.lteq(tbl); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
LuaBoolean.s_metatable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testAnd() {
|
public void testAnd() {
|
||||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||||
@@ -657,12 +1005,7 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
LuaValue uda = new LuaUserdata(new Object());
|
LuaValue uda = new LuaUserdata(new Object());
|
||||||
try {
|
try {
|
||||||
// always use left argument
|
// always use left argument
|
||||||
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] {
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.CONCAT, RETURN_LHS } );
|
||||||
LuaValue.CONCAT, new TwoArgFunction() {
|
|
||||||
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
} } );
|
|
||||||
assertEquals( tru, tru.concat(tbl) );
|
assertEquals( tru, tru.concat(tbl) );
|
||||||
assertEquals( tbl, tbl.concat(tru) );
|
assertEquals( tbl, tbl.concat(tru) );
|
||||||
assertEquals( tru, tru.concat(tbl) );
|
assertEquals( tru, tru.concat(tbl) );
|
||||||
@@ -679,12 +1022,7 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
try { ghi.concat(tbl.concat(def.buffer())).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
try { ghi.concat(tbl.concat(def.buffer())).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
// always use right argument
|
// always use right argument
|
||||||
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] {
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] { LuaValue.CONCAT, RETURN_RHS } );
|
||||||
LuaValue.CONCAT, new TwoArgFunction() {
|
|
||||||
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
|
||||||
return rhs;
|
|
||||||
}
|
|
||||||
} } );
|
|
||||||
assertEquals( tbl, tru.concat(tbl) );
|
assertEquals( tbl, tru.concat(tbl) );
|
||||||
assertEquals( tru, tbl.concat(tru) );
|
assertEquals( tru, tbl.concat(tru) );
|
||||||
assertEquals( tbl, tru.concat(tbl.buffer()).value() );
|
assertEquals( tbl, tru.concat(tbl.buffer()).value() );
|
||||||
@@ -702,4 +1040,35 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
LuaBoolean.s_metatable = null;
|
LuaBoolean.s_metatable = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testConcatErrors() {
|
||||||
|
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||||
|
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||||
|
LuaValue sa=LuaValue.valueOf("22.125"), sb=LuaValue.valueOf("7.25");
|
||||||
|
|
||||||
|
String[] ops = { "concat" };
|
||||||
|
LuaValue[] vals = { LuaValue.NIL, LuaValue.TRUE, LuaValue.tableOf() };
|
||||||
|
LuaValue[] numerics = { LuaValue.valueOf(111), LuaValue.valueOf(55.25), LuaValue.valueOf("22.125") };
|
||||||
|
for ( int i=0; i<ops.length; i++ ) {
|
||||||
|
for ( int j=0; j<vals.length; j++ ) {
|
||||||
|
for ( int k=0; k<numerics.length; k++ ) {
|
||||||
|
checkConcatError( vals[j], numerics[k], ops[i], vals[j].typename() );
|
||||||
|
checkConcatError( numerics[k], vals[j], ops[i], vals[j].typename() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConcatError(LuaValue a, LuaValue b, String op, String type) {
|
||||||
|
try {
|
||||||
|
LuaValue.class.getMethod(op, new Class[] { LuaValue.class }).invoke(a, new Object[] { b });
|
||||||
|
} catch ( InvocationTargetException ite ) {
|
||||||
|
String actual = ite.getTargetException().getMessage();
|
||||||
|
if ( (!actual.startsWith("attempt to concatenate")) || actual.indexOf(type)<0 )
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") reported '"+actual+"'" );
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
fail( "("+a.typename()+","+op+","+b.typename()+") threw "+e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user