/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

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