PageRenderTime 30ms CodeModel.GetById 14ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist041108/test/edu/vub/at/objects/natives/CustomFieldsTest.java

http://ambienttalk.googlecode.com/
Java | 138 lines | 82 code | 15 blank | 41 comment | 0 complexity | b4e5fe4200e41174d249bd969f877b4f MD5 | raw file
  1package edu.vub.at.objects.natives;
  2
  3import edu.vub.at.AmbientTalkTest;
  4import edu.vub.at.eval.Evaluator;
  5import edu.vub.at.exceptions.InterpreterException;
  6import edu.vub.at.exceptions.XDuplicateSlot;
  7import edu.vub.at.objects.ATObject;
  8import edu.vub.at.objects.coercion.NativeTypeTags;
  9import edu.vub.at.objects.natives.grammar.AGSymbol;
 10
 11/**
 12 * Tests custom fields that can be added to an object.
 13 * 
 14 * @author tvcutsem
 15 */
 16public class CustomFieldsTest extends AmbientTalkTest {
 17
 18	public static void main(String[] args) {
 19		junit.swingui.TestRunner.run(CustomFieldsTest.class);
 20	}
 21
 22	private NATObject testHost_;
 23	// a custom field that when set, increments the new value by 1
 24	private ATObject testField_;
 25	private AGSymbol foo_;
 26	
 27	// one-time setUp for all tests
 28	public void setUp() throws InterpreterException {
 29		// def testHost := object: { def x := 1 }
 30		testHost_ = new NATObject();
 31		testHost_.meta_defineField(AGSymbol.jAlloc("x"), NATNumber.ONE);
 32
 33		foo_ = AGSymbol.jAlloc("foo");
 34		
 35		ctx_.base_lexicalScope().meta_defineField(AGSymbol.jAlloc("Field"), NativeTypeTags._FIELD_);
 36		testField_ = evalAndReturn(
 37				"object: { def name := `foo;" +
 38				          "def host := nil; def init(newhost) { host := newhost; };" +
 39				          "def v := nil;" +
 40				          "def readField() { v };" +
 41				          "def writeField(n) { v := n+1 } } taggedAs: [ Field ]");
 42	}
 43	
 44	/**
 45	 * Tests whether a custom field can be added to a native object
 46	 */
 47	public void testCustomFieldAddition() throws Exception {
 48		assertNull(testHost_.customFields_);
 49		// (reflect: testHost).addField(testField)
 50		testHost_.meta_addField(testField_.asField());
 51		assertNotNull(testHost_.customFields_);
 52		assertEquals(1, testHost_.customFields_.size());
 53		assertTrue(testHost_.meta_respondsTo(foo_).asNativeBoolean().javaValue);
 54		ATObject foo = testHost_.meta_grabField(foo_);
 55		assertEquals(testHost_, foo.impl_invokeAccessor(foo, AGSymbol.jAlloc("host"), NATTable.EMPTY));
 56	}
 57	
 58	/**
 59	 * Tests whether a custom field can be read via readField
 60	 */
 61	public void testCustomFieldRead() throws Exception {
 62		testHost_.meta_addField(testField_.asField());
 63		assertEquals(Evaluator.getNil(), testHost_.impl_invokeAccessor(testHost_, foo_, NATTable.EMPTY));
 64	}
 65
 66	/**
 67	 * Tests whether a custom field can be written via writeField
 68	 */
 69	public void testCustomFieldWrite() throws Exception {
 70		testHost_.meta_addField(testField_.asField());
 71		// testHost.foo := 1
 72		assertEquals(NATNumber.atValue(1),
 73				     testHost_.impl_invoke(testHost_, foo_.asAssignmentSymbol(), NATTable.of(NATNumber.ONE)));
 74		// testHost.foo == 2
 75		assertEquals(NATNumber.atValue(2), testHost_.impl_invokeAccessor(testHost_, foo_, NATTable.EMPTY));
 76	}
 77	
 78	/**
 79	 * Tests that duplicate slots are still trapped, even with custom fields
 80	 */
 81	public void testCustomDuplicate() throws Exception {
 82		testHost_.meta_addField(testField_.asField());
 83		try {
 84			// try to add a native field for which a custom one is already defined
 85			testHost_.meta_defineField(foo_, NATNumber.ONE);
 86			fail("expected a duplicate slot exception");
 87		} catch (XDuplicateSlot e) {
 88			// expected exception: success
 89		}
 90		try {
 91			// try to add a custom field for which another custom one is already defined
 92			testHost_.meta_addField(testField_.meta_clone().asField());
 93			fail("expected a duplicate slot exception");
 94		} catch (XDuplicateSlot e) {
 95			// expected exception: success
 96		}
 97	}
 98	
 99	/**
100	 * Tests whether custom fields appear in the listFields table
101	 */
102	public void testFieldListing() throws Exception {
103		testHost_.meta_addField(testField_.meta_clone().asField());
104		assertEquals(3, testHost_.meta_listFields().base_length().asNativeNumber().javaValue);
105	}
106	
107	/**
108	 * Tests whether the fields of clones are properly re-initialized
109	 */
110	public void testCloneFieldReinit() throws Exception {
111		testHost_.meta_addField(testField_.meta_clone().asField());
112		// set foo field of testHost to 1 -> testHost_.foo := 1
113		testHost_.impl_invoke(testHost_, foo_.asAssignmentSymbol(), NATTable.of(NATNumber.ONE));
114		ATObject clone = testHost_.meta_clone();
115		// set foo field of clone to 55 -> clone.foo := 55
116		clone.impl_invoke(clone, foo_.asAssignmentSymbol(), NATTable.of(NATNumber.atValue(55)));
117		// check whether original foo field of testHost is not modified (remember: writeField increments with + 1)
118		assertEquals(2, testHost_.impl_invokeAccessor(testHost_, foo_, NATTable.EMPTY).asNativeNumber().javaValue);
119	}
120	
121	/**
122	 * Tests whether native fields added to another object are not added as custom fields,
123	 * but again as native fields
124	 */
125	public void testNativeFieldAdd() throws Exception {
126		testHost_.meta_addField(testField_.meta_clone().asField());
127		NATObject empty = new NATObject();
128		assertNull(empty.customFields_);
129		empty.meta_addField(testHost_.meta_grabField(AGSymbol.jAlloc("x")));
130		assertNull(empty.customFields_);
131		assertEquals(testHost_.impl_invokeAccessor(testHost_, AGSymbol.jAlloc("x"), NATTable.EMPTY),
132				empty.impl_invokeAccessor(empty, AGSymbol.jAlloc("x"), NATTable.EMPTY));
133		// only when custom fields are added does the customFields_ list grow
134		empty.meta_addField(testHost_.meta_grabField(foo_));
135		assertNotNull(empty.customFields_);
136	}
137	
138}