ninja-differ 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ expect(Differ.format).to eq(Differ::Format::HTML)
10
+ end
11
+
12
+ it 'should default to Differ::Format::Ascii' do
13
+ expect(Differ.format).to eq(Differ::Format::Ascii)
14
+ end
15
+ end
16
+
17
+ describe '#format=' do
18
+ it 'should call #format_for with the passed argument' do
19
+ expect(Differ).to receive(:format_for).with(:format).once
20
+ Differ.format = :format
21
+ end
22
+
23
+ it 'should raise an error on undefined behavior' do
24
+ expect {
25
+ Differ.format = 'threeve'
26
+ }.to 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 callable passed to it' do
34
+ formatter = ->(c){ c.to_s }
35
+ expect(Differ.format_for(formatter)).to eq(formatter)
36
+ end
37
+
38
+ it 'should permit nil (default behavior)' do
39
+ expect(Differ.format_for(nil)).to eq(nil)
40
+ end
41
+
42
+ it 'should raise an error on undefined behavior' do
43
+ expect {
44
+ Differ.format_for('threeve')
45
+ }.to 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
+ expect(Differ.format_for(:ascii)).to eq(Differ::Format::Ascii)
51
+ end
52
+
53
+ it 'should translate the symbol :color into Differ::Format::Color' do
54
+ expect(Differ.format_for(:color)).to eq(Differ::Format::Color)
55
+ end
56
+
57
+ it 'should translate the symbol :html into Differ::Format::HTML' do
58
+ expect(Differ.format_for(:html)).to eq(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
+ expect(diff_by_char).to eq(@expected)
75
+ end
76
+
77
+ it 'should handle prepends' do
78
+ @to = "myself"
79
+ @expected = diff(+'my', 'self')
80
+ expect(diff_by_char).to eq(@expected)
81
+ end
82
+
83
+ it 'should handle appends' do
84
+ @to = 'self-interest'
85
+ @expected = diff('self', +'-interest')
86
+ expect(diff_by_char).to eq(@expected)
87
+ end
88
+
89
+ it 'should handle leading deletes' do
90
+ @to = 'elf'
91
+ @expected = diff(-'s', 'elf')
92
+ expect(diff_by_char).to eq(@expected)
93
+ end
94
+
95
+ it 'should handle trailing deletes' do
96
+ @to = 'sel'
97
+ @expected = diff('sel', -'f')
98
+ expect(diff_by_char).to eq(@expected)
99
+ end
100
+
101
+ it 'should handle simultaneous leading changes' do
102
+ @to = 'wood-elf'
103
+ @expected = diff(('s' >> 'wood-'), 'elf')
104
+ expect(diff_by_char).to eq(@expected)
105
+ end
106
+
107
+ it 'should handle simultaneous trailing changes' do
108
+ @to = "seasoning"
109
+ @expected = diff('se', ('lf' >> 'asoning'))
110
+ expect(diff_by_char).to eq(@expected)
111
+ end
112
+
113
+ it 'should handle full-string changes' do
114
+ @to = 'turgid'
115
+ @expected = diff('self' >> 'turgid')
116
+ expect(diff_by_char).to eq(@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
+ expect(diff_by_char).to eq(@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
+ expect(diff_by_char).to eq(@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
+ expect(diff_by_char).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@expected)
163
+ end
164
+
165
+ it 'should handle leading deletes' do
166
+ @to = 'daylight will come'
167
+ @expected = diff(-'the ', 'daylight will come')
168
+ expect(diff_by_word).to eq(@expected)
169
+ end
170
+
171
+ it 'should handle trailing deletes' do
172
+ @to = 'the daylight'
173
+ @expected = diff('the daylight', -' will come')
174
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_word).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_line).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@expected)
414
+ end
415
+
416
+ it 'should handle leading deletes' do
417
+ @to = 'asymmetry, a deviation'
418
+ @expected = diff(-'alteration, ', 'asymmetry, a deviation')
419
+ expect(diff_by_comma).to eq(@expected)
420
+ end
421
+
422
+ it 'should handle trailing deletes' do
423
+ @to = 'alteration, asymmetry'
424
+ @expected = diff('alteration, asymmetry', -', a deviation')
425
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@expected)
438
+ end
439
+
440
+ it 'should handle full-string changes' do
441
+ @to = 'uniformity, unison, unity'
442
+ @expected = diff(@from >> @to)
443
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_comma).to eq(@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
+ expect(diff_by_line).to eq(@expected)
510
+ end
511
+ end
512
+ end
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'differ'
6
+
7
+ RSpec.configure do |config|
8
+ # config.order = 'random'
9
+ # config.profile_examples = 3
10
+ end
11
+
12
+ def diff(*parts)
13
+ x = Differ::Diff.new
14
+ x.instance_variable_set(:@raw, parts)
15
+ return x
16
+ end
17
+
18
+ class String
19
+ def +@
20
+ Differ::Change.new(:insert => self)
21
+ end
22
+
23
+ # this breaks rspec currently
24
+ # undefined method `call' for nil:NilClass
25
+ # def -@
26
+ # Differ::Change.new(:delete => self)
27
+ # end
28
+
29
+ def >>(to)
30
+ Differ::Change.new(:delete => self, :insert => to)
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ninja-differ
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Frank Koehl
8
+ - Pieter van de Bruggen
9
+ - Jonas Schubert Erlandsson
10
+ - Eddie Cianci
11
+ - Chad Boyd
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2022-10-26 00:00:00.000000000 Z
16
+ dependencies: []
17
+ description: A simple gem for generating string diffs
18
+ email:
19
+ - fkoehl@gmail.com
20
+ - pvande@gmail.com
21
+ - jonas.schubert.erlandsson@my-codeworks.com
22
+ - chad@txt2give.co
23
+ executables: []
24
+ extensions: []
25
+ extra_rdoc_files: []
26
+ files:
27
+ - ".gitignore"
28
+ - Gemfile
29
+ - Gemfile.lock
30
+ - LICENSE
31
+ - README.md
32
+ - Rakefile
33
+ - Vagrantfile
34
+ - differ.gemspec
35
+ - lib/differ.rb
36
+ - lib/differ/change.rb
37
+ - lib/differ/diff.rb
38
+ - lib/differ/format/ascii.rb
39
+ - lib/differ/format/color.rb
40
+ - lib/differ/format/html.rb
41
+ - lib/differ/format/patch.rb
42
+ - lib/differ/string.rb
43
+ - lib/differ/version.rb
44
+ - provision.sh
45
+ - spec/differ/change_spec.rb
46
+ - spec/differ/diff_spec.rb
47
+ - spec/differ/format/ascii_spec.rb
48
+ - spec/differ/format/color_spec.rb
49
+ - spec/differ/format/html_spec.rb
50
+ - spec/differ/format/patch_spec.rb
51
+ - spec/differ/string_spec.rb
52
+ - spec/differ_spec.rb
53
+ - spec/spec_helper.rb
54
+ homepage: https://github.com/BattleBrisket/ninja-differ
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.3.24
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: A simple gem for generating string diffs
77
+ test_files:
78
+ - spec/differ/change_spec.rb
79
+ - spec/differ/diff_spec.rb
80
+ - spec/differ/format/ascii_spec.rb
81
+ - spec/differ/format/color_spec.rb
82
+ - spec/differ/format/html_spec.rb
83
+ - spec/differ/format/patch_spec.rb
84
+ - spec/differ/string_spec.rb
85
+ - spec/differ_spec.rb
86
+ - spec/spec_helper.rb