1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3/test/functional'
5
6class TestRewritingLexerOutputDirectly < ANTLR3::Test::Functional
7  inline_grammar( <<-'END' )
8    lexer grammar SimpleRewriting;
9    options {
10        language = Ruby;
11    }
12
13    A: 'a';
14    B: 'b';
15    C: 'c';
16  END
17
18  def rewrite( input, expected )
19    lexer = SimpleRewriting::Lexer.new( input )
20    tokens = ANTLR3::TokenRewriteStream.new( lexer )
21    yield( tokens )
22    tokens.render.should == expected
23    return( tokens )
24  end
25
26  example 'insert before' do
27    rewrite( 'abc', '0abc' ) do |stream|
28      stream.insert_before( 0, '0' )
29    end
30  end
31
32  example 'insert after last index' do
33    rewrite( 'abc', 'abcx' ) do |stream|
34      stream.insert_after( 2, 'x' )
35    end
36  end
37
38  example 'insert before after middle index' do
39    rewrite( 'abc', 'axbxc' ) do |stream|
40      stream.insert_before 1, 'x'
41      stream.insert_after 1, 'x'
42    end
43  end
44
45  example 'replace index 0' do
46    rewrite( 'abc', 'xbc' ) do |stream|
47      stream.replace( 0, 'x' )
48    end
49  end
50
51  example 'replace last index' do
52    rewrite( 'abc', 'abx' ) do |stream|
53      stream.replace 2, 'x'
54    end
55  end
56
57  example 'replace last index' do
58    rewrite( 'abc', 'abx' ) do |stream|
59      stream.replace( 2, 'x' )
60    end
61  end
62
63  example 'replace middle index' do
64    rewrite( 'abc', 'axc' ) do |stream|
65      stream.replace 1, 'x'
66    end
67  end
68
69  example 'replace middle index' do
70    rewrite( 'abc', 'ayc' ) do |stream|
71      stream.replace 1, 'x'
72      stream.replace 1, 'y'
73    end
74  end
75
76  example 'replace middle index 1 insert before' do
77    rewrite( 'abc', '_ayc' ) do |stream|
78      stream.insert_before 0, '_'
79      stream.replace 1, 'x'
80      stream.replace 1, 'y'
81    end
82  end
83
84  example 'replace then delete middle index' do
85    rewrite( 'abc', 'ac' ) do |stream|
86      stream.replace 1, 'x'
87      stream.delete 1
88    end
89  end
90
91  example 'insert then replace same index' do
92    rewrite 'abc', 'xbc' do |stream|
93      stream.insert_before 0, '0'
94      stream.replace 0, 'x'
95    end
96  end
97
98  example 'insert middle index' do
99    rewrite( "abc", "ayxbc" ) do |stream|
100      stream.insert_before( 1, "x" )
101      stream.insert_before( 1, "y" )
102    end
103  end
104
105  example 'insert then replace index0' do
106    rewrite( "abc", "zbc" ) do |stream|
107      stream.insert_before( 0, "x" )
108      stream.insert_before( 0, "y" )
109      stream.replace( 0, "z" )
110    end
111  end
112
113  example 'replace then insert before last index' do
114    rewrite( "abc", "abyx" ) do |stream|
115      stream.replace( 2, "x" )
116      stream.insert_before( 2, "y" )
117    end
118  end
119
120  example 'insert then replace last index' do
121    rewrite( "abc", "abx" ) do |stream|
122      stream.insert_before( 2, "y" )
123      stream.replace( 2, "x" )
124    end
125  end
126
127  example 'replace then insert after last index' do
128    rewrite( "abc", "abxy" ) do |stream|
129      stream.replace( 2, "x" )
130      stream.insert_after( 2, "y" )
131    end
132  end
133
134  example 'replace range then insert at left edge' do
135    rewrite( "abcccba", "abyxba" ) do |stream|
136      stream.replace( 2, 4, "x" )
137      stream.insert_before( 2, "y" )
138    end
139  end
140
141  example 'replace range then insert after right edge' do
142    rewrite( "abcccba", "abxyba" ) do |stream|
143      stream.replace( 2, 4, "x" )
144      stream.insert_after( 4, "y" )
145    end
146  end
147
148  example 'replace all' do
149    rewrite( "abcccba", "x" ) do |stream|
150      stream.replace( 0, 6, "x" )
151    end
152  end
153
154  example 'replace single middle then overlapping superset' do
155    rewrite( "abcba", "fooa" ) do |stream|
156      stream.replace( 2, 2, "xyz" )
157      stream.replace( 0, 3, "foo" )
158    end
159  end
160
161  example 'combine inserts' do
162    rewrite( "abc", "yxabc" ) do |stream|
163      stream.insert_before( 0, "x" )
164      stream.insert_before( 0, "y" )
165    end
166  end
167
168  example 'combine3 inserts' do
169    rewrite( "abc", "yazxbc" ) do |stream|
170      stream.insert_before( 1, "x" )
171      stream.insert_before( 0, "y" )
172      stream.insert_before( 1, "z" )
173    end
174  end
175
176  example 'disjoint inserts' do
177    rewrite( "abc", "zaxbyc" ) do |stream|
178      stream.insert_before( 1, "x" )
179      stream.insert_before( 2, "y" )
180      stream.insert_before( 0, "z" )
181    end
182  end
183
184  example 'leave alone disjoint insert' do
185    rewrite( "abcc", "axbfoo" ) do |stream|
186      stream.insert_before( 1, "x" )
187      stream.replace( 2, 3, "foo" )
188    end
189  end
190
191  example 'leave alone disjoint insert2' do
192    rewrite( "abcc", "axbfoo" ) do |stream|
193      stream.replace( 2, 3, "foo" )
194      stream.insert_before( 1, "x" )
195    end
196  end
197
198  example 'combine insert on left with delete' do
199    rewrite( "abc", "z" ) do |stream|
200      stream.delete( 0, 2 )
201      stream.insert_before( 0, "z" )
202    end
203  end
204
205  example 'overlapping replace' do
206    rewrite( "abcc", "bar" ) do |stream|
207      stream.replace( 1, 2, "foo" )
208      stream.replace( 0, 3, "bar" )
209    end
210  end
211
212  example 'overlapping replace3' do
213    rewrite( "abcc", "barc" ) do |stream|
214      stream.replace( 1, 2, "foo" )
215      stream.replace( 0, 2, "bar" )
216    end
217  end
218
219  example 'overlapping replace 4' do
220    rewrite( "abcc", "abar" ) do |stream|
221      stream.replace( 1, 2, "foo" )
222      stream.replace( 1, 3, "bar" )
223    end
224  end
225
226  example 'overlapping replace 2' do
227    lexer = SimpleRewriting::Lexer.new( 'abcc' )
228    stream = ANTLR3::TokenRewriteStream.new( lexer )
229    stream.replace 0, 3, 'bar'
230    stream.replace 1, 2, 'foo'
231
232    lambda { stream.render }.
233    should raise_error { |error|
234      error.to_s.should == %q<operation (replace @ 1..2 : "foo") overlaps with previous operation (replace @ 0..3 : "bar")>
235    }
236  end
237
238  example 'replace range then insert at right edge' do
239    lexer = SimpleRewriting::Lexer.new( 'abcccba' )
240    stream = ANTLR3::TokenRewriteStream.new( lexer )
241    stream.replace 2, 4, 'x'
242    stream.insert_before 4, 'y'
243    lambda { stream.render }.
244    should raise_error { |error|
245      error.to_s.should == %q<operation (insert-before @ 4 : "y") overlaps with previous operation (replace @ 2..4 : "x")>
246    }
247  end
248
249  example 'replace then replace superset' do
250    lexer = SimpleRewriting::Lexer.new( 'abcccba' )
251    stream = ANTLR3::TokenRewriteStream.new( lexer )
252    stream.replace 2, 4, 'xyz'
253    stream.replace 3, 5, 'foo'
254    lambda { stream.render }.
255    should raise_error { |error|
256      error.to_s.should == %q<operation (replace @ 3..5 : "foo") overlaps with previous operation (replace @ 2..4 : "xyz")>
257    }
258  end
259
260  example 'replace then replace lower indexed superset' do
261    lexer = SimpleRewriting::Lexer.new( 'abcccba' )
262    stream = ANTLR3::TokenRewriteStream.new( lexer )
263    stream.replace 2, 4, 'xyz'
264    stream.replace 1, 3, 'foo'
265    lambda { stream.render }.
266    should raise_error { |error|
267      error.to_s.should == %q<operation (replace @ 1..3 : "foo") overlaps with previous operation (replace @ 2..4 : "xyz")>
268    }
269  end
270
271end
272
273class TestRewritingWithTokenStream2 < ANTLR3::Test::Functional
274  inline_grammar( <<-END )
275    lexer grammar SimpleRewriting2;
276    options {
277        language = Ruby;
278    }
279
280    ID : 'a'..'z'+;
281    INT : '0'..'9'+;
282    SEMI : ';';
283    PLUS : '+';
284    MUL : '*';
285    ASSIGN : '=';
286    WS : ' '+;
287  END
288
289  def rewrite( input )
290    lexer = SimpleRewriting2::Lexer.new( input )
291    ANTLR3::TokenRewriteStream.new( lexer )
292  end
293
294  example 'rendering over a range' do
295    stream = rewrite 'x = 3 * 0;'
296    stream.replace 4, 8, '0'
297    stream.original_string.should == 'x = 3 * 0;'
298    stream.render.should == 'x = 0;'
299    stream.render( 0, 9 ).should == 'x = 0;'
300    stream.render( 4, 8 ).should == '0'
301  end
302
303  example 'more rendering over a range' do
304    stream = rewrite 'x = 3 * 0 + 2 * 0;'
305    stream.original_string.should == 'x = 3 * 0 + 2 * 0;'
306    stream.replace 4, 8, '0'
307    stream.render.should == 'x = 0 + 2 * 0;'
308    stream.render( 0, 17 ).should == 'x = 0 + 2 * 0;'
309    stream.render( 4, 8 ).should  == '0'
310    stream.render( 0, 8 ).should  == 'x = 0'
311    stream.render( 12, 16 ).should == '2 * 0'
312    stream.insert_after( 17, '// comment' )
313    stream.render( 12, 17 ).should == '2 * 0;// comment'
314    stream.render( 0, 8 ).should == 'x = 0'
315  end
316
317end
318