PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/test/mri/ruby/test_struct.rb

http://github.com/jruby/jruby
Ruby | 388 lines | 330 code | 55 blank | 3 comment | 1 complexity | 966fa2456f3a4bcf7400cab6e875bacc MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, GPL-2.0, JSON, LGPL-2.1
  1. # -*- coding: us-ascii -*-
  2. # frozen_string_literal: false
  3. require 'test/unit'
  4. require 'timeout'
  5. module TestStruct
  6. def test_struct
  7. struct_test = @Struct.new("Test", :foo, :bar)
  8. assert_equal(@Struct::Test, struct_test)
  9. test = struct_test.new(1, 2)
  10. assert_equal(1, test.foo)
  11. assert_equal(2, test.bar)
  12. assert_equal(1, test[0])
  13. assert_equal(2, test[1])
  14. a, b = test.to_a
  15. assert_equal(1, a)
  16. assert_equal(2, b)
  17. test[0] = 22
  18. assert_equal(22, test.foo)
  19. test.bar = 47
  20. assert_equal(47, test.bar)
  21. end
  22. # [ruby-dev:26247] more than 10 struct members causes segmentation fault
  23. def test_morethan10members
  24. list = %w( a b c d e f g h i j k l m n o p )
  25. until list.empty?
  26. c = @Struct.new(* list.map {|ch| ch.intern }).new
  27. list.each do |ch|
  28. c.__send__(ch)
  29. end
  30. list.pop
  31. end
  32. end
  33. def test_small_structs
  34. names = [:a, :b, :c, :d]
  35. 1.upto(4) {|n|
  36. fields = names[0, n]
  37. klass = @Struct.new(*fields)
  38. o = klass.new(*(0...n).to_a)
  39. fields.each_with_index {|name, i|
  40. assert_equal(i, o[name])
  41. }
  42. o = klass.new(*(0...n).to_a.reverse)
  43. fields.each_with_index {|name, i|
  44. assert_equal(n-i-1, o[name])
  45. }
  46. }
  47. end
  48. def test_inherit
  49. klass = @Struct.new(:a)
  50. klass2 = Class.new(klass)
  51. o = klass2.new(1)
  52. assert_equal(1, o.a)
  53. end
  54. def test_members
  55. klass = @Struct.new(:a)
  56. o = klass.new(1)
  57. assert_equal([:a], klass.members)
  58. assert_equal([:a], o.members)
  59. end
  60. def test_ref
  61. klass = @Struct.new(:a)
  62. o = klass.new(1)
  63. assert_equal(1, o[:a])
  64. assert_raise(NameError) { o[:b] }
  65. end
  66. def test_set
  67. klass = @Struct.new(:a)
  68. o = klass.new(1)
  69. o[:a] = 2
  70. assert_equal(2, o[:a])
  71. assert_raise(NameError) { o[:b] = 3 }
  72. end
  73. def test_struct_new
  74. assert_raise(NameError) { @Struct.new("foo") }
  75. assert_nothing_raised { @Struct.new("Foo") }
  76. @Struct.instance_eval { remove_const(:Foo) }
  77. assert_nothing_raised { @Struct.new(:a) { } }
  78. assert_raise(RuntimeError) { @Struct.new(:a) { raise } }
  79. assert_equal([:utime, :stime, :cutime, :cstime], Process.times.members)
  80. end
  81. def test_initialize
  82. klass = @Struct.new(:a)
  83. assert_raise(ArgumentError) { klass.new(1, 2) }
  84. klass = @Struct.new(:total) do
  85. def initialize(a, b)
  86. super(a+b)
  87. end
  88. end
  89. assert_equal 3, klass.new(1,2).total
  90. end
  91. def test_each
  92. klass = @Struct.new(:a, :b)
  93. o = klass.new(1, 2)
  94. assert_equal([1, 2], o.each.to_a)
  95. end
  96. def test_each_pair
  97. klass = @Struct.new(:a, :b)
  98. o = klass.new(1, 2)
  99. assert_equal([[:a, 1], [:b, 2]], o.each_pair.to_a)
  100. bug7382 = '[ruby-dev:46533]'
  101. a = []
  102. o.each_pair {|x| a << x}
  103. assert_equal([[:a, 1], [:b, 2]], a, bug7382)
  104. end
  105. def test_inspect
  106. klass = @Struct.new(:a)
  107. o = klass.new(1)
  108. assert_equal("#<struct a=1>", o.inspect)
  109. o.a = o
  110. assert_match(/^#<struct a=#<struct #<.*?>:...>>$/, o.inspect)
  111. @Struct.new("Foo", :a)
  112. o = @Struct::Foo.new(1)
  113. assert_equal("#<struct #@Struct::Foo a=1>", o.inspect)
  114. @Struct.instance_eval { remove_const(:Foo) }
  115. klass = @Struct.new(:a, :b)
  116. o = klass.new(1, 2)
  117. assert_equal("#<struct a=1, b=2>", o.inspect)
  118. klass = @Struct.new(:@a)
  119. o = klass.new(1)
  120. assert_equal(1, o.__send__(:@a))
  121. assert_equal("#<struct :@a=1>", o.inspect)
  122. o.__send__(:"@a=", 2)
  123. assert_equal(2, o.__send__(:@a))
  124. assert_equal("#<struct :@a=2>", o.inspect)
  125. o.__send__("@a=", 3)
  126. assert_equal(3, o.__send__(:@a))
  127. assert_equal("#<struct :@a=3>", o.inspect)
  128. methods = klass.instance_methods(false)
  129. assert_equal([:@a, :"@a="].sort.inspect, methods.sort.inspect, '[Bug #8756]')
  130. assert_include(methods, :@a)
  131. assert_include(methods, :"@a=")
  132. end
  133. def test_init_copy
  134. klass = @Struct.new(:a)
  135. o = klass.new(1)
  136. assert_equal(o, o.dup)
  137. end
  138. def test_aref
  139. klass = @Struct.new(:a)
  140. o = klass.new(1)
  141. assert_equal(1, o[0])
  142. assert_raise_with_message(IndexError, /offset -2\b/) {o[-2]}
  143. assert_raise_with_message(IndexError, /offset 1\b/) {o[1]}
  144. assert_raise_with_message(NameError, /foo/) {o["foo"]}
  145. assert_raise_with_message(NameError, /foo/) {o[:foo]}
  146. end
  147. def test_aset
  148. klass = @Struct.new(:a)
  149. o = klass.new(1)
  150. o[0] = 2
  151. assert_equal(2, o[:a])
  152. assert_raise_with_message(IndexError, /offset -2\b/) {o[-2] = 3}
  153. assert_raise_with_message(IndexError, /offset 1\b/) {o[1] = 3}
  154. assert_raise_with_message(NameError, /foo/) {o["foo"] = 3}
  155. assert_raise_with_message(NameError, /foo/) {o[:foo] = 3}
  156. end
  157. def test_values_at
  158. klass = @Struct.new(:a, :b, :c, :d, :e, :f)
  159. o = klass.new(1, 2, 3, 4, 5, 6)
  160. assert_equal([2, 4, 6], o.values_at(1, 3, 5))
  161. assert_equal([2, 3, 4, 3, 4, 5], o.values_at(1..3, 2...5))
  162. end
  163. def test_select
  164. klass = @Struct.new(:a, :b, :c, :d, :e, :f)
  165. o = klass.new(1, 2, 3, 4, 5, 6)
  166. assert_equal([1, 3, 5], o.select {|v| v % 2 != 0 })
  167. assert_raise(ArgumentError) { o.select(1) }
  168. end
  169. def test_big_struct
  170. klass1 = @Struct.new(*('a'..'z').map(&:to_sym))
  171. o = klass1.new
  172. assert_nil o.z
  173. assert_equal(:foo, o.z = :foo)
  174. assert_equal(:foo, o.z)
  175. assert_equal(:foo, o[25])
  176. end
  177. def test_overridden_aset
  178. bug10601 = '[ruby-core:66846] [Bug #10601]: should not be affected by []= method'
  179. struct = Class.new(Struct.new(*(:a..:z), :result)) do
  180. def []=(*args)
  181. raise args.inspect
  182. end
  183. end
  184. obj = struct.new
  185. assert_nothing_raised(RuntimeError, bug10601) do
  186. obj.result = 42
  187. end
  188. assert_equal(42, obj.result, bug10601)
  189. end
  190. def test_overridden_aref
  191. bug10601 = '[ruby-core:66846] [Bug #10601]: should not be affected by [] method'
  192. struct = Class.new(Struct.new(*(:a..:z), :result)) do
  193. def [](*args)
  194. raise args.inspect
  195. end
  196. end
  197. obj = struct.new
  198. obj.result = 42
  199. result = assert_nothing_raised(RuntimeError, bug10601) do
  200. break obj.result
  201. end
  202. assert_equal(42, result, bug10601)
  203. end
  204. def test_equal
  205. klass1 = @Struct.new(:a)
  206. klass2 = @Struct.new(:a, :b)
  207. o1 = klass1.new(1)
  208. o2 = klass1.new(1)
  209. o3 = klass2.new(1)
  210. assert_equal(o1, o2)
  211. assert_not_equal(o1, o3)
  212. end
  213. def test_hash
  214. klass = @Struct.new(:a)
  215. o = klass.new(1)
  216. assert_kind_of(Fixnum, o.hash)
  217. end
  218. def test_eql
  219. klass1 = @Struct.new(:a)
  220. klass2 = @Struct.new(:a, :b)
  221. o1 = klass1.new(1)
  222. o2 = klass1.new(1)
  223. o3 = klass2.new(1)
  224. assert_operator(o1, :eql?, o2)
  225. assert_not_operator(o1, :eql?, o3)
  226. end
  227. def test_size
  228. klass = @Struct.new(:a)
  229. o = klass.new(1)
  230. assert_equal(1, o.size)
  231. end
  232. def test_error
  233. assert_raise(TypeError){
  234. @Struct.new(0)
  235. }
  236. end
  237. def test_redefinition_warning
  238. @Struct.new("RedefinitionWarning")
  239. e = EnvUtil.verbose_warning do
  240. @Struct.new("RedefinitionWarning")
  241. end
  242. assert_match(/redefining constant #@Struct::RedefinitionWarning/, e)
  243. end
  244. def test_nonascii
  245. struct_test = @Struct.new("R\u{e9}sum\u{e9}", :"r\u{e9}sum\u{e9}")
  246. assert_equal(@Struct.const_get("R\u{e9}sum\u{e9}"), struct_test, '[ruby-core:24849]')
  247. a = struct_test.new(42)
  248. assert_equal("#<struct #@Struct::R\u{e9}sum\u{e9} r\u{e9}sum\u{e9}=42>", a.inspect, '[ruby-core:24849]')
  249. e = EnvUtil.verbose_warning do
  250. @Struct.new("R\u{e9}sum\u{e9}", :"r\u{e9}sum\u{e9}")
  251. end
  252. assert_nothing_raised(Encoding::CompatibilityError) do
  253. assert_match(/redefining constant #@Struct::R\u{e9}sum\u{e9}/, e)
  254. end
  255. end
  256. def test_junk
  257. struct_test = @Struct.new("Foo", "a\000")
  258. o = struct_test.new(1)
  259. assert_equal(1, o.send("a\000"))
  260. @Struct.instance_eval { remove_const(:Foo) }
  261. end
  262. def test_comparison_when_recursive
  263. klass1 = @Struct.new(:a, :b, :c)
  264. x = klass1.new(1, 2, nil); x.c = x
  265. y = klass1.new(1, 2, nil); y.c = y
  266. Timeout.timeout(1) {
  267. assert_equal x, y
  268. assert_operator x, :eql?, y
  269. }
  270. z = klass1.new(:something, :other, nil); z.c = z
  271. Timeout.timeout(1) {
  272. assert_not_equal x, z
  273. assert_not_operator x, :eql?, z
  274. }
  275. x.c = y; y.c = x
  276. Timeout.timeout(1) {
  277. assert_equal x, y
  278. assert_operator x, :eql?, y
  279. }
  280. x.c = z; z.c = x
  281. Timeout.timeout(1) {
  282. assert_not_equal x, z
  283. assert_not_operator x, :eql?, z
  284. }
  285. end
  286. def test_to_h
  287. klass = @Struct.new(:a, :b, :c, :d, :e, :f)
  288. o = klass.new(1, 2, 3, 4, 5, 6)
  289. assert_equal({a:1, b:2, c:3, d:4, e:5, f:6}, o.to_h)
  290. end
  291. def test_question_mark_in_member
  292. klass = @Struct.new(:a, :b?)
  293. x = Object.new
  294. o = klass.new("test", x)
  295. assert_same(x, o.b?)
  296. o.send("b?=", 42)
  297. assert_equal(42, o.b?)
  298. end
  299. def test_bang_mark_in_member
  300. klass = @Struct.new(:a, :b!)
  301. x = Object.new
  302. o = klass.new("test", x)
  303. assert_same(x, o.b!)
  304. o.send("b!=", 42)
  305. assert_equal(42, o.b!)
  306. end
  307. def test_setter_method_returns_value
  308. klass = @Struct.new(:a)
  309. x = klass.new
  310. assert_equal "[Bug #9353]", x.send(:a=, "[Bug #9353]")
  311. end
  312. def test_dig
  313. klass = @Struct.new(:a)
  314. o = klass.new(klass.new({b: [1, 2, 3]}))
  315. assert_equal(1, o.dig(:a, :a, :b, 0))
  316. assert_nil(o.dig(:b, 0))
  317. end
  318. class TopStruct < Test::Unit::TestCase
  319. include TestStruct
  320. def initialize(*)
  321. super
  322. @Struct = Struct
  323. end
  324. end
  325. class SubStruct < Test::Unit::TestCase
  326. include TestStruct
  327. SubStruct = Class.new(Struct)
  328. def initialize(*)
  329. super
  330. @Struct = SubStruct
  331. end
  332. end
  333. end