differ 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,298 @@
1
+ require 'spec_helper'
2
+
3
+ describe Differ::Diff do
4
+ before(:each) do
5
+ $; = nil
6
+ @diff = Differ::Diff.new
7
+ end
8
+
9
+ describe '#to_s' do
10
+ before(:each) do
11
+ @format = Differ.format
12
+ end
13
+
14
+ it 'should concatenate the result list' do
15
+ diff('a', 'b', 'c').to_s.should == 'abc'
16
+ end
17
+
18
+ it 'should concatenate without regard for the $;' do
19
+ $; = '*'
20
+ diff('a', 'b', 'c').to_s.should == 'abc'
21
+ end
22
+
23
+ it 'should delegate insertion changes to Differ#format' do
24
+ i = +'b'
25
+ @format.should_receive(:format).once.with(i).and_return('!')
26
+ diff('a', i, 'c').to_s.should == 'a!c'
27
+ end
28
+ end
29
+
30
+ describe '#format_as' do
31
+ before(:each) do
32
+ @change = +'b'
33
+ Differ.format = Module.new { def self.format(c); raise :error; end }
34
+ @format = Module.new { def self.format(c); end }
35
+ end
36
+
37
+ it 'should delegate change formatting to the given format' do
38
+ @format.should_receive(:format).once.with(@change).and_return('!')
39
+ diff('a', @change, 'c').format_as(@format).should == 'a!c'
40
+ end
41
+
42
+ it 'should use Differ#format_for to grab the correct format' do
43
+ Differ.should_receive(:format_for).once.with(@format)
44
+ diff().format_as(@format)
45
+ end
46
+ end
47
+
48
+ describe '#same' do
49
+ it 'should append to the result list' do
50
+ @diff.same('c')
51
+ @diff.should == diff('c')
52
+ end
53
+
54
+ it 'should concatenate its arguments' do
55
+ @diff.same('a', 'b', 'c', 'd')
56
+ @diff.should == diff('abcd')
57
+ end
58
+
59
+ it 'should join its arguments with $;' do
60
+ $; = '*'
61
+ @diff.same(*'a*b*c*d'.split)
62
+ @diff.should == diff('a*b*c*d')
63
+ end
64
+
65
+ describe 'when the last result was a String' do
66
+ before(:each) do
67
+ @diff = diff('a')
68
+ end
69
+
70
+ it 'should append to the last result' do
71
+ @diff.same('b')
72
+ @diff.should == diff('ab')
73
+ end
74
+
75
+ it 'should join to the last result with $;' do
76
+ $; = '*'
77
+ @diff.same('b')
78
+ @diff.should == diff('a*b')
79
+ end
80
+ end
81
+
82
+ describe 'when the last result was a change' do
83
+ before(:each) do
84
+ @diff = diff('z' >> 'd')
85
+ end
86
+
87
+ it 'should append to the result list' do
88
+ @diff.same('a')
89
+ @diff.should == diff(('z' >> 'd'), 'a')
90
+ end
91
+
92
+ it 'should prepend $; to the result' do
93
+ $; = '*'
94
+ @diff.same('a')
95
+ @diff.should == diff(('z' >> 'd'), '*a')
96
+ end
97
+
98
+ it "should do nothing to a leading $; on the insert" do
99
+ @diff = diff('a', ('*-' >> '*+'))
100
+ $; = '*'
101
+ @diff.same('c')
102
+ @diff.should == diff('a', ('*-' >> '*+'), '*c')
103
+ end
104
+ end
105
+
106
+ describe 'when the last result was just a delete' do
107
+ before(:each) do
108
+ @diff = diff(-'z')
109
+ end
110
+
111
+ it 'should append to the result list' do
112
+ @diff.same('a')
113
+ @diff.should == diff(-'z', 'a')
114
+ end
115
+
116
+ it 'should append $; to the previous result' do
117
+ $; = '*'
118
+ @diff.same('a')
119
+ @diff.should == diff(-'z*', 'a')
120
+ end
121
+
122
+ it "should relocate a leading $; on the delete to the previous item" do
123
+ @diff = diff('a', -'*b')
124
+ $; = '*'
125
+ @diff.same('c')
126
+ @diff.should == diff('a*', -'b*', 'c')
127
+ end
128
+ end
129
+
130
+ describe 'when the last result was just an insert' do
131
+ before(:each) do
132
+ @diff = diff(+'z')
133
+ end
134
+
135
+ it 'should append to the result list' do
136
+ @diff.same('a')
137
+ @diff.should == diff(+'z', 'a')
138
+ end
139
+
140
+ it 'should append $; to the previous result' do
141
+ $; = '*'
142
+ @diff.same('a')
143
+ @diff.should == diff(+'z*', 'a')
144
+ end
145
+
146
+ it "should relocate a leading $; on the insert to the previous item" do
147
+ @diff = diff('a', +'*b')
148
+ $; = '*'
149
+ @diff.same('c')
150
+ @diff.should == diff('a*', +'b*', 'c')
151
+ end
152
+ end
153
+ end
154
+
155
+ describe '#delete' do
156
+ it 'should append to the result list' do
157
+ @diff.delete('c')
158
+ @diff.should == diff(-'c')
159
+ end
160
+
161
+ it 'should concatenate its arguments' do
162
+ @diff.delete('a', 'b', 'c', 'd')
163
+ @diff.should == diff(-'abcd')
164
+ end
165
+
166
+ it 'should join its arguments with $;' do
167
+ $; = '*'
168
+ @diff.delete(*'a*b*c*d'.split)
169
+ @diff.should == diff(-'a*b*c*d')
170
+ end
171
+
172
+ describe 'when the last result was a Change' do
173
+ describe '(delete)' do
174
+ before(:each) do
175
+ @diff = diff(-'a')
176
+ end
177
+
178
+ it 'should append to the last result' do
179
+ @diff.delete('b')
180
+ @diff.should == diff(-'ab')
181
+ end
182
+
183
+ it 'should join to the last result with $;' do
184
+ $; = '*'
185
+ @diff.delete('b')
186
+ @diff.should == diff(-'a*b')
187
+ end
188
+ end
189
+
190
+ describe '(insert)' do
191
+ before(:each) do
192
+ @diff = diff(+'a')
193
+ end
194
+
195
+ it "should turn the insert into a change" do
196
+ @diff.delete('b')
197
+ @diff.should == diff('b' >> 'a')
198
+ end
199
+
200
+ it "should relocate a leading $; on the insert to the previous item" do
201
+ @diff = diff('a', +'*b')
202
+ $; = '*'
203
+ @diff.delete('z')
204
+ @diff.should == diff('a*', ('z' >> 'b'))
205
+ end
206
+ end
207
+ end
208
+
209
+ describe 'when the last result was not a Change' do
210
+ before(:each) do
211
+ @diff = diff('a')
212
+ end
213
+
214
+ it 'should append a Change to the result list' do
215
+ @diff.delete('b')
216
+ @diff.should == diff('a', -'b')
217
+ end
218
+
219
+ it 'should prepend $; to the result' do
220
+ $; = '*'
221
+ @diff.delete('b')
222
+ @diff.should == diff('a', -'*b')
223
+ end
224
+ end
225
+ end
226
+
227
+ describe '#insert' do
228
+ it 'should append to the result list' do
229
+ @diff.insert('c')
230
+ @diff.should == diff(+'c')
231
+ end
232
+
233
+ it 'should concatenate its arguments' do
234
+ @diff.insert('a', 'b', 'c', 'd')
235
+ @diff.should == diff(+'abcd')
236
+ end
237
+
238
+ it 'should join its arguments with $;' do
239
+ $; = '*'
240
+ @diff.insert(*'a*b*c*d'.split)
241
+ @diff.should == diff(+'a*b*c*d')
242
+ end
243
+
244
+ describe 'when the last result was a Change' do
245
+ describe '(delete)' do
246
+ before(:each) do
247
+ @diff = diff(-'b')
248
+ end
249
+
250
+ it "should not change the 'insert' portion of the last result" do
251
+ @diff.insert('a')
252
+ @diff.should == diff('b' >> 'a')
253
+ end
254
+
255
+ it "should relocate a leading $; on the delete to the previous item" do
256
+ @diff = diff('a', -'*b')
257
+ $; = '*'
258
+ @diff.insert('z')
259
+ @diff.should == diff('a*', ('b' >> 'z'))
260
+ end
261
+ end
262
+
263
+ describe '(insert)' do
264
+ before(:each) do
265
+ @diff = diff(+'a')
266
+ end
267
+
268
+ it 'should append to the last result' do
269
+ @diff.insert('b')
270
+ @diff.should == diff(+'ab')
271
+ end
272
+
273
+ it 'should join to the last result with $;' do
274
+ $; = '*'
275
+ @diff.insert('b')
276
+ @diff.should == diff(+'a*b')
277
+ end
278
+ end
279
+ end
280
+
281
+ describe 'when the last result was not a Change' do
282
+ before(:each) do
283
+ @diff = diff('a')
284
+ end
285
+
286
+ it 'should append a Change to the result list' do
287
+ @diff.insert('b')
288
+ @diff.should == diff('a', +'b')
289
+ end
290
+
291
+ it 'should prepend $; to the result' do
292
+ $; = '*'
293
+ @diff.insert('b')
294
+ @diff.should == diff('a', +'*b')
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Differ::Format::Ascii do
4
+ it 'should format inserts well' do
5
+ @expected = '{+"SAMPLE"}'
6
+ Differ::Format::Ascii.format(+'SAMPLE').should == @expected
7
+ end
8
+
9
+ it 'should format deletes well' do
10
+ @expected = '{-"SAMPLE"}'
11
+ Differ::Format::Ascii.format(-'SAMPLE').should == @expected
12
+ end
13
+
14
+ it 'should format changes well' do
15
+ @expected = '{"THEN" >> "NOW"}'
16
+ Differ::Format::Ascii.format('THEN' >> 'NOW').should == @expected
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Differ::Format::Color do
4
+ it 'should format inserts well' do
5
+ @expected = "\033[32mSAMPLE\033[0m"
6
+ Differ::Format::Color.format(+'SAMPLE').should == @expected
7
+ end
8
+
9
+ it 'should format deletes well' do
10
+ @expected = "\033[31mSAMPLE\033[0m"
11
+ Differ::Format::Color.format(-'SAMPLE').should == @expected
12
+ end
13
+
14
+ it 'should format changes well' do
15
+ @expected = "\033[31mTHEN\033[0m\033[32mNOW\033[0m"
16
+ Differ::Format::Color.format('THEN' >> 'NOW').should == @expected
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Differ::Format::HTML do
4
+ it 'should format inserts well' do
5
+ @expected = '<ins class="differ">SAMPLE</ins>'
6
+ Differ::Format::HTML.format(+'SAMPLE').should == @expected
7
+ end
8
+
9
+ it 'should format deletes well' do
10
+ @expected = '<del class="differ">SAMPLE</del>'
11
+ Differ::Format::HTML.format(-'SAMPLE').should == @expected
12
+ end
13
+
14
+ it 'should format changes well' do
15
+ @expected = '<del class="differ">THEN</del><ins class="differ">NOW</ins>'
16
+ Differ::Format::HTML.format('THEN' >> 'NOW').should == @expected
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'differ/string'
3
+
4
+ describe Differ::StringDiffer do
5
+ it 'should be automatically mixed into String' do
6
+ String.included_modules.should include(Differ::StringDiffer)
7
+ end
8
+
9
+ before(:each) do
10
+ $; = nil
11
+ end
12
+
13
+ describe '#diff' do
14
+ it 'should call Differ#diff' do
15
+ Differ.should_receive(:diff).with('TO', 'FROM', "\n").once
16
+ 'TO'.diff('FROM')
17
+ end
18
+
19
+ it 'should call Differ#diff with $;' do
20
+ $; = 'x'
21
+ Differ.should_receive(:diff).with('TO', 'FROM', $;).once
22
+ 'TO'.diff('FROM')
23
+ end
24
+ end
25
+
26
+ describe '#-' do
27
+ it 'should call Differ#diff' do
28
+ Differ.should_receive(:diff).with('TO', 'FROM', "\n").once
29
+ 'TO' - 'FROM'
30
+ end
31
+
32
+ it 'should call Differ#diff with $;' do
33
+ $; = 'x'
34
+ Differ.should_receive(:diff).with('TO', 'FROM', $;).once
35
+ 'TO' - 'FROM'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,512 @@
1
+ require 'spec_helper'
2
+
3
+ describe Differ do
4
+ describe '#format' do
5
+ before(:each) { Differ.format = nil }
6
+
7
+ it 'should return the last value it was set to' do
8
+ Differ.format = Differ::Format::HTML
9
+ Differ.format.should == Differ::Format::HTML
10
+ end
11
+
12
+ it 'should default to Differ::Format::Ascii' do
13
+ Differ.format.should == Differ::Format::Ascii
14
+ end
15
+ end
16
+
17
+ describe '#format=' do
18
+ it 'should call #format_for with the passed argument' do
19
+ Differ.should_receive(:format_for).with(:format).once
20
+ Differ.format = :format
21
+ end
22
+
23
+ it 'should raise an error on undefined behavior' do
24
+ lambda {
25
+ Differ.format = 'threeve'
26
+ }.should raise_error('Unknown format type "threeve"')
27
+ end
28
+ end
29
+
30
+ describe '#format_for' do
31
+ before(:each) { Differ.format = nil }
32
+
33
+ it 'should store any module passed to it' do
34
+ formatter = Module.new
35
+ Differ.format_for(formatter).should == formatter
36
+ end
37
+
38
+ it 'should permit nil (default behavior)' do
39
+ Differ.format_for(nil).should == nil
40
+ end
41
+
42
+ it 'should raise an error on undefined behavior' do
43
+ lambda {
44
+ Differ.format_for('threeve')
45
+ }.should raise_error('Unknown format type "threeve"')
46
+ end
47
+
48
+ describe 'when passed a symbol' do
49
+ it 'should translate the symbol :ascii into Differ::Format::Ascii' do
50
+ Differ.format_for(:ascii).should == Differ::Format::Ascii
51
+ end
52
+
53
+ it 'should translate the symbol :color into Differ::Format::Color' do
54
+ Differ.format_for(:color).should == Differ::Format::Color
55
+ end
56
+
57
+ it 'should translate the symbol :html into Differ::Format::HTML' do
58
+ Differ.format_for(:html).should == Differ::Format::HTML
59
+ end
60
+ end
61
+ end
62
+
63
+ describe '#diff_by_char' do
64
+ def diff_by_char
65
+ Differ.send(:diff_by_char, @to, @from)
66
+ end
67
+
68
+ before(:each) do
69
+ @to = @from = 'self'
70
+ end
71
+
72
+ it 'should hande no-change situations' do
73
+ @expected = diff('self')
74
+ diff_by_char.should == @expected
75
+ end
76
+
77
+ it 'should handle prepends' do
78
+ @to = "myself"
79
+ @expected = diff(+'my', 'self')
80
+ diff_by_char.should == @expected
81
+ end
82
+
83
+ it 'should handle appends' do
84
+ @to = 'self-interest'
85
+ @expected = diff('self', +'-interest')
86
+ diff_by_char.should == @expected
87
+ end
88
+
89
+ it 'should handle leading deletes' do
90
+ @to = 'elf'
91
+ @expected = diff(-'s', 'elf')
92
+ diff_by_char.should == @expected
93
+ end
94
+
95
+ it 'should handle trailing deletes' do
96
+ @to = 'sel'
97
+ @expected = diff('sel', -'f')
98
+ diff_by_char.should == @expected
99
+ end
100
+
101
+ it 'should handle simultaneous leading changes' do
102
+ @to = 'wood-elf'
103
+ @expected = diff(('s' >> 'wood-'), 'elf')
104
+ diff_by_char.should == @expected
105
+ end
106
+
107
+ it 'should handle simultaneous trailing changes' do
108
+ @to = "seasoning"
109
+ @expected = diff('se', ('lf' >> 'asoning'))
110
+ diff_by_char.should == @expected
111
+ end
112
+
113
+ it 'should handle full-string changes' do
114
+ @to = 'turgid'
115
+ @expected = diff('self' >> 'turgid')
116
+ diff_by_char.should == @expected
117
+ end
118
+
119
+ it 'should handle complex string additions' do
120
+ @to = 'my sleeplife'
121
+ @expected = diff(+'my ', 's', +'l', 'e', +'ep', 'l', +'i', 'f', +'e')
122
+ diff_by_char.should == @expected
123
+ end
124
+
125
+ it 'should handle complex string deletions' do
126
+ @from = 'my sleeplife'
127
+ @expected = diff(-'my ', 's', -'l', 'e', -'ep', 'l', -'i', 'f', -'e')
128
+ diff_by_char.should == @expected
129
+ end
130
+
131
+ it 'should handle complex string changes' do
132
+ @from = 'my sleeplife'
133
+ @to = 'seasonal'
134
+ @expected = diff(-'my ', 's', -'l', 'e', ('ep' >> 'asona'), 'l', -'ife')
135
+ diff_by_char.should == @expected
136
+ end
137
+ end
138
+
139
+ describe '#diff_by_word' do
140
+ def diff_by_word
141
+ Differ.send(:diff_by_word, @to, @from)
142
+ end
143
+
144
+ before(:each) do
145
+ @to = @from = 'the daylight will come'
146
+ end
147
+
148
+ it 'should hande no-change situations' do
149
+ @expected = diff('the daylight will come')
150
+ diff_by_word.should == @expected
151
+ end
152
+
153
+ it 'should handle prepends' do
154
+ @to = "surely the daylight will come"
155
+ @expected = diff(+'surely ', 'the daylight will come')
156
+ diff_by_word.should == @expected
157
+ end
158
+
159
+ it 'should handle appends' do
160
+ @to = 'the daylight will come in the morning'
161
+ @expected = diff('the daylight will come', +' in the morning')
162
+ diff_by_word.should == @expected
163
+ end
164
+
165
+ it 'should handle leading deletes' do
166
+ @to = 'daylight will come'
167
+ @expected = diff(-'the ', 'daylight will come')
168
+ diff_by_word.should == @expected
169
+ end
170
+
171
+ it 'should handle trailing deletes' do
172
+ @to = 'the daylight'
173
+ @expected = diff('the daylight', -' will come')
174
+ diff_by_word.should == @expected
175
+ end
176
+
177
+ it 'should handle simultaneous leading changes' do
178
+ @to = 'some daylight will come'
179
+ @expected = diff(('the' >> 'some'), ' daylight will come')
180
+ diff_by_word.should == @expected
181
+ end
182
+
183
+ it 'should handle simultaneous trailing changes' do
184
+ @to = "the daylight will flood the room"
185
+ @expected = diff('the daylight will ', ('come' >> 'flood the room'))
186
+ diff_by_word.should == @expected
187
+ end
188
+
189
+ it 'should handle full-string changes' do
190
+ @to = 'if we should expect it'
191
+ @expected = diff(
192
+ ('the' >> 'if'),
193
+ ' ',
194
+ ('daylight' >> 'we'),
195
+ ' ',
196
+ ('will' >> 'should'),
197
+ ' ',
198
+ ('come' >> 'expect it')
199
+ )
200
+ diff_by_word.should == @expected
201
+ end
202
+
203
+ it 'should handle complex string additions' do
204
+ @to = 'the fresh daylight will surely come'
205
+ @expected = diff('the ', +'fresh ', 'daylight will ', +'surely ', 'come')
206
+ diff_by_word.should == @expected
207
+ end
208
+
209
+ it 'should handle complex string deletions' do
210
+ @from = 'the fresh daylight will surely come'
211
+ @expected = diff('the ', -'fresh ', 'daylight will ', -'surely ', 'come')
212
+ diff_by_word.should == @expected
213
+ end
214
+
215
+ it 'should handle complex string changes' do
216
+ @from = 'the fresh daylight will surely come'
217
+ @to = 'something fresh will become surly'
218
+ @expected = diff(
219
+ ('the' >> 'something'),
220
+ ' fresh ',
221
+ -'daylight ',
222
+ 'will ',
223
+ ( 'surely' >> 'become'),
224
+ ' ',
225
+ ( 'come' >> 'surly' )
226
+ )
227
+ diff_by_word.should == @expected
228
+ end
229
+ end
230
+
231
+ describe '#diff_by_line' do
232
+ def diff_by_line
233
+ Differ.send(:diff_by_line, @to, @from)
234
+ end
235
+
236
+ before(:each) do
237
+ @to = @from = <<-HAIKU.gsub(/ +|\n\Z/, '')
238
+ stallion sinks gently
239
+ slowly, sleeplessly
240
+ following harp flails
241
+ HAIKU
242
+ end
243
+
244
+ it 'should hande no-change situations' do
245
+ @expected = diff(@to)
246
+ diff_by_line.should == @expected
247
+ end
248
+
249
+ it 'should handle prepends' do
250
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
251
+ A Haiku:
252
+ stallion sinks gently
253
+ slowly, sleeplessly
254
+ following harp flails
255
+ HAIKU
256
+ @expected = diff(+"A Haiku:\n", @from)
257
+ diff_by_line.should == @expected
258
+ end
259
+
260
+ it 'should handle appends' do
261
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
262
+ stallion sinks gently
263
+ slowly, sleeplessly
264
+ following harp flails
265
+ -- http://everypoet.net
266
+ HAIKU
267
+ @expected = diff(@from, +"\n-- http://everypoet.net")
268
+ diff_by_line.should == @expected
269
+ end
270
+
271
+ it 'should handle leading deletes' do
272
+ @from = <<-HAIKU.gsub(/ +|\n\Z/, '')
273
+ A Haiku:
274
+ stallion sinks gently
275
+ slowly, sleeplessly
276
+ following harp flails
277
+ HAIKU
278
+ @expected = diff(-"A Haiku:\n", @to)
279
+ diff_by_line.should == @expected
280
+ end
281
+
282
+ it 'should handle trailing deletes' do
283
+ @from = <<-HAIKU.gsub(/ +|\n\Z/, '')
284
+ stallion sinks gently
285
+ slowly, sleeplessly
286
+ following harp flails
287
+ -- http://everypoet.net
288
+ HAIKU
289
+ @expected = diff(@to, -"\n-- http://everypoet.net")
290
+ diff_by_line.should == @expected
291
+ end
292
+
293
+ it 'should handle simultaneous leading changes' do
294
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
295
+ stallion sings gently
296
+ slowly, sleeplessly
297
+ following harp flails
298
+ HAIKU
299
+ @expected = diff(
300
+ ('stallion sinks gently' >> 'stallion sings gently'),
301
+ "\nslowly, sleeplessly" <<
302
+ "\nfollowing harp flails"
303
+ )
304
+ diff_by_line.should == @expected
305
+ end
306
+
307
+ it 'should handle simultaneous trailing changes' do
308
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
309
+ stallion sinks gently
310
+ slowly, sleeplessly
311
+ drifting ever on
312
+ HAIKU
313
+ @expected = diff(
314
+ "stallion sinks gently\n" <<
315
+ "slowly, sleeplessly\n",
316
+ ('following harp flails' >> 'drifting ever on')
317
+ )
318
+ diff_by_line.should == @expected
319
+ end
320
+
321
+ it 'should handle full-string changes' do
322
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
323
+ glumly inert coals
324
+ slumber lazily, shoulda
325
+ used more Burma Shave
326
+ HAIKU
327
+ @expected = diff(@from >> @to)
328
+ diff_by_line.should == @expected
329
+ end
330
+
331
+ it 'should handle complex string additions' do
332
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
333
+ A Haiku, with annotation:
334
+ stallion sinks gently
335
+ slowly, sleeplessly
336
+ (flailing)
337
+ following harp flails
338
+ -- modified from source
339
+ HAIKU
340
+ @expected = diff(
341
+ +"A Haiku, with annotation:\n",
342
+ "stallion sinks gently\n" <<
343
+ "slowly, sleeplessly\n",
344
+ +"(flailing)\n",
345
+ 'following harp flails',
346
+ +"\n-- modified from source"
347
+ )
348
+ diff_by_line.should == @expected
349
+ end
350
+
351
+ it 'should handle complex string deletions' do
352
+ @from = <<-HAIKU.gsub(/ +|\n\Z/, '')
353
+ A Haiku, with annotation:
354
+ stallion sinks gently
355
+ slowly, sleeplessly
356
+ (flailing)
357
+ following harp flails
358
+ -- modified from source
359
+ HAIKU
360
+ @expected = diff(
361
+ -"A Haiku, with annotation:\n",
362
+ "stallion sinks gently\n" <<
363
+ "slowly, sleeplessly\n",
364
+ -"(flailing)\n",
365
+ 'following harp flails',
366
+ -"\n-- modified from source"
367
+ )
368
+ diff_by_line.should == @expected
369
+ end
370
+
371
+ it 'should handle complex string changes' do
372
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
373
+ stallion sings gently
374
+ slowly, sleeplessly
375
+ (flailing)
376
+ following harp flails
377
+ -- modified from source
378
+ HAIKU
379
+ @expected = diff(
380
+ ('stallion sinks gently' >> 'stallion sings gently'),
381
+ "\nslowly, sleeplessly\n",
382
+ +"(flailing)\n",
383
+ 'following harp flails',
384
+ +"\n-- modified from source"
385
+ )
386
+ diff_by_line.should == @expected
387
+ end
388
+ end
389
+
390
+ describe '#diff (with arbitrary boundary)' do
391
+ def diff_by_comma
392
+ Differ.send(:diff, @to, @from, ', ')
393
+ end
394
+
395
+ before(:each) do
396
+ @to = @from = 'alteration, asymmetry, a deviation'
397
+ end
398
+
399
+ it 'should hande no-change situations' do
400
+ @expected = diff('alteration, asymmetry, a deviation')
401
+ diff_by_comma.should == @expected
402
+ end
403
+
404
+ it 'should handle prepends' do
405
+ @to = "aberration, alteration, asymmetry, a deviation"
406
+ @expected = diff(+'aberration, ', 'alteration, asymmetry, a deviation')
407
+ diff_by_comma.should == @expected
408
+ end
409
+
410
+ it 'should handle appends' do
411
+ @to = "alteration, asymmetry, a deviation, change"
412
+ @expected = diff('alteration, asymmetry, a deviation', +', change')
413
+ diff_by_comma.should == @expected
414
+ end
415
+
416
+ it 'should handle leading deletes' do
417
+ @to = 'asymmetry, a deviation'
418
+ @expected = diff(-'alteration, ', 'asymmetry, a deviation')
419
+ diff_by_comma.should == @expected
420
+ end
421
+
422
+ it 'should handle trailing deletes' do
423
+ @to = 'alteration, asymmetry'
424
+ @expected = diff('alteration, asymmetry', -', a deviation')
425
+ diff_by_comma.should == @expected
426
+ end
427
+
428
+ it 'should handle simultaneous leading changes' do
429
+ @to = 'aberration, asymmetry, a deviation'
430
+ @expected = diff(('alteration' >> 'aberration'), ', asymmetry, a deviation')
431
+ diff_by_comma.should == @expected
432
+ end
433
+
434
+ it 'should handle simultaneous trailing changes' do
435
+ @to = 'alteration, asymmetry, change'
436
+ @expected = diff('alteration, asymmetry, ', ('a deviation' >> 'change'))
437
+ diff_by_comma.should == @expected
438
+ end
439
+
440
+ it 'should handle full-string changes' do
441
+ @to = 'uniformity, unison, unity'
442
+ @expected = diff(@from >> @to)
443
+ diff_by_comma.should == @expected
444
+ end
445
+
446
+ it 'should handle complex string additions' do
447
+ @to = 'aberration, alteration, anomaly, asymmetry, a deviation, change'
448
+ @expected = diff(
449
+ +'aberration, ',
450
+ 'alteration, ',
451
+ +'anomaly, ',
452
+ 'asymmetry, a deviation',
453
+ +', change'
454
+ )
455
+ diff_by_comma.should == @expected
456
+ end
457
+
458
+ it 'should handle complex string deletions' do
459
+ @from = 'aberration, alteration, anomaly, asymmetry, a deviation, change'
460
+ @expected = diff(
461
+ -'aberration, ',
462
+ 'alteration, ',
463
+ -'anomaly, ',
464
+ 'asymmetry, a deviation',
465
+ -', change'
466
+ )
467
+ diff_by_comma.should == @expected
468
+ end
469
+
470
+ it 'should handle complex string changes' do
471
+ @from = 'a, d, g, gh, x'
472
+ @to = 'a, b, c, d, e, f, g, h, i, j'
473
+ @expected = diff(
474
+ 'a, ',
475
+ +'b, c, ',
476
+ 'd, ',
477
+ +'e, f, ',
478
+ 'g, ',
479
+ ('gh, x' >> 'h, i, j')
480
+ )
481
+ diff_by_comma.should == @expected
482
+ end
483
+ end
484
+
485
+ describe '#diff (with implied boundary)' do
486
+ def diff_by_line
487
+ Differ.send(:diff, @to, @from)
488
+ end
489
+
490
+ before(:each) do
491
+ @to = @from = <<-HAIKU.gsub(/ +|\n\Z/, '')
492
+ stallion sinks gently
493
+ slowly, sleeplessly
494
+ following harp flails
495
+ HAIKU
496
+ end
497
+
498
+ it 'should do diffs by line' do
499
+ @to = <<-HAIKU.gsub(/ +|\n\Z/, '')
500
+ stallion sinks gently
501
+ slowly, restlessly
502
+ following harp flails
503
+ HAIKU
504
+ @expected = diff(
505
+ "stallion sinks gently\n",
506
+ ('slowly, sleeplessly' >> 'slowly, restlessly'),
507
+ "\nfollowing harp flails"
508
+ )
509
+ diff_by_line.should == @expected
510
+ end
511
+ end
512
+ end