package uk.co.badgersinfoil.metaas;
import java.io.IOException;
import java.util.List;
import uk.co.badgersinfoil.metaas.dom.ASArg;
import uk.co.badgersinfoil.metaas.dom.ASClassType;
import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
import uk.co.badgersinfoil.metaas.dom.ASMethod;
import uk.co.badgersinfoil.metaas.dom.Visibility;
import junit.framework.TestCase;
public class ASMethodTests extends TestCase {
private ActionScriptFactory fact = new ActionScriptFactory();
private ASCompilationUnit unit;
private ASClassType clazz;
private ASMethod meth;
protected void setUp() {
unit = fact.newClass("Test");
clazz = (ASClassType)unit.getType();
meth = clazz.newMethod("test", Visibility.PUBLIC, null);
}
protected void tearDown() throws IOException {
CodeMirror.assertReflection(fact, unit);
}
public void testName() {
assertEquals("test", meth.getName());
meth.setName("foobar");
assertEquals("foobar", meth.getName());
try {
meth.setName("bad.name");
fail("should not have accepted method name containing '.'");
} catch (SyntaxException e) {
// expected
}
try {
meth.setName("bad:name");
fail("should not have accepted method name containing ':'");
} catch (SyntaxException e) {
// expected
}
}
public void testStatic() {
assertFalse("new methods should be non-static by default", meth.isStatic());
meth.setStatic(false);
assertFalse(meth.isStatic());
meth.setStatic(true);
assertTrue(meth.isStatic());
meth.setStatic(true);
assertTrue(meth.isStatic());
}
public void testAccessorRole() {
assertEquals(ASMethod.AccessorRole.NORMAL_METHOD, meth.getAccessorRole());
// now add a role,
meth.setAccessorRole(ASMethod.AccessorRole.GETTER);
assertEquals(ASMethod.AccessorRole.GETTER, meth.getAccessorRole());
// change existing role to set
meth.setAccessorRole(ASMethod.AccessorRole.SETTER);
assertEquals(ASMethod.AccessorRole.SETTER, meth.getAccessorRole());
// change existing role to get
meth.setAccessorRole(ASMethod.AccessorRole.GETTER);
assertEquals(ASMethod.AccessorRole.GETTER, meth.getAccessorRole());
// check the AST internals didn't get mangled along the way,
assertEquals("test", meth.getName());
meth.setAccessorRole(ASMethod.AccessorRole.NORMAL_METHOD);
assertEquals(ASMethod.AccessorRole.NORMAL_METHOD, meth.getAccessorRole());
// now add a role back in, but this time as a setter
meth.setAccessorRole(ASMethod.AccessorRole.SETTER);
assertEquals(ASMethod.AccessorRole.SETTER, meth.getAccessorRole());
// squeeze out the last bit of code coverage,
assertEquals("NORMAL_METHOD", ASMethod.AccessorRole.NORMAL_METHOD.toString());
assertEquals("GETTER", ASMethod.AccessorRole.GETTER.toString());
assertEquals("SETTER", ASMethod.AccessorRole.SETTER.toString());
}
public void testReturnType() throws IOException {
assertNull(meth.getType());
meth.setType("pkg.Clazz");
assertEquals("pkg.Clazz", meth.getType());
// "void" is a keyword, rather than an IDENT
meth.setType("void");
assertEquals("void", meth.getType());
ASCompilationUnit reflectedUnit = CodeMirror.assertReflection(fact, unit);
ASMethod reflectedMethod = reflectedUnit.getType().getMethod(meth.getName());
assertEquals("void", reflectedMethod.getType());
meth.setType(null);
assertNull(meth.getType());
}
public void testProtection() {
assertVisibility(Visibility.PUBLIC, meth);
meth.setVisibility(Visibility.PRIVATE);
assertVisibility(Visibility.PRIVATE, meth);
meth.setVisibility(Visibility.PROTECTED);
assertVisibility(Visibility.PROTECTED, meth);
meth.setVisibility(Visibility.INTERNAL);
assertVisibility(Visibility.INTERNAL, meth);
meth.setVisibility(Visibility.PUBLIC);
assertVisibility(Visibility.PUBLIC, meth);
checkSetVisibilityAfterDefault(meth, Visibility.PRIVATE);
checkSetVisibilityAfterDefault(meth, Visibility.PUBLIC);
checkSetVisibilityAfterDefault(meth, Visibility.PROTECTED);
checkSetVisibilityAfterDefault(meth, Visibility.INTERNAL);
// see what happens when there is no visibility modifier, but
// there *is* some other kind of modifier keyword,
meth.setVisibility(Visibility.DEFAULT);
meth.setStatic(true);
assertVisibility(Visibility.DEFAULT, meth);
meth.setVisibility(Visibility.PUBLIC);
assertVisibility(Visibility.PUBLIC, meth);
try {
meth.setVisibility(null);
fail("should reject 'null' visibility");
} catch (Exception e) {
// expected
}
// squeeze out the last bit of code coverage,
assertEquals("public", Visibility.PUBLIC.toString());
assertEquals("private", Visibility.PRIVATE.toString());
assertEquals("protected", Visibility.PROTECTED.toString());
assertEquals("internal", Visibility.INTERNAL.toString());
assertEquals("[default]", Visibility.DEFAULT.toString());
}
private static void assertVisibility(Visibility expectedVisibility,
ASMethod method)
{
assertSame(expectedVisibility, method.getVisibility());
}
private static void checkSetVisibilityAfterDefault(ASMethod method,
Visibility visibility)
{
method.setVisibility(Visibility.DEFAULT);
assertVisibility(Visibility.DEFAULT, method);
method.setVisibility(visibility);
assertVisibility(visibility, method);
}
public void testProtectionOnCreate() {
meth = clazz.newMethod("testDefault", Visibility.DEFAULT, null);
assertVisibility(Visibility.DEFAULT, meth);
meth = clazz.newMethod("testPublic", Visibility.PUBLIC, null);
assertVisibility(Visibility.PUBLIC, meth);
meth = clazz.newMethod("testPrivate", Visibility.PRIVATE, null);
assertVisibility(Visibility.PRIVATE, meth);
meth = clazz.newMethod("testProtected", Visibility.PROTECTED, null);
assertVisibility(Visibility.PROTECTED, meth);
meth = clazz.newMethod("testInternal", Visibility.INTERNAL, null);
assertVisibility(Visibility.INTERNAL, meth);
}
public void testArgs() throws IOException {
ASArg foo = meth.addParam("foo", "Number");
assertEquals("foo", foo.getName());
assertEquals("Number", foo.getType());
foo.setDefault("null");
foo.setDefault("1"); // reset existing value
assertEquals("1", foo.getDefaultString());
foo.setDefault(null); // remove value
try {
foo.setDefault("]");
fail("should have rejected invalid initialiser value");
} catch (SyntaxException e) {
// expected
}
assertNull(foo.getDefaultString());
meth.addParam("bar", null);
meth.addParam("blat", null);
List args = meth.getArgs();
assertEquals(3, args.size());
ASArg arg0 = (ASArg)args.get(0);
assertEquals("foo", arg0.getName());
assertEquals("Number", arg0.getType());
assertEquals("foo:Number", arg0.toString());
arg0.setType("String");
assertEquals("String", arg0.getType());
arg0.setType(null);
assertNull(arg0.getType());
assertEquals("foo", arg0.toString());
ASArg arg1 = (ASArg)args.get(1);
assertEquals("bar", arg1.getName());
assertEquals("bar", arg1.toString());
assertNull(arg1.getType());
ASArg arg2 = (ASArg)args.get(2);
arg2.setType("*");
assertEquals("*", arg2.getType());
assertEquals("bar", meth.removeParam("bar").getName());
assertEquals(2, meth.getArgs().size());
assertNull(meth.removeParam("missing"));
assertEquals(2, meth.getArgs().size());
ASCompilationUnit unit2 = CodeMirror.assertReflection(fact, unit);
ASClassType type2 = (ASClassType)unit2.getType();
ASMethod meth2 = type2.getMethod("test");
List args2 = meth2.getArgs();
ASArg bar2 = (ASArg)args2.get(1);
assertEquals("blat", bar2.getName());
assertEquals("*", bar2.getType());
}
public void testRemoveLastParameter() {
meth.addParam("foo", "Number");
meth.addRestParam("bar");
meth.removeParam("bar");
assertEquals(1, meth.getArgs().size());
}
public void testRestParameter() {
ASArg foo = meth.addParam("foo", "Number");
assertFalse(foo.isRest());
ASArg bar = meth.addRestParam("bar");
assertTrue(bar.isRest());
meth.removeParam("bar");
assertEquals(1, meth.getArgs().size());
ASArg rest = meth.addRestParam("..."); // no name
assertEquals("...", rest.getName());
meth.removeParam("...");
assertEquals(1, meth.getArgs().size());
rest = meth.addRestParam("...");
try {
rest.setDefault("12");
fail("should not have been able to set a default value for a 'rest' parameter");
} catch (SyntaxException e) {
// expected
}
assertEquals(2, meth.getArgs().size());
}
public void testDocComment() {
String comment = "foo\n bar";
meth.setDocComment(comment);
assertEquals(comment, meth.getDocComment());
}
}