11require 'spec_helper'
22require 'parser/all'
3+ require 'support/parser_class_generator'
34
45describe Unparser , mutant_expression : 'Unparser::Emitter*' do
56 describe '.unparse' do
67
7- PARSERS = IceNine . deep_freeze (
8+ RUBY_VERSION_PARSERS = IceNine . deep_freeze (
89 '2.1' => Parser ::Ruby21 ,
910 '2.2' => Parser ::Ruby22 ,
1011 '2.3' => Parser ::Ruby23
1112 )
1213
13- RUBIES = PARSERS . keys . freeze
14+ RUBY_VERSIONS = RUBY_VERSION_PARSERS . keys . freeze
1415
15- def self . parser_for_ruby_version ( version )
16- PARSERS . fetch ( version ) do
17- raise "Unrecognized Ruby version #{ version } "
16+ def self . builder_options
17+ @builder_options ||= { }
18+ end
19+
20+ def self . builder_options = ( options )
21+ @builder_options = options
22+ end
23+
24+ def self . ruby_versions
25+ @ruby_versions ||= RUBY_VERSIONS
26+ end
27+
28+ def self . ruby_versions = ( versions )
29+ @ruby_versions = versions
30+ end
31+
32+ def self . with_ruby_versions ( beginning_at : nil , ending_at : nil , only : nil )
33+ original_ruby_versions = ruby_versions
34+ if only
35+ self . ruby_versions = only & ruby_versions # intersection
36+ else
37+ if ending_at
38+ idx = ruby_versions . index ( ending_at ) || fail ( 'Invalid Ruby specified' )
39+ self . ruby_versions = ruby_versions [ 0 ..idx ]
40+ end
41+ if beginning_at
42+ idx = ruby_versions . index ( beginning_at ) || fail ( 'Invalid Ruby specified' )
43+ self . ruby_versions = ruby_versions [ idx ..-1 ]
44+ end
1845 end
46+
47+ yield
48+
49+ self . ruby_versions = original_ruby_versions
1950 end
2051
21- def self . with_versions ( versions )
22- versions . each do |version |
23- yield parser_for_ruby_version ( version )
52+ def self . current_parsers
53+ ruby_versions . map do |ruby_version |
54+ if builder_options != { }
55+ ParserClassGenerator . generate_with_options ( parser_for_ruby_version ( ruby_version ) , builder_options )
56+ else
57+ parser_for_ruby_version ( ruby_version )
58+ end
59+ end
60+ end
61+
62+ def self . with_builder_options ( options )
63+ original_options = builder_options
64+ self . builder_options = builder_options . merge ( options )
65+
66+ yield
67+
68+ self . builder_options = original_options
69+ end
70+
71+ def self . parser_for_ruby_version ( version )
72+ RUBY_VERSION_PARSERS . fetch ( version ) do
73+ raise "Unrecognized Ruby version #{ version } "
2474 end
2575 end
2676
@@ -50,14 +100,14 @@ def self.assert_unterminated(expression)
50100 assert_source ( "(#{ expression } ).foo" )
51101 end
52102
53- def self . assert_terminated ( expression , rubies = RUBIES )
54- assert_source ( expression , rubies )
55- assert_source ( "foo(#{ expression } )" , rubies )
56- assert_source ( "#{ expression } .foo" , rubies )
103+ def self . assert_terminated ( expression )
104+ assert_source ( expression )
105+ assert_source ( "foo(#{ expression } )" )
106+ assert_source ( "#{ expression } .foo" )
57107 end
58108
59- def self . assert_generates ( ast_or_string , expected , versions = RUBIES )
60- with_versions ( versions ) do |parser |
109+ def self . assert_generates ( ast_or_string , expected )
110+ current_parsers . each do |parser |
61111 it "should generate #{ ast_or_string } as #{ expected } under #{ parser . inspect } " do
62112 if ast_or_string . is_a? ( String )
63113 expected = strip ( expected )
@@ -69,16 +119,16 @@ def self.assert_generates(ast_or_string, expected, versions = RUBIES)
69119 end
70120 end
71121
72- def self . assert_round_trip ( input , versions = RUBIES )
73- with_versions ( versions ) do |parser |
122+ def self . assert_round_trip ( input )
123+ current_parsers . each do |parser |
74124 it "should round trip #{ input } under #{ parser . inspect } " do
75125 assert_round_trip ( input , parser )
76126 end
77127 end
78128 end
79129
80- def self . assert_source ( input , versions = RUBIES )
81- assert_round_trip ( strip ( input ) , versions )
130+ def self . assert_source ( input )
131+ assert_round_trip ( strip ( input ) )
82132 end
83133
84134 context 'kwargs' do
@@ -273,8 +323,18 @@ def foo(bar:, baz: "value")
273323
274324 context 'magic keywords' do
275325 assert_generates '__ENCODING__' , 'Encoding::UTF_8'
276- assert_generates '__FILE__' , '"(string)"'
277- assert_generates '__LINE__' , '1'
326+
327+ # These two assertions don't actually need to be wrapped in this block since `true` is the default,
328+ # but it is helpful to contrast with the assertions farther down.
329+ with_builder_options ( emit_file_line_as_literals : true ) do
330+ assert_generates '__FILE__' , '"(string)"'
331+ assert_generates '__LINE__' , '1'
332+ end
333+
334+ with_builder_options ( emit_file_line_as_literals : false ) do
335+ assert_source '__FILE__'
336+ assert_source '__LINE__'
337+ end
278338 end
279339
280340 context 'assignment' do
@@ -408,8 +468,10 @@ def foo
408468 end
409469
410470 context 'conditional send (csend)' do
411- assert_terminated 'a&.b' , %w( 2.3 )
412- assert_terminated 'a&.b(c)' , %w( 2.3 )
471+ with_ruby_versions ( beginning_at : '2.3' ) do
472+ assert_terminated 'a&.b'
473+ assert_terminated 'a&.b(c)'
474+ end
413475 end
414476
415477 context 'send' do
0 commit comments