PageRenderTime 66ms CodeModel.GetById 54ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2-build270707/test/edu/vub/at/objects/natives/CustomFieldsTest.java

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