PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/TDDBC_Yokohama2_PCUnit/Ruby/doc/ruby/ruby-1.9.2/test/ruby/test_yield.rb

https://bitbucket.org/aetos/tddbc_yokohama2
Ruby | 382 lines | 323 code | 43 blank | 16 comment | 47 complexity | b2fdc35d7ae7a3a1b7be1baca52d847e MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, AGPL-3.0, 0BSD, Unlicense
  1. require 'test/unit'
  2. require 'stringio'
  3. class TestRubyYield < Test::Unit::TestCase
  4. def test_ary_each
  5. ary = [1]
  6. ary.each {|a, b, c, d| assert_equal [1,nil,nil,nil], [a,b,c,d] }
  7. ary.each {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
  8. ary.each {|a, b| assert_equal [1,nil], [a,b] }
  9. ary.each {|a| assert_equal 1, a }
  10. end
  11. def test_hash_each
  12. h = {:a => 1}
  13. h.each do |k, v|
  14. assert_equal :a, k
  15. assert_equal 1, v
  16. end
  17. h.each do |kv|
  18. assert_equal [:a, 1], kv
  19. end
  20. end
  21. def test_yield_0
  22. assert_equal 1, iter0 { 1 }
  23. assert_equal 2, iter0 { 2 }
  24. end
  25. def iter0
  26. yield
  27. end
  28. def test_yield_1
  29. iter1([]) {|a, b| assert_equal [nil,nil], [a, b] }
  30. iter1([1]) {|a, b| assert_equal [1,nil], [a, b] }
  31. iter1([1, 2]) {|a, b| assert_equal [1,2], [a,b] }
  32. iter1([1, 2, 3]) {|a, b| assert_equal [1,2], [a,b] }
  33. iter1([]) {|a| assert_equal [], a }
  34. iter1([1]) {|a| assert_equal [1], a }
  35. iter1([1, 2]) {|a| assert_equal [1,2], a }
  36. iter1([1, 2, 3]) {|a| assert_equal [1,2,3], a }
  37. end
  38. def iter1(args)
  39. yield args
  40. end
  41. def test_yield2
  42. def iter2_1() yield 1, *[2, 3] end
  43. iter2_1 {|a, b, c| assert_equal [1,2,3], [a,b,c] }
  44. def iter2_2() yield 1, *[] end
  45. iter2_2 {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
  46. def iter2_3() yield 1, *[2] end
  47. iter2_3 {|a, b, c| assert_equal [1,2,nil], [a,b,c] }
  48. end
  49. def test_yield_nested
  50. [[1, [2, 3]]].each {|a, (b, c)|
  51. assert_equal [1,2,3], [a,b,c]
  52. }
  53. [[1, [2, 3]]].map {|a, (b, c)|
  54. assert_equal [1,2,3], [a,b,c]
  55. }
  56. end
  57. def test_with_enum
  58. obj = Object
  59. def obj.each
  60. yield(*[])
  61. end
  62. obj.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
  63. obj.to_enum.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
  64. end
  65. def block_args_unleashed
  66. yield(1,2,3,4,5)
  67. end
  68. def test_block_args_unleashed
  69. r = block_args_unleashed {|a,b=1,*c,d,e|
  70. [a,b,c,d,e]
  71. }
  72. assert_equal([1,2,[3],4,5], r, "[ruby-core:19485]")
  73. end
  74. end
  75. require_relative 'sentence'
  76. class TestRubyYieldGen < Test::Unit::TestCase
  77. Syntax = {
  78. :exp => [["0"],
  79. ["nil"],
  80. ["false"],
  81. ["[]"],
  82. ["[",:exps,"]"]],
  83. :exps => [[:exp],
  84. [:exp,",",:exps]],
  85. :opt_block_param => [[],
  86. [:block_param_def]],
  87. :block_param_def => [['|', '|'],
  88. ['|', :block_param, '|']],
  89. :block_param => [[:f_arg, ",", :f_rest_arg, :opt_f_block_arg],
  90. [:f_arg, ","],
  91. [:f_arg, ',', :f_rest_arg, ",", :f_arg, :opt_f_block_arg],
  92. [:f_arg, :opt_f_block_arg],
  93. [:f_rest_arg, :opt_f_block_arg],
  94. [:f_rest_arg, ',', :f_arg, :opt_f_block_arg],
  95. [:f_block_arg]],
  96. :f_arg => [[:f_arg_item],
  97. [:f_arg, ',', :f_arg_item]],
  98. :f_rest_arg => [['*', "var"],
  99. ['*']],
  100. :opt_f_block_arg => [[',', :f_block_arg],
  101. []],
  102. :f_block_arg => [['&', 'var']],
  103. :f_arg_item => [[:f_norm_arg],
  104. ['(', :f_margs, ')']],
  105. :f_margs => [[:f_marg_list],
  106. [:f_marg_list, ',', '*', :f_norm_arg],
  107. [:f_marg_list, ',', '*', :f_norm_arg, ',', :f_marg_list],
  108. [:f_marg_list, ',', '*'],
  109. [:f_marg_list, ',', '*', ',', :f_marg_list],
  110. [ '*', :f_norm_arg],
  111. [ '*', :f_norm_arg, ',', :f_marg_list],
  112. [ '*'],
  113. [ '*', ',', :f_marg_list]],
  114. :f_marg_list => [[:f_marg],
  115. [:f_marg_list, ',', :f_marg]],
  116. :f_marg => [[:f_norm_arg],
  117. ['(', :f_margs, ')']],
  118. :f_norm_arg => [['var']],
  119. :command_args => [[:open_args]],
  120. :open_args => [[' ',:call_args],
  121. ['(', ')'],
  122. ['(', :call_args2, ')']],
  123. :call_args => [[:command],
  124. [ :args, :opt_block_arg],
  125. [ :assocs, :opt_block_arg],
  126. [ :args, ',', :assocs, :opt_block_arg],
  127. [ :block_arg]],
  128. :call_args2 => [[:arg, ',', :args, :opt_block_arg],
  129. [:arg, ',', :block_arg],
  130. [ :assocs, :opt_block_arg],
  131. [:arg, ',', :assocs, :opt_block_arg],
  132. [:arg, ',', :args, ',', :assocs, :opt_block_arg],
  133. [ :block_arg]],
  134. :command_args_noblock => [[:open_args_noblock]],
  135. :open_args_noblock => [[' ',:call_args_noblock],
  136. ['(', ')'],
  137. ['(', :call_args2_noblock, ')']],
  138. :call_args_noblock => [[:command],
  139. [ :args],
  140. [ :assocs],
  141. [ :args, ',', :assocs]],
  142. :call_args2_noblock => [[:arg, ',', :args],
  143. [ :assocs],
  144. [:arg, ',', :assocs],
  145. [:arg, ',', :args, ',', :assocs]],
  146. :command => [],
  147. :args => [[:arg],
  148. ["*",:arg],
  149. [:args,",",:arg],
  150. [:args,",","*",:arg]],
  151. :arg => [[:exp]],
  152. :assocs => [[:assoc],
  153. [:assocs, ',', :assoc]],
  154. :assoc => [[:arg, '=>', :arg],
  155. ['label', ':', :arg]],
  156. :opt_block_arg => [[',', :block_arg],
  157. []],
  158. :block_arg => [['&', :arg]],
  159. #:test => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']]
  160. :test_proc => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']],
  161. :test_lambda => [['def m() yield', :command_args_noblock, ' end; r = m(&lambda {', :block_param_def, 'vars', '}); undef m; r']],
  162. :test_enum => [['o = Object.new; def o.each() yield', :command_args_noblock, ' end; r1 = r2 = nil; o.each {|*x| r1 = x }; o.to_enum.each {|*x| r2 = x }; [r1, r2]']]
  163. }
  164. def rename_var(obj)
  165. vars = []
  166. r = obj.subst('var') {
  167. var = "v#{vars.length}"
  168. vars << var
  169. var
  170. }
  171. return r, vars
  172. end
  173. def split_by_comma(ary)
  174. return [] if ary.empty?
  175. result = [[]]
  176. ary.each {|e|
  177. if e == ','
  178. result << []
  179. else
  180. result.last << e
  181. end
  182. }
  183. result
  184. end
  185. def emu_return_args(*vs)
  186. vs
  187. end
  188. def emu_eval_args(args)
  189. if args.last == []
  190. args = args[0...-1]
  191. end
  192. code = "emu_return_args(#{args.map {|a| a.join('') }.join(",")})"
  193. eval code, nil, 'generated_code_in_emu_eval_args'
  194. end
  195. def emu_bind_single(arg, param, result_binding)
  196. #p [:emu_bind_single, arg, param]
  197. if param.length == 1 && String === param[0] && /\A[a-z0-9]+\z/ =~ param[0]
  198. result_binding[param[0]] = arg
  199. elsif param.length == 1 && Array === param[0] && param[0][0] == '(' && param[0][-1] == ')'
  200. arg = [arg] unless Array === arg
  201. emu_bind_params(arg, split_by_comma(param[0][1...-1]), false, result_binding)
  202. else
  203. raise "unexpected param: #{param.inspect}"
  204. end
  205. result_binding
  206. end
  207. def emu_bind_params(args, params, islambda, result_binding={})
  208. #p [:emu_bind_params, args, params]
  209. if params.last == [] # extra comma
  210. params.pop
  211. end
  212. star_index = nil
  213. params.each_with_index {|par, i|
  214. star_index = i if par[0] == '*'
  215. }
  216. if islambda
  217. if star_index
  218. if args.length < params.length - 1
  219. throw :emuerror, ArgumentError
  220. end
  221. else
  222. if args.length != params.length
  223. throw :emuerror, ArgumentError
  224. end
  225. end
  226. end
  227. # TRICK #2 : adjust mismatch on number of arguments
  228. if star_index
  229. pre_params = params[0...star_index]
  230. rest_param = params[star_index]
  231. post_params = params[(star_index+1)..-1]
  232. pre_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
  233. if post_params.length <= args.length
  234. post_params.reverse_each {|par| emu_bind_single(args.pop, par, result_binding) }
  235. else
  236. post_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
  237. end
  238. if rest_param != ['*']
  239. emu_bind_single(args, rest_param[1..-1], result_binding)
  240. end
  241. else
  242. params.each_with_index {|par, i|
  243. emu_bind_single(args[i], par, result_binding)
  244. }
  245. end
  246. #p [args, params, result_binding]
  247. result_binding
  248. end
  249. def emu_bind(t, islambda)
  250. #puts
  251. #p t
  252. command_args_noblock = t[1]
  253. block_param_def = t[3]
  254. command_args_noblock = command_args_noblock.expand {|a| !(a[0] == '[' && a[-1] == ']') }
  255. block_param_def = block_param_def.expand {|a| !(a[0] == '(' && a[-1] == ')') }
  256. if command_args_noblock.to_a[0] == ' '
  257. args = command_args_noblock.to_a[1..-1]
  258. elsif command_args_noblock.to_a[0] == '(' && command_args_noblock.to_a[-1] == ')'
  259. args = command_args_noblock.to_a[1...-1]
  260. else
  261. raise "unexpected command_args_noblock: #{command_args_noblock.inspect}"
  262. end
  263. args = emu_eval_args(split_by_comma(args))
  264. params = block_param_def.to_a[1...-1]
  265. params = split_by_comma(params)
  266. #p [:emu0, args, params]
  267. result_binding = {}
  268. if params.last && params.last[0] == '&'
  269. result_binding[params.last[1]] = nil
  270. params.pop
  271. end
  272. if !islambda
  273. # TRICK #1 : single array argument is expanded if there are two or more params.
  274. # * block parameter is not counted.
  275. # * extra comma after single param forces the expansion.
  276. if args.length == 1 && Array === args[0] && 1 < params.length
  277. args = args[0]
  278. end
  279. end
  280. emu_bind_params(args, params, islambda, result_binding)
  281. #p result_binding
  282. result_binding
  283. end
  284. def emu(t, vars, islambda)
  285. catch(:emuerror) {
  286. emu_binding = emu_bind(t, islambda)
  287. vars.map {|var| emu_binding.fetch(var, "NOVAL") }
  288. }
  289. end
  290. def disable_stderr
  291. begin
  292. save_stderr = $stderr
  293. $stderr = StringIO.new
  294. yield
  295. ensure
  296. $stderr = save_stderr
  297. end
  298. end
  299. def check_nofork(t, islambda=false)
  300. t, vars = rename_var(t)
  301. t = t.subst('vars') { " [#{vars.join(",")}]" }
  302. emu_values = emu(t, vars, islambda)
  303. s = t.to_s
  304. #print "#{s}\t\t"
  305. #STDOUT.flush
  306. eval_values = disable_stderr {
  307. begin
  308. eval(s, nil, 'generated_code_in_check_nofork')
  309. rescue ArgumentError
  310. ArgumentError
  311. end
  312. }
  313. #success = emu_values == eval_values ? 'succ' : 'fail'
  314. #puts "eval:#{vs_ev.inspect[1...-1].delete(' ')}\temu:#{vs_emu.inspect[1...-1].delete(' ')}\t#{success}"
  315. assert_equal(emu_values, eval_values, s)
  316. end
  317. def test_yield
  318. syntax = Sentence.expand_syntax(Syntax)
  319. Sentence.each(syntax, :test_proc, 4) {|t|
  320. check_nofork(t)
  321. }
  322. end
  323. def test_yield_lambda
  324. syntax = Sentence.expand_syntax(Syntax)
  325. Sentence.each(syntax, :test_lambda, 4) {|t|
  326. check_nofork(t, true)
  327. }
  328. end
  329. def test_yield_enum
  330. syntax = Sentence.expand_syntax(Syntax)
  331. Sentence.each(syntax, :test_enum, 4) {|t|
  332. code = t.to_s
  333. r1, r2 = disable_stderr {
  334. eval(code, nil, 'generated_code_in_test_yield_enum')
  335. }
  336. assert_equal(r1, r2, "#{t}")
  337. }
  338. end
  339. end