sub_diff 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 68d94bfc8c4cdd97c0ad2830274f3e62aac1703f
4
+ data.tar.gz: 9e3d83376c646399983352017abd0ed848d5c8ff
5
+ SHA512:
6
+ metadata.gz: 3326572008e2952db12ea5c5701c35bf9acdf8d2d0c54b304d722d727e1ec01a46933259d0c0c27756098f6e09fceef811b182ba2acd75d053214f8bbb22ab09
7
+ data.tar.gz: a45b5a88dbf77f7ae0667f9a0864b00fc2dffa8db331e2ca03435af66c2d0432f99d9be97edb3875d839cd7d4bc7a1d5c40810f758fd4a8fabf126b49cf12285
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ rdoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ addons:
2
+ code_climate:
3
+ repo_token: 6f133fcc28caad1e1099287a1ac4ee0ac4fb428cdd9c5cb9424be1110ef8704a
4
+
5
+ install: bundle install --jobs 3 --retry 3
6
+
7
+ rvm:
8
+ - 1.8.7
9
+ - 1.9.3
10
+ - 2.0.0
11
+ - ruby-head
12
+
13
+ script: bundle exec rspec
data/Gemfile CHANGED
@@ -1,8 +1,7 @@
1
- source 'http://www.rubygems.org'
1
+ source 'https://www.rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- group :test do
6
- gem 'rake'
7
- gem 'rdoc', '>= 2.4.2'
8
- end
5
+ unless RUBY_VERSION =~ /1\.8\./
6
+ gem 'codeclimate-test-reporter'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sub_diff (1.0.0)
5
+
6
+ GEM
7
+ remote: https://www.rubygems.org/
8
+ specs:
9
+ codeclimate-test-reporter (0.4.7)
10
+ simplecov (>= 0.7.1, < 1.0.0)
11
+ diff-lcs (1.2.5)
12
+ docile (1.1.5)
13
+ multi_json (1.11.0)
14
+ rspec (3.2.0)
15
+ rspec-core (~> 3.2.0)
16
+ rspec-expectations (~> 3.2.0)
17
+ rspec-mocks (~> 3.2.0)
18
+ rspec-core (3.2.2)
19
+ rspec-support (~> 3.2.0)
20
+ rspec-expectations (3.2.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.2.0)
23
+ rspec-mocks (3.2.1)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.2.0)
26
+ rspec-support (3.2.2)
27
+ simplecov (0.9.2)
28
+ docile (~> 1.1.0)
29
+ multi_json (~> 1.0)
30
+ simplecov-html (~> 0.9.0)
31
+ simplecov-html (0.9.0)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ codeclimate-test-reporter
38
+ rspec
39
+ sub_diff!
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Sean Huber - shuber@huberry.com
1
+ Copyright (c) 2011 Sean Huber - github@shuber.io
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # [![Sean Huber](https://cloud.githubusercontent.com/assets/2419/6550752/832d9a64-c5ea-11e4-9717-6f9aa6e023b5.png)](https://github.com/shuber) sub_diff
2
+
3
+ [![Build Status](https://secure.travis-ci.org/shuber/sub_diff.svg)](http://travis-ci.org/shuber/sub_diff) [![Code Climate](https://codeclimate.com/github/shuber/sub_diff/badges/gpa.svg)](https://codeclimate.com/github/shuber/sub_diff) [![Coverage](https://codeclimate.com/github/shuber/sub_diff/badges/coverage.svg)](https://codeclimate.com/github/shuber/sub_diff) [![Gem Version](https://badge.fury.io/rb/sub_diff.svg)](http://badge.fury.io/rb/sub_diff)
4
+
5
+ Inspect the changes of your [`String#sub`] and [`String#gsub`] replacements.
6
+
7
+ [`String#sub`]: http://ruby-doc.org//core-2.2.0/String.html#method-i-sub
8
+ [`String#gsub`]: http://ruby-doc.org//core-2.2.0/String.html#method-i-gsub
9
+
10
+ ## Installation
11
+
12
+ ```
13
+ gem install sub_diff
14
+ ```
15
+
16
+
17
+ ## Requirements
18
+
19
+ Ruby 1.8.7+
20
+
21
+
22
+ ## Usage
23
+
24
+ This gem introduces a couple new methods to [`String`](http://ruby-doc.org/core-2.2.0/String.html) objects.
25
+
26
+ * [`String#sub_diff`](http://ruby-doc.org/core-2.2.0/String.html#method-i-sub)
27
+ * [`String#gsub_diff`](http://ruby-doc.org/core-2.2.0/String.html#method-i-gsub)
28
+
29
+ These methods accept the same arguments as their `sub` and `gsub` counterparts.
30
+
31
+ ```ruby
32
+ replaced = 'this is a test'.gsub_diff(/(\S*is)/, 'replaced(\1)') #=> #<DiffCollection:0x007fc532049508>
33
+ ```
34
+
35
+ The difference is that it returns a `DiffCollection` instead. This object behaves just like a `String`.
36
+
37
+ ```ruby
38
+ puts replaced #=> "replaced(this) replaced(is) a test"
39
+ ```
40
+
41
+ But it also allows us to check if the replacement actually *changed* anything.
42
+
43
+ ```ruby
44
+ replaced.changed? #=> true
45
+ ```
46
+
47
+ For a closer look at the changes, we can iterate thru each `Diff` in the replacment.
48
+
49
+ ```ruby
50
+ replaced.each do |diff|
51
+ puts diff.inspect
52
+ end
53
+
54
+ #=> "replaced(this)"
55
+ #=> " "
56
+ #=> "replaced(is)"
57
+ #=> " a test"
58
+ ```
59
+
60
+ Each `Diff` object behaves just like a string, but also includes a few additional methods.
61
+
62
+ ```ruby
63
+ replaced.each do |diff|
64
+ puts " value: #{diff.value.inspect}"
65
+ puts "value_was: #{diff.value_was.inspect}"
66
+ puts " changed?: #{diff.changed?}"
67
+ end
68
+
69
+ #=> value: "replaced(this)"
70
+ #=> value_was: "this"
71
+ #=> changed?: true
72
+
73
+ #=> value: " "
74
+ #=> value_was: " "
75
+ #=> changed?: false
76
+
77
+ #=> value: "replaced(is)"
78
+ #=> value_was: "is"
79
+ #=> changed?: true
80
+
81
+ #=> value: " a test"
82
+ #=> value_was: " a test"
83
+ #=> changed?: false
84
+ ```
85
+
86
+
87
+ ## API
88
+
89
+ [YARD Documentation](http://www.rubydoc.info/github/shuber/sub_diff)
90
+
91
+ * `Diff#changed?`
92
+ * `Diff#value`
93
+ * `Diff#value_was`
94
+ * `DiffCollection#changed?`
95
+ * `DiffCollection#diffs`
96
+ * `DiffCollection#each`
97
+ * `DiffCollection#size`
98
+
99
+ ## Testing
100
+
101
+ ```
102
+ bundle exec rspec
103
+ ```
104
+
105
+
106
+ ## Contributing
107
+
108
+ * Fork the project.
109
+ * Make your feature addition or bug fix.
110
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
111
+ * Commit, do not mess with the version or history.
112
+ * Send me a pull request. Bonus points for topic branches.
113
+
114
+
115
+ ## License
116
+
117
+ [MIT](https://github.com/shuber/sub_diff/blob/master/LICENSE) - Copyright © 2011 Sean Huber
@@ -0,0 +1,15 @@
1
+ require 'sub_diff/diff_builder'
2
+
3
+ module SubDiff
4
+ module CoreExt
5
+ module String
6
+ def sub_diff(*args, &block)
7
+ DiffBuilder.new(self, :sub).diff(*args, &block)
8
+ end
9
+
10
+ def gsub_diff(*args, &block)
11
+ DiffBuilder.new(self, :gsub).diff(*args, &block)
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/sub_diff/diff.rb CHANGED
@@ -1,22 +1,22 @@
1
+ require 'delegate'
2
+
1
3
  module SubDiff
2
- class Diff
3
- attr_reader :value, :value_was
4
- alias_method :to_s, :value
4
+ class Diff < SimpleDelegator
5
+ attr_reader :value_was
6
+
7
+ alias_method :value, :__getobj__
5
8
 
6
9
  def initialize(value, value_was = nil)
7
- @value, @value_was = value, value_was || value
10
+ @value_was = value_was || value
11
+ super(value)
8
12
  end
9
13
 
10
14
  def changed?
11
- @changed ||= value != value_was
12
- end
13
-
14
- def method_missing(*args, &block)
15
- to_s.send(*args, &block)
15
+ value != value_was
16
16
  end
17
17
 
18
- def respond_to_missing?(method, include_private)
19
- to_s.respond_to?(method, include_private)
18
+ def empty?
19
+ value.empty? && !changed?
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -0,0 +1,34 @@
1
+ require 'forwardable'
2
+ require 'sub_diff/diff_collection'
3
+ require 'sub_diff/differ'
4
+ require 'sub_diff/gsub'
5
+
6
+ module SubDiff
7
+ class DiffBuilder < Struct.new(:string, :type)
8
+ extend Forwardable
9
+
10
+ def_delegators :instance, :diff
11
+
12
+ private
13
+
14
+ def instance
15
+ builder.new(differ)
16
+ end
17
+
18
+ def builder
19
+ Module.nesting.last.const_get(constant)
20
+ end
21
+
22
+ def constant
23
+ type.to_s.capitalize
24
+ end
25
+
26
+ def differ
27
+ Differ.new(collection, type)
28
+ end
29
+
30
+ def collection
31
+ DiffCollection.new(string)
32
+ end
33
+ end
34
+ end
@@ -1,38 +1,43 @@
1
+ require 'delegate'
2
+ require 'forwardable'
3
+ require 'sub_diff/diff'
4
+
1
5
  module SubDiff
2
- class DiffCollection
6
+ class DiffCollection < SimpleDelegator
7
+ extend Forwardable
3
8
  include Enumerable
4
9
 
5
- def initialize(diffs = [])
6
- @diffs = []
7
- diffs.each { |diff| self << diff }
8
- end
10
+ attr_reader :string, :diffs
9
11
 
10
- def <<(diff)
11
- if diff.changed? || !diff.empty?
12
- @diffs << diff
13
- @to_s = nil
14
- end
15
- self
16
- end
12
+ def_delegators :diffs, :each, :size
17
13
 
18
- def each(&block)
19
- @diffs.each(&block)
14
+ def initialize(string)
15
+ @string = string
16
+ @diffs = []
17
+ super(string)
20
18
  end
21
19
 
22
- def method_missing(*args, &block)
23
- to_s.send(*args, &block)
20
+ def changed?
21
+ diffs.any?(&:changed?)
24
22
  end
25
23
 
26
- def respond_to_missing?(method, include_private)
27
- to_s.respond_to?(method, include_private)
28
- end
24
+ def push(*args)
25
+ if args.compact.any?
26
+ diff = Diff.new(*args)
27
+ append(diff)
28
+ end
29
29
 
30
- def size
31
- @diffs.size
30
+ self
32
31
  end
32
+ alias_method :<<, :push
33
+
34
+ private
33
35
 
34
- def to_s
35
- @to_s ||= @diffs.join
36
+ def append(diff)
37
+ unless diff.empty?
38
+ diffs << diff
39
+ __setobj__(diffs.join)
40
+ end
36
41
  end
37
42
  end
38
- end
43
+ end
@@ -0,0 +1,22 @@
1
+ module SubDiff
2
+ class Differ < Struct.new(:diff_collection, :diff_method)
3
+ def diff(*args)
4
+ # Ruby 1.8.7 does not support additional args after * (splat)
5
+ block = args.pop
6
+
7
+ differ.call(args.first) do |match|
8
+ diff = { :match => match, :prefix => $`, :suffix => $' }
9
+ diff[:replacement] = match.sub(*args, &block)
10
+ yield(diff_collection, diff)
11
+ end
12
+
13
+ diff_collection
14
+ end
15
+
16
+ private
17
+
18
+ def differ
19
+ diff_collection.string.method(diff_method)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'sub_diff/sub'
2
+
3
+ module SubDiff
4
+ class Gsub < Sub
5
+ private
6
+
7
+ def diff!(_builder, diff, _search)
8
+ super
9
+ last_prefix << prefix(diff) << diff[:match]
10
+ end
11
+
12
+ def last_prefix
13
+ @last_prefix ||= ''
14
+ end
15
+
16
+ def prefix(_diff)
17
+ super.sub(last_prefix, '')
18
+ end
19
+
20
+ def suffix(_diff, search)
21
+ matcher = suffix_matcher(search)
22
+ super unless super.send(matcher, search)
23
+ end
24
+
25
+ def suffix_matcher(search)
26
+ search.is_a?(Regexp) ? :match : :include?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module SubDiff
2
+ class Sub < Struct.new(:differ)
3
+ def diff(*args, &block)
4
+ # Ruby 1.8.7 does not support additional args after * (splat)
5
+ args.push(block)
6
+
7
+ differ.diff(*args) do |builder, diff|
8
+ diff!(builder, diff, args.first)
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def diff!(builder, diff, search)
15
+ builder << prefix(diff)
16
+ builder.push(diff[:replacement], diff[:match])
17
+ builder << suffix(diff, search)
18
+ end
19
+
20
+ def prefix(diff)
21
+ diff[:prefix]
22
+ end
23
+
24
+ def suffix(diff, _search)
25
+ diff[:suffix]
26
+ end
27
+ end
28
+ end
@@ -1,17 +1,3 @@
1
1
  module SubDiff
2
- # Contains information about this gem's version
3
- module Version
4
- MAJOR = 0
5
- MINOR = 0
6
- PATCH = 0
7
-
8
- # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
9
- #
10
- # Example
11
- #
12
- # puts Version # '1.0.2'
13
- def self.to_s
14
- [MAJOR, MINOR, PATCH].join('.')
15
- end
16
- end
17
- end
2
+ VERSION = '1.0.0'
3
+ end
data/lib/sub_diff.rb CHANGED
@@ -1,39 +1,4 @@
1
- require 'respond_to_missing'
1
+ require 'sub_diff/core_ext/string'
2
+ require 'sub_diff/version'
2
3
 
3
- module SubDiff
4
- autoload :Diff, 'sub_diff/diff'
5
- autoload :DiffCollection, 'sub_diff/diff_collection'
6
- autoload :Version, 'sub_diff/version'
7
-
8
- def gsub_diff(*args, &block)
9
- with_diff_collection do |diff_collection|
10
- match_prefix, suffix_matcher = '', args.first.is_a?(Regexp) ? :match : :include?
11
- gsub(args.first) do |match|
12
- suffix, prefix, replacement = Diff.new($'), Diff.new($`.sub(match_prefix, '')), Diff.new(match.sub(*args, &block), match)
13
- diff_collection << prefix << replacement
14
- diff_collection << suffix unless suffix.send(suffix_matcher, args.first)
15
- match_prefix << prefix + match
16
- end
17
- end
18
- end
19
-
20
- def sub_diff(*args, &block)
21
- with_diff_collection do |diff_collection|
22
- sub(args.first) do |match|
23
- suffix, prefix, replacement = Diff.new($'), Diff.new($`), Diff.new(match.sub(*args, &block), match)
24
- diff_collection << prefix << replacement << suffix
25
- end
26
- end
27
- end
28
-
29
- protected
30
-
31
- def with_diff_collection
32
- diff_collection = DiffCollection.new
33
- yield diff_collection
34
- diff_collection << Diff.new(self) if diff_collection.empty?
35
- diff_collection
36
- end
37
- end
38
-
39
- String.send(:include, SubDiff)
4
+ String.send(:include, SubDiff::CoreExt::String)
@@ -0,0 +1,78 @@
1
+ begin
2
+ if ENV['CODECLIMATE_REPO_TOKEN']
3
+ require 'codeclimate-test-reporter'
4
+ CodeClimate::TestReporter.start
5
+ else
6
+ require 'simplecov'
7
+ SimpleCov.start { add_filter('/vendor/bundle/') }
8
+ end
9
+ rescue LoadError
10
+ # Ignore when testing with Ruby 1.8.7
11
+ end
12
+
13
+ RSpec.configure do |config|
14
+ config.filter_run :focus
15
+ config.raise_errors_for_deprecations!
16
+ config.run_all_when_everything_filtered = true
17
+ end
18
+
19
+ # RSpec matcher to spec delegations.
20
+ # Forked from https://gist.github.com/ssimeonov/5942729 with fixes
21
+ # for arity + custom prefix.
22
+ #
23
+ # Usage:
24
+ #
25
+ # describe Post do
26
+ # it { should delegate(:name).to(:author).with_prefix } # post.author_name
27
+ # it { should delegate(:name).to(:author).with_prefix(:any) } # post.any_name
28
+ # it { should delegate(:month).to(:created_at) }
29
+ # it { should delegate(:year).to(:created_at) }
30
+ # it { should delegate(:something).to(:'@instance_var') }
31
+ # end
32
+ RSpec::Matchers.define :delegate do |method|
33
+ match do |delegator|
34
+ @prefix ||= nil
35
+ @method = @prefix ? :"#{@prefix}_#{method}" : method
36
+ @delegator = delegator
37
+
38
+ if @to.to_s[0] == '@'
39
+ # Delegation to an instance variable
40
+ old_value = @delegator.instance_variable_get(@to)
41
+ begin
42
+ @delegator.instance_variable_set(@to, receiver_double(method))
43
+ @delegator.send(@method) == :called
44
+ ensure
45
+ @delegator.instance_variable_set(@to, old_value)
46
+ end
47
+ elsif @delegator.respond_to?(@to, true)
48
+ unless [0,-1].include?(@delegator.method(@to).arity)
49
+ raise "#{@delegator}'s' #{@to} method does not have zero or -1 arity (it expects parameters)"
50
+ end
51
+ allow(@delegator).to receive(@to).and_return(receiver_double(method))
52
+ @delegator.send(@method) == :called
53
+ else
54
+ raise "#{@delegator} does not respond to #{@to}"
55
+ end
56
+ end
57
+
58
+ description do
59
+ "delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
60
+ end
61
+
62
+ failure_message do |text|
63
+ "expected #{@delegator} to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
64
+ end
65
+
66
+ failure_message_when_negated do |text|
67
+ "expected #{@delegator} not to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
68
+ end
69
+
70
+ chain(:to) { |receiver| @to = receiver }
71
+ chain(:with_prefix) { |prefix| @prefix = prefix || @to }
72
+
73
+ def receiver_double(method)
74
+ double('receiver').tap do |receiver|
75
+ allow(receiver).to receive(method).and_return(:called)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,74 @@
1
+ require File.expand_path('../../../lib/sub_diff/diff_collection', __FILE__)
2
+
3
+ RSpec.describe SubDiff::DiffCollection do
4
+ subject { described_class.new(diffable) }
5
+
6
+ let(:diffable) { 'this is a simple test' }
7
+
8
+ describe '#changed?' do
9
+ it 'should return true if any diffs have changed' do
10
+ subject.push('one', 'two')
11
+ expect(subject).to be_changed
12
+ end
13
+
14
+ it 'should return false if no diffs have changed' do
15
+ subject.push('same', 'same')
16
+ expect(subject).not_to be_changed
17
+ end
18
+
19
+ it 'should return false if there are no diffs' do
20
+ expect(subject).not_to be_changed
21
+ end
22
+ end
23
+
24
+ describe '#each' do
25
+ it { is_expected.to be_an(Enumerable) }
26
+ it { is_expected.to delegate(:each).to(:diffs) }
27
+ end
28
+
29
+ describe '#push' do
30
+ it 'should return self' do
31
+ expect(subject.push).to eq(subject)
32
+ end
33
+
34
+ it 'should append an unchanged diff' do
35
+ block = proc { subject.push('unchanged') }
36
+ expect(block).to change(subject.diffs, :size)
37
+ end
38
+
39
+ it 'should append a changed diff' do
40
+ block = proc { subject.push('now', 'was') }
41
+ expect(block).to change(subject.diffs, :size)
42
+ end
43
+
44
+ it 'should not append a nil diff' do
45
+ block = proc { subject.push(nil) }
46
+ expect(block).not_to change(subject.diffs, :size)
47
+ end
48
+
49
+ it 'should not append an empty diff' do
50
+ block = proc { subject.push('') }
51
+ expect(block).not_to change(subject.diffs, :size)
52
+ end
53
+ end
54
+
55
+ describe '#size' do
56
+ it { is_expected.to delegate(:size).to(:diffs) }
57
+
58
+ it 'should not use the string size' do
59
+ expect(subject.size).not_to eq(subject.to_s.size)
60
+ end
61
+ end
62
+
63
+ describe '#__getobj__' do
64
+ it 'should join the diff values if any' do
65
+ subject.push('test')
66
+ subject.push('example')
67
+ expect(subject.__getobj__).to eq('testexample')
68
+ end
69
+
70
+ it 'should return the diffable if diffs are empty' do
71
+ expect(subject.__getobj__).to eq(diffable)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path('../../../lib/sub_diff/diff', __FILE__)
2
+
3
+ RSpec.describe SubDiff::Diff do
4
+ let(:diff) { described_class.new(value, value_was) }
5
+ let(:diff_without_value_was) { described_class.new(value) }
6
+ let(:diff_with_empty_values) { described_class.new('', '') }
7
+
8
+ let(:value) { 'test' }
9
+ let(:value_was) { 'testing' }
10
+
11
+ describe '#changed?' do
12
+ it 'should return true if value does not match value_was' do
13
+ expect(diff).to be_changed
14
+ end
15
+
16
+ it 'should return false if value matches value_was' do
17
+ expect(diff_without_value_was).not_to be_changed
18
+ expect(diff_with_empty_values).not_to be_changed
19
+ end
20
+ end
21
+
22
+ describe '#empty?' do
23
+ it 'should return false if the diff was changed' do
24
+ expect(diff).not_to be_empty
25
+ end
26
+
27
+ it 'should return false if the diff value is not empty' do
28
+ expect(diff_without_value_was).not_to be_empty
29
+ end
30
+
31
+ it 'should return true if the diff was not changed and is empty' do
32
+ expect(diff_with_empty_values).to be_empty
33
+ end
34
+ end
35
+
36
+ describe '#value' do
37
+ it 'should return the diff value' do
38
+ expect(diff.value).to eq(value)
39
+ end
40
+ end
41
+
42
+ describe '#value_was' do
43
+ it 'should accept value_was' do
44
+ expect(diff.value_was).to eq(value_was)
45
+ end
46
+
47
+ it 'should set value_was to value if it is not specified' do
48
+ expect(diff_without_value_was.value_was).to eq(value)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../../lib/sub_diff', __FILE__)
2
+
3
+ RSpec.describe SubDiff do
4
+ subject { 'this is a simple test' }
5
+
6
+ describe '#sub_diff' do
7
+ context 'with a string' do
8
+ it 'should process arguments correctly' do
9
+ result = subject.sub_diff('simple', 'very simple')
10
+ expect(result.to_s).to eq('this is a very simple test')
11
+ expect(result.size).to eq(3)
12
+ end
13
+
14
+ it 'should handle no matches correctly' do
15
+ result = subject.sub_diff('no-match', 'test')
16
+ expect(result.to_s).to eq(subject)
17
+ expect(result.size).to eq(0)
18
+ end
19
+ end
20
+
21
+ context 'with a regex' do
22
+ it 'should process arguments correctly' do
23
+ result = subject.sub_diff(/a \S+/, 'an easy')
24
+ expect(result.to_s).to eq('this is an easy test')
25
+ expect(result.size).to eq(3)
26
+ end
27
+
28
+ it 'should handle captures correctly' do
29
+ result = subject.sub_diff(/a (\S+)/, 'a very \1')
30
+ expect(result.to_s).to eq('this is a very simple test')
31
+ expect(result.size).to eq(3)
32
+ end
33
+ end
34
+
35
+ context 'with a block' do
36
+ it 'should process arguments correctly' do
37
+ result = subject.sub_diff('simple') { |match| 'block' }
38
+ expect(result.to_s).to eq('this is a block test')
39
+ expect(result.size).to eq(3)
40
+ end
41
+ end
42
+
43
+ if RUBY_VERSION > '1.8.7'
44
+ context 'with a hash' do
45
+ it 'should process arguments correctly' do
46
+ result = subject.sub_diff(/simple/, 'simple' => 'harder')
47
+ expect(result.to_s).to eq('this is a harder test')
48
+ expect(result.size).to eq(3)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe '#gsub_diff' do
55
+ context 'with a string' do
56
+ it 'should process arguments correctly' do
57
+ result = subject.gsub_diff('i', 'x')
58
+ expect(result.to_s).to eq('thxs xs a sxmple test')
59
+ expect(result.size).to eq(7)
60
+ end
61
+
62
+ it 'should handle no matches correctly' do
63
+ result = subject.gsub_diff('no-match', 'test')
64
+ expect(result.to_s).to eq(subject)
65
+ expect(result.size).to eq(0)
66
+ end
67
+ end
68
+
69
+ context 'with a regex' do
70
+ it 'should process arguments correctly' do
71
+ result = subject.gsub_diff(/(\S*is)/, 'X')
72
+ expect(result.to_s).to eq('X X a simple test')
73
+ expect(result.size).to eq(4)
74
+ end
75
+
76
+ it 'should handle captures correctly' do
77
+ result = subject.gsub_diff(/(\S*is)/, 'X(\1)')
78
+ expect(result.to_s).to eq('X(this) X(is) a simple test')
79
+ expect(result.size).to eq(4)
80
+ end
81
+ end
82
+
83
+ context 'with a block' do
84
+ it 'should process arguments correctly' do
85
+ result = subject.gsub_diff('i') { |match| 'x' }
86
+ expect(result.to_s).to eq('thxs xs a sxmple test')
87
+ expect(result.size).to eq(7)
88
+ end
89
+ end
90
+
91
+ if RUBY_VERSION > '1.8.7'
92
+ context 'with a hash' do
93
+ it 'should process arguments correctly' do
94
+ result = subject.gsub_diff(/(\S*is)/, 'is' => 'IS', 'this' => 'THIS')
95
+ expect(result.to_s).to eq('THIS IS a simple test')
96
+ expect(result.size).to eq(4)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
data/sub_diff.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../lib/sub_diff/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.author = 'Sean Huber'
5
+ s.email = 'github@shuber.io'
6
+ s.extra_rdoc_files = %w(LICENSE)
7
+ s.files = `git ls-files`.split("\n")
8
+ s.homepage = 'https://github.com/shuber/sub_diff'
9
+ s.license = 'MIT'
10
+ s.name = 'sub_diff'
11
+ s.rdoc_options = %w(--charset=UTF-8 --inline-source --line-numbers --main README.md)
12
+ s.require_paths = %w(lib)
13
+ s.summary = 'Inspect the changes of your `String#sub` and `String#gsub` replacements'
14
+ s.test_files = `git ls-files -- spec/*`.split("\n")
15
+ s.version = SubDiff::VERSION
16
+
17
+ s.add_development_dependency 'rspec'
18
+ end
metadata CHANGED
@@ -1,94 +1,88 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sub_diff
3
- version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 0
10
- version: 0.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Sean Huber
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-08-16 00:00:00 -07:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: respond_to_missing
11
+ date: 2015-03-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
23
21
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
27
24
  - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
33
- type: :runtime
34
- version_requirements: *id001
35
- description: Allows you to apply regular expression replacements to strings while presenting the result in a "diff" like format
36
- email: shuber@huberry.com
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: github@shuber.io
37
29
  executables: []
38
-
39
30
  extensions: []
40
-
41
- extra_rdoc_files: []
42
-
43
- files:
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ files:
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - ".travis.yml"
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - LICENSE
40
+ - README.md
41
+ - lib/sub_diff.rb
42
+ - lib/sub_diff/core_ext/string.rb
44
43
  - lib/sub_diff/diff.rb
44
+ - lib/sub_diff/diff_builder.rb
45
45
  - lib/sub_diff/diff_collection.rb
46
+ - lib/sub_diff/differ.rb
47
+ - lib/sub_diff/gsub.rb
48
+ - lib/sub_diff/sub.rb
46
49
  - lib/sub_diff/version.rb
47
- - lib/sub_diff.rb
48
- - Gemfile
49
- - MIT-LICENSE
50
- - Rakefile
51
- - README.rdoc
52
- - test/diff_collection_test.rb
53
- - test/diff_test.rb
54
- - test/sub_diff_test.rb
55
- - test/test_helper.rb
56
- has_rdoc: true
57
- homepage: http://github.com/shuber/sub_diff
58
- licenses: []
59
-
50
+ - spec/spec_helper.rb
51
+ - spec/sub_diff/diff_collection_spec.rb
52
+ - spec/sub_diff/diff_spec.rb
53
+ - spec/sub_diff_spec.rb
54
+ - sub_diff.gemspec
55
+ homepage: https://github.com/shuber/sub_diff
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
60
59
  post_install_message:
61
- rdoc_options: []
62
-
63
- require_paths:
60
+ rdoc_options:
61
+ - "--charset=UTF-8"
62
+ - "--inline-source"
63
+ - "--line-numbers"
64
+ - "--main"
65
+ - README.md
66
+ require_paths:
64
67
  - lib
65
- required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
68
70
  - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
74
- required_rubygems_version: !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
77
75
  - - ">="
78
- - !ruby/object:Gem::Version
79
- hash: 3
80
- segments:
81
- - 0
82
- version: "0"
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
83
78
  requirements: []
84
-
85
79
  rubyforge_project:
86
- rubygems_version: 1.6.2
80
+ rubygems_version: 2.4.5
87
81
  signing_key:
88
- specification_version: 3
89
- summary: Apply regular expression replacements to strings while presenting the result in a "diff" like format
90
- test_files:
91
- - test/diff_collection_test.rb
92
- - test/diff_test.rb
93
- - test/sub_diff_test.rb
94
- - test/test_helper.rb
82
+ specification_version: 4
83
+ summary: Inspect the changes of your `String#sub` and `String#gsub` replacements
84
+ test_files:
85
+ - spec/spec_helper.rb
86
+ - spec/sub_diff/diff_collection_spec.rb
87
+ - spec/sub_diff/diff_spec.rb
88
+ - spec/sub_diff_spec.rb
data/README.rdoc DELETED
@@ -1,32 +0,0 @@
1
- = sub_diff
2
-
3
- Allows you to apply regular expression replacements to strings while presenting the result in a "diff" like format
4
-
5
- == Installation
6
-
7
- gem install sub_diff
8
-
9
-
10
- == Usage
11
-
12
- <tt>String#gsub_diff</tt> or <tt>String#sub_diff</tt> accept the same arguments as the standard <tt>gsub</tt> and <tt>sub</tt> methods, however the returned object is enumerable and allows you to iterate thru each replacement
13
-
14
- replacement = 'this is a test'.gsub_diff(/(\S*is)/, 'x(\1)')
15
-
16
- puts replacement
17
- # => x(this) x(is) a test
18
-
19
- replacement.each { |diff| puts [diff.changed?, diff.value_was.inspect, diff.value.inspect].join(' - ') }
20
- # => true - "this" - "x(this)"
21
- # => false - " " - " "
22
- # => true - "is" - "x(is)"
23
- # => false - " a test" - " a test"
24
-
25
-
26
- == Patches and pull requests
27
-
28
- * Fork the project.
29
- * Make your feature addition or bug fix.
30
- * Add tests for it. This is important so I don't break it in a future version unintentionally.
31
- * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
32
- * Send me a pull request. Bonus points for topic branches.
data/Rakefile DELETED
@@ -1,22 +0,0 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rdoc/task'
4
-
5
- desc 'Default: run unit tests'
6
- task :default => :test
7
-
8
- desc 'Test the sub_diff gem'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs += ['lib', 'test']
11
- t.pattern = 'test/**/*_test.rb'
12
- t.verbose = true
13
- end
14
-
15
- desc 'Generate documentation for the sub_diff gem'
16
- RDoc::Task.new(:rdoc) do |rdoc|
17
- rdoc.rdoc_dir = 'rdoc'
18
- rdoc.title = 'sub_diff'
19
- rdoc.options << '--line-numbers' << '--inline-source'
20
- rdoc.rdoc_files.include('README*')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
@@ -1,42 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- module SubDiff
4
- class DiffCollectionTest < Test::Unit::TestCase
5
- def setup
6
- @diffs = [Diff.new('one '), Diff.new('two', '2'), Diff.new(' three ')]
7
- @diff_collection = DiffCollection.new(@diffs)
8
- end
9
-
10
- def test_append
11
- size, value = @diff_collection.size, @diff_collection.to_s
12
- @diff_collection << Diff.new('four', '4')
13
- @diff_collection << Diff.new('', 'test')
14
- @diff_collection << Diff.new('') # should skip this since it's empty
15
- assert_equal size + 2, @diff_collection.size
16
- assert_not_equal value, @diff_collection.to_s
17
- end
18
-
19
- def test_enumerable
20
- assert @diff_collection.is_a?(Enumerable)
21
- assert_equal @diffs, @diff_collection.collect { |diff| diff }
22
- end
23
-
24
- def test_method_missing
25
- assert_equal @diffs.to_s.upcase, @diff_collection.upcase
26
- assert_raises(NoMethodError) { @diff_collection.invalid_method }
27
- end
28
-
29
- def test_respond_to_missing?
30
- assert @diff_collection.respond_to?(:upcase)
31
- assert !@diff_collection.respond_to?(:invalid_method)
32
- end
33
-
34
- def test_size
35
- assert_equal @diffs.size, @diff_collection.size
36
- end
37
-
38
- def to_s
39
- assert_equal @diffs.join, @diff_collection.to_s
40
- end
41
- end
42
- end
data/test/diff_test.rb DELETED
@@ -1,42 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- module SubDiff
4
- class DiffTest < Test::Unit::TestCase
5
- def setup
6
- @diff_value = 'test'
7
- @diff_value_was = 'testing'
8
- @diff = Diff.new(@diff_value, @diff_value_was)
9
- @diff_without_value_was = Diff.new(@diff_value)
10
- end
11
-
12
- def test_initialize_with_value_was
13
- assert_equal @diff_value, @diff.value
14
- assert_equal @diff_value_was, @diff.value_was
15
- end
16
-
17
- def test_initialize_without_value_was
18
- assert_equal @diff_value, @diff_without_value_was.value
19
- assert_equal @diff_without_value_was.value, @diff_without_value_was.value_was
20
- end
21
-
22
- def test_changed?
23
- assert @diff.changed?
24
- assert !@diff_without_value_was.changed?
25
- assert !Diff.new('test', 'test').changed?
26
- end
27
-
28
- def test_method_missing
29
- assert_equal @diff_value.upcase, @diff.upcase
30
- assert_raises(NoMethodError) { @diff.invalid_method }
31
- end
32
-
33
- def test_respond_to_missing?
34
- assert @diff.respond_to?(:upcase)
35
- assert !@diff.respond_to?(:invalid_method)
36
- end
37
-
38
- def test_to_s
39
- assert_equal @diff.value, @diff.to_s
40
- end
41
- end
42
- end
@@ -1,85 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- module SubDiff
4
- class SubDiffTest < Test::Unit::TestCase
5
- def setup
6
- @string = 'this is a simple test'
7
- end
8
-
9
- def test_gsub_diff_with_block
10
- diff_collection = @string.gsub_diff('i') { |match| 'x' }
11
- assert_equal 'thxs xs a sxmple test', diff_collection.to_s
12
- assert_equal 7, diff_collection.size
13
- end
14
-
15
- def test_gsub_diff_with_hash
16
- diff_collection = @string.gsub_diff(/(\S*is)/, 'is' => 'IS', 'this' => 'THIS')
17
- assert_equal 'THIS IS a harder test', diff_collection.to_s
18
- assert_equal 4, diff_collection.size
19
- rescue TypeError => error # Hash arguments only work in ruby 1.9+
20
- assert_equal "can't convert Hash into String", error.message
21
- end
22
-
23
- def test_gsub_diff_with_regex
24
- diff_collection = @string.gsub_diff(/(\S*is)/, 'X')
25
- assert_equal 'X X a simple test', diff_collection.to_s
26
- assert_equal 4, diff_collection.size
27
- end
28
-
29
- def test_gsub_diff_with_regex_captures
30
- diff_collection = @string.gsub_diff(/(\S*is)/, 'X(\1)')
31
- assert_equal 'X(this) X(is) a simple test', diff_collection.to_s
32
- assert_equal 4, diff_collection.size
33
- end
34
-
35
- def test_gsub_diff_with_string
36
- diff_collection = @string.gsub_diff('i', 'x')
37
- assert_equal 'thxs xs a sxmple test', diff_collection.to_s
38
- assert_equal 7, diff_collection.size
39
- end
40
-
41
- def test_gsub_diff_without_matches
42
- diff_collection = @string.gsub_diff('no-match', 'test')
43
- assert_equal @string, diff_collection.to_s
44
- assert_equal 1, diff_collection.size
45
- end
46
-
47
- def test_sub_diff_with_block
48
- diff_collection = @string.sub_diff('simple') { |match| 'block' }
49
- assert_equal 'this is a block test', diff_collection.to_s
50
- assert_equal 3, diff_collection.size
51
- end
52
-
53
- def test_sub_diff_with_hash
54
- diff_collection = @string.sub_diff(/simple/, 'simple' => 'harder')
55
- assert_equal 'this is a harder test', diff_collection.to_s
56
- assert_equal 3, diff_collection.size
57
- rescue TypeError => error # Hash arguments only work in ruby 1.9+
58
- assert_equal "can't convert Hash into String", error.message
59
- end
60
-
61
- def test_sub_diff_with_regex
62
- diff_collection = @string.sub_diff(/a \S+/, 'an easy')
63
- assert_equal 'this is an easy test', diff_collection.to_s
64
- assert_equal 3, diff_collection.size
65
- end
66
-
67
- def test_sub_diff_with_regex_captures
68
- diff_collection = @string.sub_diff(/a (\S+)/, 'a very \1')
69
- assert_equal 'this is a very simple test', diff_collection.to_s
70
- assert_equal 3, diff_collection.size
71
- end
72
-
73
- def test_sub_diff_with_string
74
- diff_collection = @string.sub_diff('simple', 'very simple')
75
- assert_equal 'this is a very simple test', diff_collection.to_s
76
- assert_equal 3, diff_collection.size
77
- end
78
-
79
- def test_sub_diff_without_matches
80
- diff_collection = @string.sub_diff('no-match', 'test')
81
- assert_equal @string, diff_collection.to_s
82
- assert_equal 1, diff_collection.size
83
- end
84
- end
85
- end
data/test/test_helper.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'test/unit'
4
-
5
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $:.unshift(File.dirname(__FILE__))
7
- require 'sub_diff'