/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

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