/interpreter/tags/at2-build270707/test/edu/vub/at/objects/symbiosis/CoercionTest.java
Java | 98 lines | 51 code | 14 blank | 33 comment | 0 complexity | 1f83abc5af4aa50554ec5dceadf2c3ba MD5 | raw file
1/** 2 * 3 */ 4package edu.vub.at.objects.symbiosis; 5 6import edu.vub.at.AmbientTalkTest; 7import edu.vub.at.exceptions.InterpreterException; 8import edu.vub.at.objects.ATObject; 9import edu.vub.at.objects.ATTable; 10import edu.vub.at.objects.base.BaseClosure; 11import edu.vub.at.objects.coercion.Coercer; 12import edu.vub.at.objects.natives.NATNumber; 13import edu.vub.at.objects.natives.NATTable; 14import edu.vub.at.objects.natives.OBJNil; 15import edu.vub.at.objects.natives.grammar.AGSymbol; 16 17/** 18 * Tests the coercion of both objects and native data types to an interface. The use of coercion is required not 19 * only to absorb AmbientTalk objects and use them instead of native types (i.e. passing an object with at and 20 * atPut methods where a table is expected) but is also used to ensure the proper use of AmbientTalk objects 21 * which are passed outside their enclosing actor and handed to another Java thread. 22 * 23 * @author smostinc 24 */ 25public class CoercionTest extends AmbientTalkTest { 26 27 public static void main(String[] args) { 28 junit.swingui.TestRunner.run(CoercionTest.class); 29 } 30 31 /** 32 * Tests the coercion of an AmbientTalk object which is to be used as a native table type. 33 */ 34 public void testTypeCoercion() throws InterpreterException { 35 ATObject cubbyhole = evalAndReturn( 36 "def cubbyhole := object: { \n" + 37 " def content := nil; \n" + 38 " def at(i) { \n" + 39 " if: (i = 1) then: { content } else: { `error }; \n" + 40 " }; \n" + 41 " def atPut(i, val) { \n" + 42 " if: (i = 1) then: { content := val } else: { `error }; \n" + 43 " }; \n" + 44 "} \n"); 45 46 // under normal circumstances the cubbyhole object would be implicitly coerced to a table once it is 47 // passed to a function which expects a table as an argument. Here we explicitly coerce by performing 48 // such an invocation at the Java level. 49 50 ATTable coercedCubbyhole = (ATTable)Coercer.coerce(cubbyhole, ATTable.class); 51 ATObject result = coercedCubbyhole.base_at(NATNumber.ONE); 52 53 assertEquals(OBJNil._INSTANCE_, result); 54 } 55 56 /** 57 * Tests the coercion of an AmbientTalk object onto a classical Java Interface for symbiotic use. 58 * Such coercions typically happen when passing an AmbientTalk object to a Java method which expects 59 * a given interface. At that point in time the passed AmbientTalk object will be implictly coerced 60 * to the requested type. 61 */ 62 public void testSymbioticCoercion() throws InterpreterException { 63 ATObject listener = evalAndReturn( 64 "def result := `error;" + 65 "def listener := object: { \n" + 66 " def run() { result := `ok; }; \n" + 67 "}; \n"); 68 69 Runnable coercedListener = (Runnable)Coercer.coerce(listener, Runnable.class); 70 coercedListener.run(); 71 72 ATObject result = evalAndReturn("result"); 73 assertEquals(AGSymbol.jAlloc("ok"), result); 74 } 75 76 /** 77 * Tests the coercion of an AmbientTalk native type onto a Java Interface corresponding to its base-level 78 * interface for symbiotic use. The reason to support this is that coercion ensures that invoking a method 79 * respects the event loop concurrency properties of AmbientTalk actors. 80 * <p> 81 * Hence, the difference between <closure:lambda>.base_apply([]) and <coercer on:<closure:lambda> >.apply([]) 82 * is that is the latter is called from a separate Java thread, it will schedule a message in the owning 83 * actor's queue whereas the latter would proceed and thus activate a second thread within the boundaries 84 * of a single actor. 85 */ 86 public void testSymbioticNativeCoercion() throws InterpreterException { 87 ATObject lambda = evalAndReturn( 88 "def result := `error;" + 89 "def lambda := { result := `ok; }; \n"); 90 91 92 BaseClosure coercedListener = (BaseClosure)Coercer.coerce(lambda, BaseClosure.class); 93 coercedListener.apply(NATTable.EMPTY); 94 95 ATObject result = evalAndReturn("result"); 96 assertEquals(AGSymbol.jAlloc("ok"), result); 97 } 98}