/interpreter/tags/at2-build270707/test/edu/vub/at/objects/natives/CustomFieldsTest.java
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}