xref: /aosp_15_r20/external/antlr/runtime/Ruby/test/unit/test-template.rb (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot#!/usr/bin/ruby
2*16467b97STreehugger Robot# encoding: utf-8
3*16467b97STreehugger Robot
4*16467b97STreehugger Robotrequire 'spec'
5*16467b97STreehugger Robotrequire 'antlr3/template'
6*16467b97STreehugger Robotrequire 'antlr3/util'
7*16467b97STreehugger Robot
8*16467b97STreehugger Robotinclude ANTLR3
9*16467b97STreehugger RobotMethodDescription = Struct.new( :name, :body, :arguments )
10*16467b97STreehugger RobotTEMPLATE_NAMES = %w( method class_definition attribute )
11*16467b97STreehugger RobotSAMPLE_GROUP_FILE = File.join(
12*16467b97STreehugger Robot  File.dirname( __FILE__ ), 'sample-input', 'template-group'
13*16467b97STreehugger Robot)
14*16467b97STreehugger Robot
15*16467b97STreehugger Robotdescribe Template::Context do
16*16467b97STreehugger Robot  example "creating an empty context" do
17*16467b97STreehugger Robot    context = Template::Context.new
18*16467b97STreehugger Robot    context.instance_variables.should be_empty
19*16467b97STreehugger Robot  end
20*16467b97STreehugger Robot
21*16467b97STreehugger Robot  example "creating a context with a variable map" do
22*16467b97STreehugger Robot    context = Template::Context.new(
23*16467b97STreehugger Robot      :a => 1, :b => 2
24*16467b97STreehugger Robot    )
25*16467b97STreehugger Robot
26*16467b97STreehugger Robot    vars = context.instance_variables.map { | i | i.to_s }
27*16467b97STreehugger Robot    vars.should include( '@a' )
28*16467b97STreehugger Robot    vars.should include( '@b' )
29*16467b97STreehugger Robot
30*16467b97STreehugger Robot    context.instance_variable_get( '@a' ).should == 1
31*16467b97STreehugger Robot    context.instance_variable_get( '@b' ).should == 2
32*16467b97STreehugger Robot  end
33*16467b97STreehugger Robot
34*16467b97STreehugger Robot  example "fetching variable values from []" do
35*16467b97STreehugger Robot    context = Template::Context.new(
36*16467b97STreehugger Robot      :a => 1, :b => 2
37*16467b97STreehugger Robot    )
38*16467b97STreehugger Robot
39*16467b97STreehugger Robot    context[ :a ].should == 1
40*16467b97STreehugger Robot    context[ 'a' ].should == 1
41*16467b97STreehugger Robot    context[ :b ].should == 2
42*16467b97STreehugger Robot    context[ 'b' ].should == 2
43*16467b97STreehugger Robot  end
44*16467b97STreehugger Robot
45*16467b97STreehugger Robot  example "defining variables with []=" do
46*16467b97STreehugger Robot    context = Template::Context.new( :a => 3 )
47*16467b97STreehugger Robot    context[ :a ] = 1
48*16467b97STreehugger Robot    context[ 'b' ] = 2
49*16467b97STreehugger Robot
50*16467b97STreehugger Robot    context.instance_variable_get( '@a' ).should == 1
51*16467b97STreehugger Robot    context.instance_variable_get( '@b' ).should == 2
52*16467b97STreehugger Robot  end
53*16467b97STreehugger Robot
54*16467b97STreehugger Robot  example "using method missing to assign values" do
55*16467b97STreehugger Robot    context = Template::Context.new( :a => 3 )
56*16467b97STreehugger Robot    context.a = 1
57*16467b97STreehugger Robot    context.b = 2
58*16467b97STreehugger Robot
59*16467b97STreehugger Robot    context.instance_variable_get( '@a' ).should == 1
60*16467b97STreehugger Robot    context.instance_variable_get( '@b' ).should == 2
61*16467b97STreehugger Robot  end
62*16467b97STreehugger Robot
63*16467b97STreehugger Robot  example "using method missing to get variable values" do
64*16467b97STreehugger Robot    context = Template::Context.new( :a => 1, :b => 2)
65*16467b97STreehugger Robot
66*16467b97STreehugger Robot    context.a.should == 1
67*16467b97STreehugger Robot    context.b.should == 2
68*16467b97STreehugger Robot  end
69*16467b97STreehugger Robot
70*16467b97STreehugger Robotend
71*16467b97STreehugger Robot
72*16467b97STreehugger Robot
73*16467b97STreehugger Robotshared_examples_for "template groups" do
74*16467b97STreehugger Robot  include ANTLR3::Util
75*16467b97STreehugger Robot
76*16467b97STreehugger Robot  example "template definitions" do
77*16467b97STreehugger Robot    templates = @group.templates
78*16467b97STreehugger Robot    templates.should_not be_empty
79*16467b97STreehugger Robot    templates.should equal @group::TEMPLATES
80*16467b97STreehugger Robot
81*16467b97STreehugger Robot    names = templates.keys
82*16467b97STreehugger Robot
83*16467b97STreehugger Robot    names.should have(3).things
84*16467b97STreehugger Robot    for template_name in TEMPLATE_NAMES
85*16467b97STreehugger Robot      names.should include template_name
86*16467b97STreehugger Robot      template_class = templates[ template_name ]
87*16467b97STreehugger Robot      template_class.should be_a_kind_of Class
88*16467b97STreehugger Robot      template_class.superclass.should equal Template::Context
89*16467b97STreehugger Robot      template_class.should be < @group # it should include the group module
90*16467b97STreehugger Robot    end
91*16467b97STreehugger Robot  end
92*16467b97STreehugger Robot
93*16467b97STreehugger Robot  example "template_defined?( name ) should verify whether a template is defined in a group" do
94*16467b97STreehugger Robot    for name in TEMPLATE_NAMES
95*16467b97STreehugger Robot      @group.template_defined?( name ).should be_true
96*16467b97STreehugger Robot      @group.template_defined?( name.to_s ).should be_true
97*16467b97STreehugger Robot    end
98*16467b97STreehugger Robot
99*16467b97STreehugger Robot    @group.template_defined?( :something_else ).should be_false
100*16467b97STreehugger Robot  end
101*16467b97STreehugger Robot
102*16467b97STreehugger Robot  example "template method definitions" do
103*16467b97STreehugger Robot    for name in TEMPLATE_NAMES
104*16467b97STreehugger Robot      @group.should respond_to( name )
105*16467b97STreehugger Robot      @group.should respond_to( "#{ name }!" )
106*16467b97STreehugger Robot      if RUBY_VERSION =~ /^1\.9/
107*16467b97STreehugger Robot        @group.private_instance_methods.should include name.to_sym
108*16467b97STreehugger Robot        @group.private_instance_methods.should include :"#{ name }!"
109*16467b97STreehugger Robot      else
110*16467b97STreehugger Robot        @group.private_instance_methods.should include name.to_s
111*16467b97STreehugger Robot        @group.private_instance_methods.should include "#{ name }!"
112*16467b97STreehugger Robot      end
113*16467b97STreehugger Robot    end
114*16467b97STreehugger Robot  end
115*16467b97STreehugger Robot
116*16467b97STreehugger Robot  example "template method operation" do
117*16467b97STreehugger Robot    value = @group.class_definition
118*16467b97STreehugger Robot    value.should be_a_kind_of Template::Context
119*16467b97STreehugger Robot
120*16467b97STreehugger Robot    value = @group.class_definition!
121*16467b97STreehugger Robot    value.should be_a_kind_of String
122*16467b97STreehugger Robot
123*16467b97STreehugger Robot    value = @group.attribute( :name => 'a' )
124*16467b97STreehugger Robot    value.should be_a_kind_of Template::Context
125*16467b97STreehugger Robot  end
126*16467b97STreehugger Robotend
127*16467b97STreehugger Robot
128*16467b97STreehugger Robotdescribe Template::Group, "dynamic template definition" do
129*16467b97STreehugger Robot  include ANTLR3::Util
130*16467b97STreehugger Robot
131*16467b97STreehugger Robot  before :each do
132*16467b97STreehugger Robot    @group = Template::Group.new do
133*16467b97STreehugger Robot      extend ANTLR3::Util
134*16467b97STreehugger Robot      define_template( :class_definition, tidy( <<-'END'.chomp ) )
135*16467b97STreehugger Robot      | class <%= @name %><% if @superclass %> < <%= @superclass %><% end %>
136*16467b97STreehugger Robot      | % if @attributes
137*16467b97STreehugger Robot      |
138*16467b97STreehugger Robot      | % for attr, access in @attributes
139*16467b97STreehugger Robot      | <%= attribute( :name => attr, :access => ( access || 'rw' ) ).to_s.chomp %>
140*16467b97STreehugger Robot      | % end
141*16467b97STreehugger Robot      | % end
142*16467b97STreehugger Robot      | % if @methods
143*16467b97STreehugger Robot      | % for method in ( @methods || [] )
144*16467b97STreehugger Robot      | <%= method( method ) %>
145*16467b97STreehugger Robot      | % end
146*16467b97STreehugger Robot      | % end
147*16467b97STreehugger Robot      | end
148*16467b97STreehugger Robot      END
149*16467b97STreehugger Robot
150*16467b97STreehugger Robot      define_template( :attribute, tidy( <<-'END'.chomp ) )
151*16467b97STreehugger Robot      | % case @access.to_s.downcase
152*16467b97STreehugger Robot      | % when 'r'
153*16467b97STreehugger Robot      |   attr_reader :<%= @name %>
154*16467b97STreehugger Robot      | % when 'w'
155*16467b97STreehugger Robot      |   attr_writer :<%= @name %>
156*16467b97STreehugger Robot      | % else
157*16467b97STreehugger Robot      |   attr_accessor :<%= @name %>
158*16467b97STreehugger Robot      | % end
159*16467b97STreehugger Robot      END
160*16467b97STreehugger Robot
161*16467b97STreehugger Robot      define_template( :method, tidy( <<-'END'.chomp ) )
162*16467b97STreehugger Robot      |
163*16467b97STreehugger Robot      |   def <%= @name %><% if @arguments and not @arguments.empty? %>( <%= @arguments.join( ', ' ) %> )<% end %>
164*16467b97STreehugger Robot      | <%= @body.gsub( /^/, '    ' ) %>
165*16467b97STreehugger Robot      |   end
166*16467b97STreehugger Robot      END
167*16467b97STreehugger Robot    end
168*16467b97STreehugger Robot  end
169*16467b97STreehugger Robot
170*16467b97STreehugger Robot  it_should_behave_like "template groups"
171*16467b97STreehugger Robot
172*16467b97STreehugger Robot  example "template object string rendering" do
173*16467b97STreehugger Robot    attributes = [
174*16467b97STreehugger Robot      %w( family ),
175*16467b97STreehugger Robot      %w( name r )
176*16467b97STreehugger Robot    ]
177*16467b97STreehugger Robot
178*16467b97STreehugger Robot    methods = [
179*16467b97STreehugger Robot      MethodDescription.new( 'eat', %q[puts( "ate %s %s" % [ number, @name ] )], %w( number ) ),
180*16467b97STreehugger Robot      MethodDescription.new( :to_s, '@name.to_s.dup' )
181*16467b97STreehugger Robot    ]
182*16467b97STreehugger Robot
183*16467b97STreehugger Robot    vegetable = @group.class_definition(
184*16467b97STreehugger Robot      :name => 'Vegetable',
185*16467b97STreehugger Robot      :superclass => 'Food',
186*16467b97STreehugger Robot      :attributes => attributes,
187*16467b97STreehugger Robot      :methods => methods
188*16467b97STreehugger Robot    )
189*16467b97STreehugger Robot
190*16467b97STreehugger Robot    vegetable.to_s.should == tidy( <<-END.chomp )
191*16467b97STreehugger Robot    | class Vegetable < Food
192*16467b97STreehugger Robot    |
193*16467b97STreehugger Robot    |   attr_accessor :family
194*16467b97STreehugger Robot    |   attr_reader :name
195*16467b97STreehugger Robot    |
196*16467b97STreehugger Robot    |   def eat( number )
197*16467b97STreehugger Robot    |     puts( "ate %s %s" % [ number, @name ] )
198*16467b97STreehugger Robot    |   end
199*16467b97STreehugger Robot    |
200*16467b97STreehugger Robot    |   def to_s
201*16467b97STreehugger Robot    |     @name.to_s.dup
202*16467b97STreehugger Robot    |   end
203*16467b97STreehugger Robot    | end
204*16467b97STreehugger Robot    END
205*16467b97STreehugger Robot  end
206*16467b97STreehugger Robotend
207*16467b97STreehugger Robot
208*16467b97STreehugger Robotdescribe Template::Group, "loading a template definition file" do
209*16467b97STreehugger Robot
210*16467b97STreehugger Robot  before :each do
211*16467b97STreehugger Robot    @group = Template::Group.load( SAMPLE_GROUP_FILE )
212*16467b97STreehugger Robot  end
213*16467b97STreehugger Robot
214*16467b97STreehugger Robot  it_should_behave_like "template groups"
215*16467b97STreehugger Robot
216*16467b97STreehugger Robot  example "template object string rendering" do
217*16467b97STreehugger Robot    attributes = [
218*16467b97STreehugger Robot      %w( family ),
219*16467b97STreehugger Robot      %w( name r )
220*16467b97STreehugger Robot    ]
221*16467b97STreehugger Robot
222*16467b97STreehugger Robot    methods = [
223*16467b97STreehugger Robot      MethodDescription.new( 'eat', %q[puts( "ate %s %s" % [ number, @name ] )], %w( number ) ),
224*16467b97STreehugger Robot      MethodDescription.new( :to_s, '@name.to_s.dup' )
225*16467b97STreehugger Robot    ]
226*16467b97STreehugger Robot
227*16467b97STreehugger Robot    vegetable = @group.class_definition(
228*16467b97STreehugger Robot      :name => 'Vegetable',
229*16467b97STreehugger Robot      :superclass => 'Food',
230*16467b97STreehugger Robot      :attributes => attributes,
231*16467b97STreehugger Robot      :methods => methods
232*16467b97STreehugger Robot    )
233*16467b97STreehugger Robot
234*16467b97STreehugger Robot    vegetable.to_s.should == tidy( <<-END.chomp )
235*16467b97STreehugger Robot    | class Vegetable < Food
236*16467b97STreehugger Robot    |
237*16467b97STreehugger Robot    |   attr_accessor :family
238*16467b97STreehugger Robot    |   attr_reader :name
239*16467b97STreehugger Robot    |
240*16467b97STreehugger Robot    |   def eat( number )
241*16467b97STreehugger Robot    |     puts( "ate %s %s" % [ number, @name ] )
242*16467b97STreehugger Robot    |   end
243*16467b97STreehugger Robot    |
244*16467b97STreehugger Robot    |   def to_s
245*16467b97STreehugger Robot    |     @name.to_s.dup
246*16467b97STreehugger Robot    |   end
247*16467b97STreehugger Robot    | end
248*16467b97STreehugger Robot    END
249*16467b97STreehugger Robot  end
250*16467b97STreehugger Robotend
251