package st.gravel.support.compiler;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import st.gravel.support.compiler.testtools.ClassBuilder;
import st.gravel.support.compiler.testtools.TestBootstrap;
import st.gravel.support.jvm.runtime.ImageBootstrapper;
public class BlockTest {
@Before
public void setUp() {
TestBootstrap.getSingleton();
}
@Test
public void testBooleanAnd() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testBooleanAnd").method(
"foo: a bar: b ^a and: [b]").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_bar_", Object.class, Object.class);
assertEquals(Boolean.TRUE, method.invoke(fooObject, true, true));
assertEquals(Boolean.FALSE, method.invoke(fooObject, true, false));
assertEquals(Boolean.FALSE, method.invoke(fooObject, false, true));
assertEquals(Boolean.FALSE, method.invoke(fooObject, false, false));
}
@Test
public void testBooleanOr() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testBooleanOr").method(
"foo: a bar: b ^a or: [b]").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_bar_", Object.class, Object.class);
assertEquals(Boolean.TRUE, method.invoke(fooObject, true, true));
assertEquals(Boolean.TRUE, method.invoke(fooObject, true, false));
assertEquals(Boolean.TRUE, method.invoke(fooObject, false, true));
assertEquals(Boolean.FALSE, method.invoke(fooObject, false, false));
}
@Test
public void testEmptyBlockReturnsNil() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testEmptyBlockReturnsNil").method(
"foo ^[] value").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo");
assertEquals(null, method.invoke(fooObject));
}
@Test
public void testCleanBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject").method(
"foo: bar\n" + " | block |\n" + " block := [:a | a + 4].\n"
+ " ^block value: bar").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(7), method.invoke(fooObject, 3));
}
@Test
public void testTwoArgCleanBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testTwoArgCleanBlock").method(
"foo: foo bar: bar\n" + " | block |\n" + " block := [:a :b| a + b].\n"
+ " ^block value: foo value: bar").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_bar_", Object.class, Object.class);
assertEquals(Integer.valueOf(7), method.invoke(fooObject, 3, 4));
}
@Test
public void testCopyingBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testCopyingBlock")
.method("foo: bar\n" + " | block |\n"
+ " block := [:a | a + bar].\n" + " ^block value: 4")
.build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(7), method.invoke(fooObject, 3));
}
@Test
public void testCopyingBlockWithSelfReference()
throws NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testCopyingBlockWithSelfReference")
.method("foo ^11")
.method("foo: bar\n" + " | block |\n"
+ " block := [:a | a + bar + self foo].\n"
+ " ^block value: 4").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(18), method.invoke(fooObject, 3));
}
@Test
public void testFullBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testFullBlock")
.method("foo: bar\n" + " | block |\n" + " block := [^1].\n"
+ " bar ifFalse: [block value].\n" + " ^2").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(2), method.invoke(fooObject, true));
assertEquals(Integer.valueOf(1), method.invoke(fooObject, false));
}
@Test
public void testFullCopyingBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testFullCopyingBlock").method(
"foo: bar\n" + " | block a |\n" + " a := 1.\n"
+ " block := [^a].\n"
+ " bar ifFalse: [block value].\n" + " ^2").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(2), method.invoke(fooObject, true));
assertEquals(Integer.valueOf(1), method.invoke(fooObject, false));
}
@Test
public void testReadOuterTemp1() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testReadOuterTemp1").method(
"foo: bar\n" + "| a ar aw |\n" + "a := 0.\n"
+ "ar := [a + 7].\n" + "a := bar. \n" + "^ar value")
.build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(9), method.invoke(fooObject, 2));
assertEquals(Integer.valueOf(8), method.invoke(fooObject, 1));
}
@Test
public void testReadWriteOuterTemp() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testReadWriteOuterTemp").method(
"foo: bar\n" + "| a ar aw |\n" + "a := 0.\n" + "ar := [a].\n"
+ "aw := [:x | a := x + 7].\n" + "aw value: bar. \n"
+ "^ar value").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(9), method.invoke(fooObject, 2));
assertEquals(Integer.valueOf(8), method.invoke(fooObject, 1));
}
@Test
public void testReadWriteOuterTempDoubleNested()
throws NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testReadWriteOuterTempDoubleNested").method(
"foo: bar\n" + "| a ar aw |\n" + "a := 0.\n"
+ "ar := [[a] value].\n"
+ "aw := [:x | [:y | a := y + 7] value: x].\n"
+ "aw value: bar. \n" + "^ar value").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(9), method.invoke(fooObject, 2));
assertEquals(Integer.valueOf(8), method.invoke(fooObject, 1));
}
@Test
public void testNestedReturn() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testNestedReturn")
.method("foo: bar\n" + "| a ar aw |\n" + "a := 0.\n"
+ "ar := [[^a] value].\n"
+ "aw := [:x | [:y | a := y + 7] value: x].\n"
+ "aw value: bar. \n" + "^ar value").build();
Object fooObject = stClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals(Integer.valueOf(9), method.invoke(fooObject, 2));
assertEquals(Integer.valueOf(8), method.invoke(fooObject, 1));
}
@Test
public void testReadWriteInstVar() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder("FooObject_testReadWriteInstVar")
.method("foo: bar\n" + "bar name: 'Fromage'.\n" + "^bar name")
.build();
Class barClass = new ClassBuilder("BarObject_testReadWriteInstVar")
.method("name: aString name := aString").method("name ^name")
.instVar("name").build();
Object fooObject = stClass.newInstance();
Object barObject = barClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals("Fromage", method.invoke(fooObject, barObject));
}
@Test
public void testReadWriteInstVarInBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testReadWriteInstVarInBlock").method(
"foo: bar\n" + "bar setNameInBlock: 'Fromage'.\n"
+ "^bar readNameInBlock").build();
Class barClass = new ClassBuilder(
"BarObject_testReadWriteInstVarInBlock")
.method("setNameInBlock: anObject\n"
+ " [name := anObject] value")
.method("readNameInBlock\n" + " ^[name] value").instVar("name")
.build();
Object fooObject = stClass.newInstance();
Object barObject = barClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals("Fromage", method.invoke(fooObject, barObject));
}
@Test
public void testReadWriteInstVarInNameBlock() throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class stClass = new ClassBuilder(
"FooObject_testReadWriteInstVarInNameBlock").method(
"foo: bar\n" + "|bl|\n" + "bl := bar nameBlock.\n"
+ "bar setNameInBlock: 'Fromage'.\n" + "^bl value")
.build();
Class barClass = new ClassBuilder(
"BarObject_testReadWriteInstVarInNameBlock")
.method("setNameInBlock: anObject\n"
+ " [name := anObject] value")
.method("nameBlock\n" + " ^[name]").instVar("name")
.build();
Object fooObject = stClass.newInstance();
Object barObject = barClass.newInstance();
Method method = fooObject.getClass().getMethod("foo_", Object.class);
assertEquals("Fromage", method.invoke(fooObject, barObject));
}
}