PageRenderTime 87ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/Languages/Ruby/Tests/Runtime/Class/test_class_variables.rb

https://github.com/thomo13/ironruby
Ruby | 412 lines | 376 code | 21 blank | 15 comment | 35 complexity | 5429fea70a634ef9350062c6c8d3eaa0 MD5 | raw file
  1. # ****************************************************************************
  2. #
  3. # Copyright (c) Microsoft Corporation.
  4. #
  5. # This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. # copy of the license can be found in the License.html file at the root of this distribution. If
  7. # you cannot locate the Apache License, Version 2.0, please send an email to
  8. # ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. # by the terms of the Apache License, Version 2.0.
  10. #
  11. # You must not remove this notice, or any other, from this software.
  12. #
  13. #
  14. # ****************************************************************************
  15. require '../../util/simple_test.rb'
  16. # make class_variable_set and class_variable_get callable
  17. describe "Dynamic class variable methods" do
  18. skip "(BUG: private visibility is not working) class variable methods have correct visibility" do
  19. should_raise(NoMethodError, "private method `class_variable_get' called for Object:Class") do
  20. Object.class_variable_get :@@foo
  21. end
  22. should_raise(NoMethodError, "private method `class_variable_set' called for Object:Class") do
  23. Object.class_variable_set :@@foo, 'foo'
  24. end
  25. should_raise(NoMethodError, "private method `class_variable_get' called for Enumerable:Module") do
  26. Enumerable.class_variable_get :@@foo
  27. end
  28. should_raise(NoMethodError, "private method `class_variable_set' called for Enumerable:Module") do
  29. Enumerable.class_variable_set :@@foo, 'foo'
  30. end
  31. Object.class_variables.should == []
  32. Object.class_variable_defined?(:@@foo).should == false
  33. Enumerable.class_variables.should == []
  34. Enumerable.class_variable_defined?(:@@foo).should == false
  35. end
  36. it "class variable methods shouldn't exist on objects" do
  37. should_raise(NoMethodError) { Object.new.class_variable_get :@@foo }
  38. should_raise(NoMethodError) { Object.new.class_variable_set :@@foo, 'foo' }
  39. should_raise(NoMethodError) { Object.new.class_variables }
  40. should_raise(NoMethodError) { Object.new.class_variable_defined? :@@foo }
  41. end
  42. it "Module#class_variable_set, Module#class_variable_get" do
  43. # make the method visible
  44. class Module
  45. def class_var_get x
  46. class_variable_get x
  47. end
  48. def class_var_set x, v
  49. class_variable_set x, v
  50. end
  51. end
  52. class Bob
  53. def bar; @@foo = 200; end
  54. end
  55. should_raise(NameError, 'uninitialized class variable @@foo in Bob') { Bob.class_var_get(:@@foo) }
  56. Bob.class_variables.should == []
  57. Bob.class_var_set(:@@foo, 123).should == 123
  58. Bob.class_var_get('@@foo').should == 123
  59. Bob.class_variables.should == ['@@foo']
  60. Bob.class_variable_defined?(:@@foo).should == true
  61. Bob.class_var_set('@@foo', '654').should == '654'
  62. Bob.class_var_get(:@@foo).should == '654'
  63. end
  64. it "bad class variable names cause a name error" do
  65. should_raise(NameError) { Object.class_variable_defined?(:@iv) }
  66. should_raise(NameError) { Object.class_variable_defined?("@iv") }
  67. should_raise(NameError) { Object.class_variable_defined?(:iv) }
  68. should_raise(NameError) { Object.class_variable_defined?("iv") }
  69. should_raise(NameError) { Object.class_variable_defined?("@@iv@x") }
  70. should_raise(NameError) { Object.class_var_get(:@iv) }
  71. should_raise(NameError) { Object.class_var_get("@iv") }
  72. should_raise(NameError) { Object.class_var_get(:iv) }
  73. should_raise(NameError) { Object.class_var_get("iv") }
  74. should_raise(NameError) { Object.class_var_get("@@iv@x") }
  75. should_raise(NameError) { Object.class_var_set(:@iv, 10) }
  76. should_raise(NameError) { Object.class_var_set('CV', 10) }
  77. should_raise(NameError) { Object.class_var_set(:lv, 10) }
  78. end
  79. end
  80. describe "Class variables used inside a type" do
  81. it "basic usages inside the class" do
  82. class My_variables
  83. @@sv = 10
  84. def check_sv; @@sv; end
  85. def My_variables.check_sv; @@sv; end
  86. def My_variables.check_sv2; @@sv2; end
  87. end
  88. My_variables::check_sv.should == 10
  89. My_variables.check_sv.should == 10
  90. should_raise(NameError, 'uninitialized class variable @@sv2 in My_variables') { My_variables.check_sv2 }
  91. My_variables.class_variable_defined?(:@@sv).should == true
  92. My_variables.class_variable_defined?(:@@sv2).should == false
  93. x = My_variables.new
  94. should_raise(NoMethodError) { My_variables.sv }
  95. should_raise(NoMethodError) { My_variables::sv }
  96. x.check_sv.should == 10
  97. x.class.class_variables.should == ["@@sv"]
  98. x.class.class_var_get(:@@sv).should == 10
  99. end
  100. it "class variables are different from instance variables" do
  101. class My_variables2
  102. @@v = 555
  103. @v = 789
  104. def initialize
  105. @@v = 123
  106. @v = 456
  107. end
  108. def self.check_sv; @@v; end
  109. def self.check_iv; @v; end
  110. def check_sv; @@v; end
  111. def check_iv; @v; end
  112. end
  113. My_variables2.check_sv.should == 555
  114. My_variables2.check_iv.should == 789
  115. x = My_variables2.new
  116. x.check_sv.should == 123
  117. x.check_iv.should == 456
  118. x.class.check_sv.should == 123
  119. x.class.check_iv.should == 789
  120. My_variables2.class_variables.should == [ '@@v' ]
  121. end
  122. end
  123. describe "class variables are stored on the module/class where they are first set" do
  124. it "class variables show all variables in the base & mixins" do
  125. module Test1Module1
  126. def m1_a= x; @@a = x; end
  127. def m1_a; @@a; end
  128. end
  129. module Test1Module2
  130. def m2_b= x; @@b = x; end
  131. def m2_b; @@b; end
  132. end
  133. class Test1Class1
  134. include Test1Module1
  135. def c1_c= x; @@c = x; end
  136. def c1_c; @@c; end
  137. end
  138. class Test1Class2 < Test1Class1
  139. include Test1Module2
  140. def c2_d= x; @@d = x; end
  141. def c2_vars; [@@a, @@b, @@c, @@d]; end
  142. end
  143. Test1Class2.class_variables.should == []
  144. x = Test1Class2.new
  145. x.m1_a = 123
  146. x.m2_b = 456
  147. x.c1_c = 789
  148. x.c2_d = 555
  149. Test1Class2.class_variables.should == ["@@d", "@@b", "@@c", "@@a"]
  150. Test1Class1.class_variables.should == ["@@c", "@@a"]
  151. Test1Module1.class_variables.should == ["@@a"]
  152. Test1Module2.class_variables.should == ["@@b"]
  153. x.c2_vars.should == [123, 456, 789, 555]
  154. [x.m1_a, x.m2_b, x.c1_c].should == [123, 456, 789]
  155. end
  156. it "class variables stay where they are first set" do
  157. module Test2Module1
  158. def m1_a= x; @@a = x; end
  159. end
  160. module Test2Module2
  161. def m2_b= x; @@b = x; end
  162. end
  163. class Test2Class1
  164. include Test2Module1
  165. def c1_c= x; @@c = x; end
  166. end
  167. class Test2Class2 < Test2Class1
  168. include Test2Module2
  169. def c2_a= x; @@a = x; end
  170. def c2_b= x; @@b = x; end
  171. def c2_c= x; @@c = x; end
  172. def c2_d= x; @@d = x; end
  173. def c2_vars; [@@a, @@b, @@c, @@d]; end
  174. end
  175. Test2Class2.class_variables.should == []
  176. x = Test2Class2.new
  177. x.c2_a = 12.1
  178. x.c2_b = 34.3
  179. x.c2_c = 56.5
  180. x.c2_d = 78.8
  181. Test2Class2.class_variables.sort.should == ["@@a", "@@b", "@@c", "@@d"]
  182. x.c2_vars.should == [12.1, 34.3, 56.5, 78.8]
  183. Test2Class1.class_variables.should == []
  184. Test2Module1.class_variables.should == []
  185. Test2Module2.class_variables.should == []
  186. # now set the variables on the base class & included modules
  187. x.c1_c = 'testC1'
  188. Test2Class2.class_variables.sort.should == ["@@a", "@@b", "@@c", "@@d"]
  189. Test2Class1.class_variables.should == ['@@c']
  190. Test2Module1.class_variables.should == []
  191. Test2Module2.class_variables.should == []
  192. x.m1_a = 'testM1'
  193. Test2Class1.class_variables.should == ['@@c', '@@a']
  194. Test2Module1.class_variables.should == ['@@a']
  195. Test2Module2.class_variables.should == []
  196. x.m2_b = 'testM2'
  197. Test2Class1.class_variables.should == ['@@c', '@@a']
  198. Test2Module1.class_variables.should == ['@@a']
  199. Test2Module2.class_variables.should == ['@@b']
  200. x.c2_vars.should == [12.1, 34.3, 56.5, 78.8]
  201. Test2Module1.class_var_get('@@a').should == 'testM1'
  202. Test2Module2.class_var_get('@@b').should == 'testM2'
  203. Test2Class1.class_var_get('@@a').should == 'testM1'
  204. Test2Class1.class_var_get('@@c').should == 'testC1'
  205. end
  206. it "variables set on mixins or the super class can't be set only to the derived class" do
  207. module Test3Module1
  208. def m1_a= x; @@a = x; end
  209. def m1_a; @@a; end
  210. end
  211. module Test3Module2
  212. def m2_b= x; @@b = x; end
  213. def m2_b; @@b; end
  214. end
  215. class Test3Class1
  216. include Test3Module1
  217. def c1_c= x; @@c = x; end
  218. def c1_c; @@c; end
  219. end
  220. class Test3Class2 < Test3Class1
  221. include Test3Module2
  222. def c2_a= x; @@a = x; end
  223. def c2_b= x; @@b = x; end
  224. def c2_c= x; @@c = x; end
  225. def c2_d= x; @@d = x; end
  226. def c2_vars; [@@a, @@b, @@c, @@d]; end
  227. def c2_vars_a_b; [@@a, @@b]; end
  228. end
  229. Test3Class2.class_variables.should == []
  230. x = Test3Class2.new
  231. x.m1_a = 123
  232. x.m2_b = 456
  233. x.c2_vars_a_b.should == [123, 456]
  234. x.c1_c = 789
  235. x.c2_a = 'aaa'
  236. x.c2_vars_a_b.should == ['aaa', 456]
  237. x.c2_b = 'bbb'
  238. x.c2_c = 'ccc'
  239. x.c2_d = 'ddd'
  240. Test3Class2.class_variables.sort.should == ["@@a", "@@b", "@@c", "@@d"]
  241. Test3Class1.class_variables.should == ["@@c", "@@a"]
  242. Test3Module1.class_variables.should == ["@@a"]
  243. Test3Module2.class_variables.should == ["@@b"]
  244. x.c2_vars.should == ['aaa', 'bbb', 'ccc', 'ddd']
  245. [x.m1_a, x.m2_b, x.c1_c].should == ['aaa', 'bbb', 'ccc']
  246. end
  247. it 'class variables with same name' do
  248. module Test4Module1
  249. def m1_a= x; @@a = x; end
  250. def m1_a; @@a; end
  251. end
  252. module Test4Module2
  253. def m2_a= x; @@a = x; end
  254. def m2_a; @@a; end
  255. end
  256. class Test4Class1
  257. include Test4Module1
  258. def c1_a= x; @@a = x; end
  259. def c1_a; @@a; end
  260. end
  261. class Test4Class2 < Test4Class1
  262. include Test4Module2
  263. def c2_a= x; @@a = x; end
  264. def c2_a; @@a; end
  265. end
  266. x = Test4Class2.new
  267. x.c1_a = 456
  268. should_raise(NameError) { x.m1_a }
  269. should_raise(NameError) { x.m2_a }
  270. x.c1_a.should == 456
  271. x.c2_a.should == 456
  272. x.m1_a = 123
  273. x.m1_a.should == 123
  274. should_raise(NameError) { x.m2_a }
  275. x.c1_a.should == 456
  276. x.c2_a.should == 456
  277. x.c2_a = 789
  278. x.m1_a.should == 123
  279. should_raise(NameError) { x.m2_a }
  280. x.c1_a.should == 789
  281. x.c2_a.should == 789
  282. x.m2_a = 210
  283. x.m1_a.should == 123
  284. x.m2_a.should == 210
  285. x.c1_a.should == 789
  286. x.c2_a.should == 210
  287. Test4Class2.class_var_get("@@a").should == 210
  288. Test4Class1.class_var_get("@@a").should == 789
  289. Test4Module2.class_var_get("@@a").should == 210
  290. Test4Module1.class_var_get("@@a").should == 123
  291. end
  292. end
  293. describe "class variables are lexically bound to the surrounding class/module" do
  294. it "class variables in nested modules get the correct scope" do
  295. module Foo
  296. @@bob = 123
  297. def self.foo
  298. @@bob
  299. end
  300. module Bar
  301. module Baz
  302. def self.baz
  303. @@bob = 555
  304. end
  305. end
  306. @@bob = 456
  307. def self.bar
  308. @@bob
  309. end
  310. end
  311. class Bob
  312. @@bob = 789
  313. def self.bob
  314. @@bob
  315. end
  316. end
  317. module Zoo
  318. def self.zoo
  319. @@bob
  320. end
  321. end
  322. end
  323. Foo.foo.should == 123
  324. Foo::Bar.bar.should == 456
  325. Foo::Bob.bob.should == 789
  326. Foo::Bar::Baz.baz.should == 555
  327. should_raise(NameError, "uninitialized class variable @@bob in Foo::Zoo") { Foo::Zoo.zoo }
  328. end
  329. it "blocks don't interfere with scoping" do
  330. class Module
  331. def call_test_block
  332. yield
  333. end
  334. end
  335. module Foo
  336. call_test_block do
  337. @@abc = 'test1'
  338. end
  339. def self.get_abc; @@abc; end
  340. call_test_block do
  341. module Bar
  342. def self.get_def; @@def; end
  343. @@def = 'test2'
  344. end
  345. end
  346. end
  347. Foo.get_abc.should == 'test1'
  348. Foo::Bar::get_def.should == 'test2'
  349. end
  350. it "module level get/set methods set variables on Object (this test needs to be last)" do
  351. # test module level get/set methods
  352. def set_class_var x; @@osv = x; end
  353. def get_class_var; @@osv; end
  354. class Using_module_get_set_functions
  355. def check_sv; get_class_var; end
  356. def set_sv x; set_class_var x; end
  357. end
  358. x = Using_module_get_set_functions.new
  359. should_raise(NameError) { x.check_sv }
  360. x.set_sv(777).should == 777
  361. x.check_sv.should == 777
  362. x.class.class_variables.should == ['@@osv']
  363. Object.class_variables.should == ['@@osv']
  364. Object.class_var_get(:@@osv).should == 777
  365. x.class.class_var_get('@@osv').should == 777
  366. Array.class_var_get('@@osv').should == 777
  367. Comparable.class_variables.should == []
  368. end
  369. end
  370. finished