sub_diff 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21eca8a2613f2283e8b2ef108dd26fcc8fff6b97
4
- data.tar.gz: 28b9f6a0700801ddcdc7968dad2c881554216697
3
+ metadata.gz: 6a95327c2f9868be0c23e279dbc32c577a4c45c2
4
+ data.tar.gz: 17c3721197874d746bc1d0377469d5971694195f
5
5
  SHA512:
6
- metadata.gz: 3dcd408aae1f8d2feee698eaf84cd0e447d7fc8fd11a91e10147dcf96714fff538eca8dfe8b397e7c916722fe78dd6b8c3813b9b574f0be2bdb66b550b4f0e7f
7
- data.tar.gz: 18145f531b6e8e73fec399c49db871ac410b5b5e1b648da6c0fa80cb061e5013663899eb72e572069269830201b4f53a2947997e5bf367403898ea8751295674
6
+ metadata.gz: dbf615e3a719b9508cff821a11c30ba6ad82adfa7d5cf9fac082b2d48975b9c6e0f630000063c0e9fe31939bce2d0ce0eac6ce9560c5e5a33ac69edf3ad86292
7
+ data.tar.gz: 35005311dee8874633c3d6e497177d316474eebc86eacf80d0ed296a90d1d5dbf78adea076ec5867f3f7fa8cdbca2028e5f296c3cdf23f779747715878f3bc6b
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sub_diff (1.1.0)
4
+ sub_diff (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://www.rubygems.org/
@@ -1,5 +1,6 @@
1
1
  require 'delegate'
2
2
  require 'forwardable'
3
+ require 'sub_diff/buildable'
3
4
  require 'sub_diff/adapter'
4
5
  require 'sub_diff/builder'
5
6
  require 'sub_diff/collection'
@@ -1,21 +1,19 @@
1
1
  module SubDiff
2
+ # Constructs an instance of {Sub} or {Gsub} to be
3
+ # used as a receiver for delegated calls to `diff`.
4
+ #
5
+ # Used internally by {Builder}.
6
+ #
7
+ # @api private
2
8
  class Adapter
3
- extend Forwardable
9
+ include Buildable
4
10
 
5
- def_delegators :differ, :builder
6
- def_delegators :builder, :diff_method
7
- def_delegators :instance, :diff
8
-
9
- attr_reader :differ
10
-
11
- def initialize(differ)
12
- @differ = differ
13
- end
11
+ def_delegators :adapter, :diff
14
12
 
15
13
  private
16
14
 
17
- def instance
18
- adapter_class.new(differ)
15
+ def adapter
16
+ adapter_class.new(builder)
19
17
  end
20
18
 
21
19
  def adapter_class
@@ -0,0 +1,22 @@
1
+ module SubDiff
2
+ # This module allows classes to accept a {Builder} object as
3
+ # an initializer argument and defines an `attr_reader` for it.
4
+ #
5
+ # It also delegates commonly used methods to the {Builder} instance.
6
+ #
7
+ # Used internally by {Adapter}, {Differ}, and {Sub}.
8
+ #
9
+ # @api private
10
+ module Buildable
11
+ attr_reader :builder
12
+
13
+ def initialize(builder)
14
+ @builder = builder
15
+ end
16
+
17
+ def self.included(base)
18
+ base.extend(Forwardable)
19
+ base.def_delegators(:builder, :diff_method, :differ, :string)
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,10 @@
1
1
  module SubDiff
2
+ # Performs a {Sub} or {Gsub} replacement and returns
3
+ # the resulting {Collection} of {Diff} objects.
4
+ #
5
+ # Used internally by {CoreExt::String#sub_diff} and {CoreExt::String#gsub_diff}.
6
+ #
7
+ # @api private
2
8
  class Builder
3
9
  attr_reader :string, :diff_method
4
10
 
@@ -32,7 +38,7 @@ module SubDiff
32
38
  end
33
39
 
34
40
  def adapter
35
- @adapter ||= Adapter.new(differ)
41
+ @adapter ||= Adapter.new(self)
36
42
  end
37
43
 
38
44
  def differ
@@ -1,4 +1,14 @@
1
1
  module SubDiff
2
+ # Stores a collection of {Diff} objects for all matches from
3
+ # a {String#sub_diff} or {String#gsub_diff} replacement.
4
+ #
5
+ # It behaves like a {String} that represents the entire
6
+ # replacement result from {String#sub} or {String#gsub}.
7
+ #
8
+ # It also behaves like an {Enumerable} by delegating to
9
+ # {Collection#diffs} - an {Array} containing each {Diff}.
10
+ #
11
+ # @api public
2
12
  class Collection < SimpleDelegator
3
13
  extend Forwardable
4
14
  include Enumerable
@@ -1,10 +1,18 @@
1
1
  module SubDiff
2
2
  module CoreExt
3
3
  module String
4
+ # Behaves just like {String#sub} but wraps the returned replacement
5
+ # string in an enumerable {Collection} of {Diff} objects.
6
+ #
7
+ # See http://ruby-doc.org/core-2.2.0/String.html#method-i-sub
4
8
  def sub_diff(*args, &block)
5
9
  Builder.new(self, :sub).diff(*args, &block)
6
10
  end
7
11
 
12
+ # Behaves just like {String#gsub} but wraps the returned replacement
13
+ # string in an enumerable {Collection} of {Diff} objects.
14
+ #
15
+ # See http://ruby-doc.org/core-2.2.0/String.html#method-i-gsub
8
16
  def gsub_diff(*args, &block)
9
17
  Builder.new(self, :gsub).diff(*args, &block)
10
18
  end
@@ -1,4 +1,16 @@
1
1
  module SubDiff
2
+ # Stores a single match (and optional replacement)
3
+ # from a {String#sub} or {String#gsub} replacement.
4
+ #
5
+ # It behaves just like a {String} and represents the
6
+ # newly replaced string if a replacement was made, or
7
+ # the matched string itself if no changes occurred.
8
+ #
9
+ # It also has additional methods that provide access
10
+ # to the old string, the newly replaced string, and a
11
+ # boolean to determine if a replacement was actually made.
12
+ #
13
+ # @api public
2
14
  class Diff < SimpleDelegator
3
15
  attr_reader :value_was
4
16
 
@@ -1,20 +1,28 @@
1
1
  module SubDiff
2
+ # Performs a {String#sub} or {String#gsub} replacement
3
+ # while yielding each match "diff payload" to a block.
4
+ #
5
+ # The payload contains:
6
+ #
7
+ # match - the string matching the search.
8
+ # prefix - the string preceding the match.
9
+ # suffix - the string trailing the match.
10
+ # replacement - the string replacing the match.
11
+ #
12
+ # This class uses some special global variables: $` and $'.
13
+ # See http://ruby-doc.org/core-2.2.0/doc/globals_rdoc.html
14
+ #
15
+ # Used internally by {Sub}.
16
+ #
17
+ # @api private
2
18
  class Differ
3
- extend Forwardable
19
+ include Buildable
4
20
 
5
- def_delegators :builder, :diff_method, :string
6
-
7
- attr_reader :builder
8
-
9
- def initialize(builder)
10
- @builder = builder
11
- end
12
-
13
- def each_diff(search, *args, block)
21
+ def match(search, *args, replacement)
14
22
  string.send(diff_method, search) do |match|
15
23
  diff = { match: match, prefix: $`, suffix: $' }
16
- diff[:replacement] = match.sub(search, *args, &block)
17
- yield(builder, diff)
24
+ diff[:replacement] = match.sub(search, *args, &replacement)
25
+ yield(diff)
18
26
  end
19
27
  end
20
28
  end
@@ -1,8 +1,14 @@
1
1
  module SubDiff
2
+ # Processes matches for {String#gsub} replacements
3
+ # by pushing diffs into a {Builder} instance.
4
+ #
5
+ # Used internally by {Adapter}.
6
+ #
7
+ # @api private
2
8
  class Gsub < Sub
3
9
  private
4
10
 
5
- def process(_builder, diff, _search)
11
+ def append_diff_to_builder(diff, _search)
6
12
  super
7
13
  last_prefix << prefix(diff) << diff[:match]
8
14
  end
@@ -17,13 +23,8 @@ module SubDiff
17
23
 
18
24
  def suffix(_diff, search)
19
25
  suffix = super
20
- matcher = suffix_matcher(search)
21
- skip_suffix = suffix.send(matcher, search)
22
- suffix unless skip_suffix
23
- end
24
-
25
- def suffix_matcher(search)
26
- search.is_a?(Regexp) ? :match : :include?
26
+ regex = Regexp.new(search)
27
+ suffix unless suffix.match(regex)
27
28
  end
28
29
  end
29
30
  end
@@ -1,20 +1,22 @@
1
1
  module SubDiff
2
+ # Processes matches for {String#gsub} replacements
3
+ # by pushing diffs into a {Builder} instance.
4
+ #
5
+ # Used internally by {Adapter}.
6
+ #
7
+ # @api private
2
8
  class Sub
3
- attr_reader :differ
4
-
5
- def initialize(differ)
6
- @differ = differ
7
- end
9
+ include Buildable
8
10
 
9
11
  def diff(search, *args, &block)
10
- differ.each_diff(search, *args, block) do |builder, diff|
11
- process(builder, diff, search)
12
+ differ.match(search, *args, block) do |diff|
13
+ append_diff_to_builder(diff, search)
12
14
  end
13
15
  end
14
16
 
15
17
  private
16
18
 
17
- def process(builder, diff, search)
19
+ def append_diff_to_builder(diff, search)
18
20
  builder << prefix(diff)
19
21
  builder.push(diff[:replacement], diff[:match])
20
22
  builder << suffix(diff, search)
@@ -1,3 +1,3 @@
1
1
  module SubDiff
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.1'
3
3
  end
@@ -1,13 +1,9 @@
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
1
+ if ENV['CODECLIMATE_REPO_TOKEN']
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+ else
5
+ require 'simplecov'
6
+ SimpleCov.start { add_filter('/vendor/bundle/') }
11
7
  end
12
8
 
13
9
  require File.expand_path('../../lib/sub_diff', __FILE__)
@@ -17,64 +13,3 @@ RSpec.configure do |config|
17
13
  config.raise_errors_for_deprecations!
18
14
  config.run_all_when_everything_filtered = true
19
15
  end
20
-
21
- # RSpec matcher to spec delegations.
22
- # Forked from https://gist.github.com/ssimeonov/5942729 with fixes
23
- # for arity + custom prefix.
24
- #
25
- # Usage:
26
- #
27
- # describe Post do
28
- # it { should delegate(:name).to(:author).with_prefix } # post.author_name
29
- # it { should delegate(:name).to(:author).with_prefix(:any) } # post.any_name
30
- # it { should delegate(:month).to(:created_at) }
31
- # it { should delegate(:year).to(:created_at) }
32
- # it { should delegate(:something).to(:'@instance_var') }
33
- # end
34
- RSpec::Matchers.define :delegate do |method|
35
- match do |delegator|
36
- @prefix ||= nil
37
- @method = @prefix ? :"#{@prefix}_#{method}" : method
38
- @delegator = delegator
39
-
40
- if @to.to_s[0] == '@'
41
- # Delegation to an instance variable
42
- old_value = @delegator.instance_variable_get(@to)
43
- begin
44
- @delegator.instance_variable_set(@to, receiver_double(method))
45
- @delegator.send(@method) == :called
46
- ensure
47
- @delegator.instance_variable_set(@to, old_value)
48
- end
49
- elsif @delegator.respond_to?(@to, true)
50
- unless [0,-1].include?(@delegator.method(@to).arity)
51
- raise "#{@delegator}'s' #{@to} method does not have zero or -1 arity (it expects parameters)"
52
- end
53
- allow(@delegator).to receive(@to).and_return(receiver_double(method))
54
- @delegator.send(@method) == :called
55
- else
56
- raise "#{@delegator} does not respond to #{@to}"
57
- end
58
- end
59
-
60
- description do
61
- "delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
62
- end
63
-
64
- failure_message do |text|
65
- "expected #{@delegator} to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
66
- end
67
-
68
- failure_message_when_negated do |text|
69
- "expected #{@delegator} not to delegate :#{@method} to its #{@to}#{@prefix ? ' with prefix' : ''}"
70
- end
71
-
72
- chain(:to) { |receiver| @to = receiver }
73
- chain(:with_prefix) { |prefix| @prefix = prefix || @to }
74
-
75
- def receiver_double(method)
76
- double('receiver').tap do |receiver|
77
- allow(receiver).to receive(method).and_return(:called)
78
- end
79
- end
80
- end
@@ -43,7 +43,6 @@ RSpec.describe SubDiff::Collection do
43
43
 
44
44
  describe '#each' do
45
45
  it { is_expected.to be_an(Enumerable) }
46
- it { is_expected.to delegate(:each).to(:diffs) }
47
46
  end
48
47
 
49
48
  describe '#push' do
@@ -88,7 +87,9 @@ RSpec.describe SubDiff::Collection do
88
87
  end
89
88
 
90
89
  describe '#size' do
91
- it { is_expected.to delegate(:size).to(:diffs) }
90
+ it 'should use the diffs size' do
91
+ expect(subject.size).to eq(subject.diffs.size)
92
+ end
92
93
 
93
94
  it 'should not use the string size' do
94
95
  expect(subject.size).not_to eq(subject.to_s.size)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sub_diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Huber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-12 00:00:00.000000000 Z
11
+ date: 2015-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -40,6 +40,7 @@ files:
40
40
  - README.md
41
41
  - lib/sub_diff.rb
42
42
  - lib/sub_diff/adapter.rb
43
+ - lib/sub_diff/buildable.rb
43
44
  - lib/sub_diff/builder.rb
44
45
  - lib/sub_diff/collection.rb
45
46
  - lib/sub_diff/core_ext/string.rb