home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / TCL / ITCL / _ITCL.TAR / usr / lib / itcl / tests / inherit.test < prev    next >
Encoding:
Text File  |  1994-04-08  |  8.2 KB  |  289 lines

  1. #
  2. # Tests for inheritance and scope handling
  3. # ----------------------------------------------------------------------
  4. #   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
  5. #            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
  6. #
  7. #      RCS:  inherit.test,v 1.3 1994/04/08 13:40:20 mmc Exp
  8. # ----------------------------------------------------------------------
  9. #               Copyright (c) 1993  AT&T Bell Laboratories
  10. # ======================================================================
  11. # Permission to use, copy, modify, and distribute this software and its
  12. # documentation for any purpose and without fee is hereby granted,
  13. # provided that the above copyright notice appear in all copies and that
  14. # both that the copyright notice and warranty disclaimer appear in
  15. # supporting documentation, and that the names of AT&T Bell Laboratories
  16. # any of their entities not be used in advertising or publicity
  17. # pertaining to distribution of the software without specific, written
  18. # prior permission.
  19. #
  20. # AT&T disclaims all warranties with regard to this software, including
  21. # all implied warranties of merchantability and fitness.  In no event
  22. # shall AT&T be liable for any special, indirect or consequential
  23. # damages or any damages whatsoever resulting from loss of use, data or
  24. # profits, whether in an action of contract, negligence or other
  25. # tortuous action, arising out of or in connection with the use or
  26. # performance of this software.
  27. # ======================================================================
  28.  
  29. # ----------------------------------------------------------------------
  30. #  MULTIPLE BASE-CLASS ERROR DETECTION
  31. # ----------------------------------------------------------------------
  32. test {Cannot inherit from the same base class more than once} {
  33.     catch "VirtualErr" errmsg
  34.     set errmsg
  35. } {
  36.     $result == {error while autoloading "VirtualErr": class "VirtualErr" inherits base class "Foo" more than once:
  37.   VirtualErr->Mongrel->FooBar->Foo
  38.   VirtualErr->Foo
  39.   VirtualErr->BarFoo->Foo}
  40. }
  41.  
  42. # ----------------------------------------------------------------------
  43. #  CONSTRUCTION
  44. # ----------------------------------------------------------------------
  45. test {Constructors should be invoked implicitly} {
  46.     set WATCH ""
  47.     concat [Mongrel m] / $WATCH
  48. } {
  49.     $result == "m / Mongrel FooBar Foo Bar Geek"
  50. }
  51.  
  52. test {Initialization of shadowed variables works properly} {
  53.     concat [m info public blit -value] / [m info public Foo::blit -value]
  54. } {
  55.     $result == "nonnull / <undefined>"
  56. }
  57.  
  58. # ----------------------------------------------------------------------
  59. #  PUBLIC VARIABLES
  60. # ----------------------------------------------------------------------
  61. test {Inherited "config" method works on derived classes} {
  62.     m config -blit xyz -Foo::blit pdq
  63. } {
  64.     $result == "Mongrel::blit Foo::blit"
  65. }
  66.  
  67. test {Inherited "config" method works on derived classes} {
  68.     m config -blit xyz -Foo::blit pdq
  69.     concat [m info public blit -value] / [m info public Foo::blit -value]
  70. } {
  71.     $result == "xyz / pdq"
  72. }
  73.  
  74. test {Inherited "config" method works on derived classes} {
  75.     m config -tag #0000
  76. } {
  77.     $result == "Mongrel::tag"
  78. }
  79.  
  80. # ----------------------------------------------------------------------
  81. #  INHERITANCE INFO
  82. # ----------------------------------------------------------------------
  83. test {Info: class} {
  84.     m info class
  85. } {
  86.     $result == "Mongrel"
  87. }
  88.  
  89. test {Info: inherit} {
  90.     m info inherit
  91. } {
  92.     $result == "FooBar Geek"
  93. }
  94.  
  95. test {Info: heritage} {
  96.     m info heritage
  97. } {
  98.     $result == "Mongrel FooBar Foo Bar Geek"
  99. }
  100.  
  101. test {Built-in "isa" method} {
  102.     set status 1
  103.     foreach c [m info heritage] {
  104.         set status [expr {$status && [m isa $c]}]
  105.     }
  106.     set status
  107. } {
  108.     $result == 1
  109. }
  110.  
  111. test {Built-in "isa" method} {
  112.     m isa Watermelon
  113. } {
  114.     $result == 0
  115. }
  116.  
  117. # ----------------------------------------------------------------------
  118. #  SCOPE MANIPULATION
  119. # ----------------------------------------------------------------------
  120. test {commands normally execute in the scope of their class} {
  121.     m Foo::do {info class}
  122. } {
  123.     $result == "Foo says 'Foo'"
  124. }
  125.  
  126. test {"virtual" command moves scope to most specific class} {
  127.     m Foo::do {virtual info class}
  128. } {
  129.     $result == "Foo says 'Mongrel'"
  130. }
  131.  
  132. test {"previous" command moves scope upward in hierarchy} {
  133.     m do {virtual previous info class}
  134. } {
  135.     $result == "Foo says 'FooBar'"
  136. }
  137.  
  138. test {"previous" command can be chained} {
  139.     m do {virtual previous previous info class}
  140. } {
  141.     $result == "Foo says 'Foo'"
  142. }
  143.  
  144. # ----------------------------------------------------------------------
  145. #  METHOD INVOCATION
  146. # ----------------------------------------------------------------------
  147. test {Simple method names are assigned based on heritage} {
  148.     m do {concat "$this ([virtual info class]) at scope [info class]::"}
  149. } {
  150.     $result == "Foo says 'm (Mongrel) at scope Foo::'"
  151. }
  152.  
  153. test {Explicit scoping can be used to reach shadowed members} {
  154.     m Geek::do {concat "$this ([virtual info class]) at scope [info class]::"}
  155. } {
  156.     $result == "Geek says 'm (Mongrel) at scope Geek::'"
  157. }
  158.  
  159. test {Methods execute in local scope of class, e.g., Foo::do} {
  160.     m config -blit abc -Foo::blit def
  161.     m Foo::do {set blit xyz}
  162.     concat [m info public blit -value] / [m info public Foo::blit -value]
  163. } {
  164.     $result == "abc / xyz"
  165. }
  166.  
  167. # ----------------------------------------------------------------------
  168. #  DESTRUCTION
  169. # ----------------------------------------------------------------------
  170. test {Destructors should be invoked implicitly} {
  171.     set WATCH ""
  172.     concat [m delete] / $WATCH
  173. } {
  174.     $result == "/ Mongrel Geek Bar Foo FooBar"
  175. }
  176.  
  177. # ----------------------------------------------------------------------
  178. #  OBJECT INFO
  179. # ----------------------------------------------------------------------
  180. foreach obj [itcl_info objects] {
  181.     $obj delete
  182. }
  183. Mongrel m
  184. FooBar fb
  185. Foo f
  186. Geek g
  187.  
  188. test {Object queries can be restricted by object name} {
  189.     itcl_info objects f*
  190. } {
  191.     [test_cmp_lists $result {f fb}]
  192. }
  193.  
  194. test {Object queries can be restricted to specific classes} {
  195.     itcl_info objects -class Foo
  196. } {
  197.     $result == "f"
  198. }
  199.  
  200. test {Object queries can be restricted by object heritage} {
  201.     itcl_info objects -isa Foo
  202. } {
  203.     [test_cmp_lists $result {m f fb}]
  204. }
  205.  
  206. test {Object queries can be restricted by object name / specific classes} {
  207.     itcl_info objects f* -class Foo
  208. } {
  209.     $result == "f"
  210. }
  211.  
  212. test {Object queries can be restricted by object name / object heritage} {
  213.     itcl_info objects f* -isa Foo
  214. } {
  215.     [test_cmp_lists $result {f fb}]
  216. }
  217.  
  218. # ----------------------------------------------------------------------
  219. #  ERROR HANDLING ACROSS CLASS BOUNDARIES
  220. # ----------------------------------------------------------------------
  221. Mongrel m1
  222. FooBar fb2
  223.  
  224. test {Errors and detected and reported across class boundaries} {
  225.     set status [catch {m1 do {fb2 do {error "test"}}} mesg]
  226.     format "$mesg $status"
  227. } {
  228.     $result == "test 1"
  229. }
  230.  
  231. test {Stack trace unwinds properly across class boundaries} {
  232.     catch {m1 do {fb2 do {error "test"}}} mesg
  233.     format "$errorInfo"
  234. } {
  235.     $result == {test
  236.     while executing
  237. "error "test""
  238.     ("eval" body line 1)
  239.     invoked from within
  240. "eval $cmds"
  241.     invoked from within
  242. "return "Foo says '[eval $cmds]..."
  243.     (object "fb2" method "FooBar::do" body line 2)
  244.     invoked from within
  245. "fb2 do {error "test"}"
  246.     invoked from within
  247. "fb2 do {error "test"}"
  248.     ("eval" body line 1)
  249.     invoked from within
  250. "eval $cmds"
  251.     invoked from within
  252. "return "Foo says '[eval $cmds]..."
  253.     (object "m1" method "Mongrel::do" body line 2)
  254.     invoked from within
  255. "m1 do {fb2 do {error "test"}}"}
  256. }
  257.  
  258. test {Stack trace unwinds properly across class boundaries} {
  259.     catch {m1 do {fb2 do {error "test" "some error"}}} mesg
  260.     format "$errorInfo"
  261. } {
  262.     $result == {some error
  263.     ("eval" body line 2)
  264.     invoked from within
  265. "eval $cmds"
  266.     invoked from within
  267. "return "Foo says '[eval $cmds]..."
  268.     (object "fb2" method "FooBar::do" body line 2)
  269.     invoked from within
  270. "fb2 do {error "test" "some error"}"
  271.     invoked from within
  272. "fb2 do {error "test" "some error"}"
  273.     ("eval" body line 1)
  274.     invoked from within
  275. "eval $cmds"
  276.     invoked from within
  277. "return "Foo says '[eval $cmds]..."
  278.     (object "m1" method "Mongrel::do" body line 2)
  279.     invoked from within
  280. "m1 do {fb2 do {error "test" "some error"}}"}
  281. }
  282.  
  283. test {Error codes are preserved across class boundaries} {
  284.     catch {m1 do {fb2 do {error "test" "some error" CODE-BLUE}}} mesg
  285.     format "$errorCode"
  286. } {
  287.     $result == "CODE-BLUE"
  288. }
  289.