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

http://ambienttalk.googlecode.com/ · Java · 185 lines · 96 code · 29 blank · 60 comment · 0 complexity · badec150755be6cbabc7072a1e898770 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.XImportConflict;
  6. import edu.vub.at.objects.natives.grammar.AGBegin;
  7. import edu.vub.at.objects.natives.grammar.AGImport;
  8. import edu.vub.at.objects.natives.grammar.AGSelf;
  9. import edu.vub.at.objects.natives.grammar.AGSymbol;
  10. /**
  11. * @author tvcutsem
  12. *
  13. * The unit test LexicalRootTest tests globally visible methods in the lexical root.
  14. *
  15. * TODO: finish me
  16. */
  17. public class LexicalRootTest extends AmbientTalkTest {
  18. public static void main(String[] args) {
  19. junit.swingui.TestRunner.run(LexicalRootTest.class);
  20. }
  21. //private OBJLexicalRoot root_ = (OBJLexicalRoot) OBJLexicalRoot.getGlobalLexicalScope().lexicalParent_;
  22. public void testLexicalRootFields() {
  23. evalAndCompareTo("nil", OBJNil._INSTANCE_);
  24. evalAndCompareTo("true", NATBoolean._TRUE_);
  25. evalAndCompareTo("false", NATBoolean._FALSE_);
  26. evalAndCompareTo("/", Evaluator.getLobbyNamespace());
  27. }
  28. private NATObject trait_;
  29. public static final AGSymbol atX_ = AGSymbol.jAlloc("x");
  30. public static final AGSymbol atM_ = AGSymbol.jAlloc("m");
  31. public static final AGSymbol atN_ = AGSymbol.jAlloc("n");
  32. /**
  33. * Initialize the trait used for testing import:
  34. *
  35. * def parent := object: { def n() { nil }; def m() { nil } }
  36. * def trait := extend: parent with: {
  37. * def x := 0;
  38. * def m() { self }
  39. * }
  40. */
  41. public void setUp() throws Exception {
  42. super.setUp();
  43. NATObject parent = new NATObject();
  44. parent.meta_addMethod(new NATMethod(atN_, NATTable.EMPTY, new AGBegin(NATTable.of(OBJNil._INSTANCE_))));
  45. parent.meta_addMethod(new NATMethod(atM_, NATTable.EMPTY, new AGBegin(NATTable.of(OBJNil._INSTANCE_))));
  46. trait_ = new NATObject(parent, Evaluator.getGlobalLexicalScope(), NATObject._IS_A_);
  47. trait_.meta_defineField(atX_, NATNumber.ZERO);
  48. trait_.meta_addMethod(new NATMethod(atM_,
  49. NATTable.EMPTY,
  50. new AGBegin(NATTable.of(AGSelf._INSTANCE_))));
  51. }
  52. /**
  53. * Tests whether a basic import of fields and methods from a
  54. * 'trait' object into a 'host' object works properly.
  55. */
  56. public void testBasicImport() throws InterpreterException {
  57. // def host := object: { def test() { x } }
  58. NATObject host = new NATObject();
  59. AGSymbol atTest = AGSymbol.jAlloc("test");
  60. // test method accesses 'x' unqualified
  61. host.meta_addMethod(new NATMethod(atTest, NATTable.EMPTY,
  62. new AGBegin(NATTable.of(atX_))));
  63. // < import trait > . eval(ctx[lex=host;self=host])
  64. new AGImport(trait_, NATTable.EMPTY, NATTable.EMPTY).meta_eval(new NATContext(host, host));
  65. // check whether host contains the appropriate fields and methods of the traits
  66. assertTrue(host.meta_respondsTo(atX_).asNativeBoolean().javaValue);
  67. assertTrue(host.meta_respondsTo(atM_).asNativeBoolean().javaValue);
  68. // check whether the methods and fields of the parents of traits are also present
  69. assertTrue(host.meta_respondsTo(atN_).asNativeBoolean().javaValue);
  70. // ensure that 'self' is correctly late bound to host when invoking m()
  71. assertEquals(host, host.meta_invoke(host, atM_, NATTable.EMPTY));
  72. // when invoking m() directly on the trait, self should be bound to the trait
  73. assertEquals(trait_, trait_.meta_invoke(trait_, atM_, NATTable.EMPTY));
  74. // when someone delegates m() to host, the trait's self should be bound to the original delegator
  75. NATObject delegator = new NATObject();
  76. assertEquals(delegator, host.meta_invoke(delegator, atM_, NATTable.EMPTY));
  77. // ensure that when invoking test() on host, it can access x unqualified
  78. assertEquals(NATNumber.ZERO, host.meta_invoke(host, atTest, NATTable.EMPTY));
  79. // when assigning x in host, trait's x field should not be modified
  80. host.meta_invoke(host, atX_.asAssignmentSymbol(), NATTable.of(NATNumber.ONE));
  81. assertEquals(NATNumber.ZERO, trait_.impl_invokeAccessor(trait_, atX_, NATTable.EMPTY));
  82. // host's primitive methods should be left untouched, i.e.
  83. // host != trait and host == host
  84. assertTrue(host.meta_invoke(host, NATObject._EQL_NAME_, NATTable.of(host)).asNativeBoolean().javaValue);
  85. assertFalse(host.meta_invoke(host, NATObject._EQL_NAME_, NATTable.of(trait_)).asNativeBoolean().javaValue);
  86. }
  87. /**
  88. * Tests whether conflicts are successfully detected.
  89. */
  90. public void testConflictingImport() throws InterpreterException {
  91. NATObject host = new NATObject();
  92. // host defines x itself, so import should fail
  93. host.meta_defineField(atX_, NATNumber.ONE);
  94. try {
  95. // < import trait > . eval(ctx[lex=host;self=host])
  96. new AGImport(trait_, NATTable.EMPTY, NATTable.EMPTY).meta_eval(new NATContext(host, host));
  97. fail("Expected an XImportConflict exception");
  98. } catch (XImportConflict e) {
  99. assertEquals(atX_, e.getConflictingNames().base_at(NATNumber.ONE));
  100. }
  101. }
  102. /**
  103. * Tests whether traits can be transitively imported into objects.
  104. */
  105. public void testTransitiveImport() throws InterpreterException {
  106. NATObject hostA = new NATObject();
  107. NATObject hostB = new NATObject();
  108. // < import trait > . eval(ctx[lex=hostA;self=hostA])
  109. new AGImport(trait_, NATTable.EMPTY, NATTable.EMPTY).meta_eval(new NATContext(hostA, hostA));
  110. // < import trait > . eval(ctx[lex=hostB;self=hostB])
  111. new AGImport(trait_, NATTable.EMPTY, NATTable.EMPTY).meta_eval(new NATContext(hostB, hostB));
  112. // check whether m() can be invoked from hostB and that self equals hostB
  113. assertEquals(hostB, hostB.meta_invoke(hostB, atM_, NATTable.EMPTY));
  114. }
  115. /**
  116. * Tests whether aliasing works properly.
  117. */
  118. public void testImportAndAliasing() throws InterpreterException {
  119. NATObject host = new NATObject();
  120. AGSymbol foo = AGSymbol.jAlloc("foo");
  121. NATTable alias = NATTable.of(NATTable.of(atM_, foo)); // [[m,foo]]
  122. // < import trait alias m := foo > . eval(ctx[lex=host;self=host])
  123. new AGImport(trait_, alias, NATTable.EMPTY).meta_eval(new NATContext(host, host));
  124. // check whether m() can be invoked as foo()
  125. assertTrue(host.meta_respondsTo(foo).asNativeBoolean().javaValue);
  126. assertEquals(host, host.meta_invoke(host, foo, NATTable.EMPTY));
  127. }
  128. /**
  129. * Tests whether exclusion works properly.
  130. */
  131. public void testImportAndExclusion() throws InterpreterException {
  132. NATObject host = new NATObject();
  133. NATTable exclude = NATTable.of(atN_);
  134. // < import trait exclude n > . eval(ctx[lex=host;self=host])
  135. new AGImport(trait_, NATTable.EMPTY, exclude).meta_eval(new NATContext(host, host));
  136. // check whether m is present and n is not present
  137. assertTrue(host.meta_respondsTo(atM_).asNativeBoolean().javaValue);
  138. assertFalse(host.meta_respondsTo(atN_).asNativeBoolean().javaValue);
  139. }
  140. /**
  141. * Tests whether aliasing and exclusion work properly together.
  142. */
  143. public void testImportAndAliasingAndExclusion() throws InterpreterException {
  144. NATObject host = new NATObject();
  145. AGSymbol foo = AGSymbol.jAlloc("foo");
  146. NATTable alias = NATTable.of(NATTable.of(atM_, foo)); // [[m,foo]]
  147. NATTable exclude = NATTable.of(atN_);
  148. // < import trait alias m := foo exclude n> . eval(ctx[lex=host;self=host])
  149. new AGImport(trait_, alias, exclude).meta_eval(new NATContext(host, host));
  150. // check whether m() can be invoked as foo()
  151. assertTrue(host.meta_respondsTo(foo).asNativeBoolean().javaValue);
  152. assertEquals(host, host.meta_invoke(host, foo, NATTable.EMPTY));
  153. // check whether n is not present
  154. assertFalse(host.meta_respondsTo(atN_).asNativeBoolean().javaValue);
  155. }
  156. }