safe_monkeypatch 0.0.1 → 0.1.0

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: 844de048f173e6086d969251524d92a7c31ed3ba
4
- data.tar.gz: f96cd2f537e8060d2772adb966e85dd3a06daee5
3
+ metadata.gz: 38da338572140b59706ba5ba0021bae5605b9af7
4
+ data.tar.gz: b36380cd9a7a6818a2eaa2ae84ee7e4eaffc3b79
5
5
  SHA512:
6
- metadata.gz: dab778853b53dc6c4f0c7fc4407779b85b47cfb5d30bae151ad465909ce5a17ef4cb5c6966e5d9296ac7983dfbe9d4d9ced54946e3e607b6691f59dd472c12d0
7
- data.tar.gz: 6e5b91d0cb0058944fdd263a898da8a2f35fb7bb02bc217ff5fcdd5db334aab96c87851d0b16f8e8aa3ba7277df88021bc9bcc829a50b88f00f1914c46e5134a
6
+ metadata.gz: 0b1360b349f2d26ab655c2a7d8cfd954df14f67764dce80bab4c55b5d44c954eca5cedf5aa76bf287223edb147d39e8df98411454638bb6a64a1285da074cadb
7
+ data.tar.gz: 72cf5eef62fef71733b04a824a3bbf0b2fcf7d13595151afa8f4596f7f920a2dd195626d6293eb1a9150047c3b847e9afd226d00a7ad56ac64daa0f5b0abeda7
data/README.md CHANGED
@@ -10,9 +10,10 @@ it's gonna break in the next version of Rails. This gem
10
10
  would raise an error if monkey patched method has changed
11
11
  since last time you've adapted your patch to the upstream.
12
12
 
13
- ## Usage
13
+ ## Simple usage
14
+
15
+ Assume some upstream in foo.gem:
14
16
 
15
- # assume some upstream in foo.gem:
16
17
  class Foo
17
18
  def bar
18
19
  puts "do first thing"
@@ -21,12 +22,10 @@ since last time you've adapted your patch to the upstream.
21
22
  end
22
23
  end
23
24
 
24
- # your code
25
- class Foo
25
+ And your code:
26
26
 
27
- # you can use any of Digest::*** checksum's methods: sha1, etc.
28
- # NOTE: do this BEFORE monkeypatch happens
29
- safe_monkeypatch :bar, md5: "", error: "my additional info for exception"
27
+ class Foo
28
+ safe_monkeypatch :bar, md5: "", error: "patch for foo.gem v0.0.1"
30
29
 
31
30
  def bar
32
31
  puts "do first thing"
@@ -35,13 +34,63 @@ since last time you've adapted your patch to the upstream.
35
34
  end
36
35
  end
37
36
 
37
+ **NOTE:** do this BEFORE monkeypatch happens
38
+
39
+ You can also use any of Digest::*** checksum's methods: sha1 or even combine md5+sha1
40
+
38
41
  Until upstream code isn't changed, it's working like usual.
39
42
  But if the new version changes the implementation of `Foo#bar` method, an
40
43
  error is raised **while startup time**
41
44
  (unless you monkeypatch in runtime, but now you're on your own):
42
45
 
43
46
  SafeMonkeypatch::UpstreamChanged: Foo#bar expected to have md5 checksum: "", but has: ""
44
- my additional info for exception
47
+ patch for foo.gem v0.0.1
48
+
49
+ ## Matching usage
50
+
51
+ Unfortunately, if you have to support different versions of `foo.gem`, you have to monkeypatch all the
52
+ variant implementation. Use blocks for this:
53
+
54
+ class Foo
55
+ safe_monkeypatch :bar, md5: 'some_checksum' do
56
+ def bar
57
+ "this works if upstream Foo#bar method has md5 of source equals 'some_checksum'
58
+ end
59
+ end
60
+
61
+ safe_monkeypatch :bar, md5: 'another_checksum' do
62
+ def bar
63
+ "this works if upstream Foo#bar method has md5 of source equals 'another_checksum'
64
+ end
65
+ end
66
+ end
67
+
68
+ **Note:** if source of upstream change dramatically and you haven't such matching checksum,
69
+ **you won't notice this**, as such use this method:
70
+
71
+ class Foo
72
+
73
+ # NOTE: insert this BEFORE ANY monkeypatch: list all checksum variants
74
+ safe_monkeypatch :bar, md5: ['some_checksum', 'another_checksum']
75
+
76
+ safe_monkeypatch :bar, md5: 'some_checksum' do
77
+ def bar
78
+ "this works if upstream Foo#bar method has md5 of source equals 'some_checksum'
79
+ end
80
+ end
81
+
82
+ safe_monkeypatch :bar, md5: 'another_checksum' do
83
+ def bar
84
+ "another patch"
85
+ "this works if upstream Foo#bar method has md5 of source equals 'another_checksum'
86
+ end
87
+ end
88
+ end
89
+
90
+ Use block matching **always this way**. This will guarantee, that any of patches will be applied,
91
+ or you'll get standard exception.
92
+
93
+ ## Advanced usage
45
94
 
46
95
  You can also use it without patched module scope (for proper error use patched class/module name):
47
96
 
@@ -36,12 +36,32 @@ class Module
36
36
  raise SafeMonkeypatch::ConfigurationError, "Provide at least one cypher name like: md5: '...'"
37
37
  end
38
38
 
39
+ found_match = false
40
+ error_parts = ["#{inspect}##{meth} expected to have"]
41
+
39
42
  options.each do |cypher_name, expected|
40
43
  cypher = Digest.const_get(cypher_name.upcase)
41
- if (actual = cypher.hexdigest(source)) != expected
42
- raise SafeMonkeypatch::UpstreamChanged, "#{inspect}##{meth} expected to have #{cypher_name} expected: '#{expected}', but has: '#{actual}'\n#{info}".strip
44
+ actual = cypher.hexdigest(source)
45
+ found_match = if expected.is_a? Array
46
+ expected.any? { |e| e == actual }
47
+ else
48
+ actual == expected
49
+ end
50
+
51
+ unless found_match
52
+ error_parts << "#{cypher_name} expected: #{expected.inspect}, but has: #{actual.inspect}"
43
53
  end
44
54
  end
55
+
56
+ error_parts << info.to_s if info
57
+
58
+ if block_given? && found_match
59
+ yield
60
+ elsif block_given?
61
+ nil # pass
62
+ elsif not found_match
63
+ raise SafeMonkeypatch::UpstreamChanged, error_parts.join(" ")
64
+ end
45
65
  end
46
66
  end
47
67
 
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "safe_monkeypatch"
7
- spec.version = "0.0.1"
7
+ spec.version = "0.1.0"
8
8
  spec.authors = ["Vlad Bokov"]
9
9
  spec.email = ["razum2um@mail.ru"]
10
10
  spec.summary = %q{Patch methods without fear!}
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  MD5_CHECKSUM = 'b1c5ef3149e6e0062e1c21c3ce8af7d8'
4
+ SHA1_CHECKSUM = '31c701df5f245ac40a1f8cc958c77e4c4fa815df'
4
5
 
5
6
  RSpec.describe SafeMonkeypatch do
6
7
  subject { Foo.new }
@@ -13,7 +14,7 @@ RSpec.describe SafeMonkeypatch do
13
14
  end
14
15
  end
15
16
 
16
- it "works as usual" do
17
+ it "works" do
17
18
  class Foo
18
19
  safe_monkeypatch :bar, md5: MD5_CHECKSUM
19
20
 
@@ -61,7 +62,7 @@ RSpec.describe SafeMonkeypatch do
61
62
  end
62
63
  }.to raise_error(
63
64
  SafeMonkeypatch::UpstreamChanged,
64
- /Foo#bar expected to have md5 expected: 'invalid_checksum', but has: '#{MD5_CHECKSUM}'/
65
+ /Foo#bar expected to have md5 expected: "invalid_checksum", but has: "#{MD5_CHECKSUM}"/
65
66
  )
66
67
  end
67
68
 
@@ -70,7 +71,113 @@ RSpec.describe SafeMonkeypatch do
70
71
  Foo.safe_monkeypatch Foo.instance_method(:bar), md5: 'another_checksum'
71
72
  }.to raise_error(
72
73
  SafeMonkeypatch::UpstreamChanged,
73
- /Foo#bar expected to have md5 expected: 'another_checksum', but has: '#{MD5_CHECKSUM}'/
74
+ /Foo#bar expected to have md5 expected: "another_checksum", but has: "#{MD5_CHECKSUM}"/
74
75
  )
75
76
  end
77
+
78
+ describe "multiple cyphers" do
79
+ it "works" do
80
+ class Foo
81
+ safe_monkeypatch :bar, md5: MD5_CHECKSUM, sha1: SHA1_CHECKSUM
82
+
83
+ def bar
84
+ "patched bar"
85
+ end
86
+ end
87
+
88
+ expect(subject.bar).to eq "patched bar"
89
+ end
90
+
91
+ it "fails if some cypher is invalid" do
92
+ expect {
93
+ class Foo
94
+ safe_monkeypatch :bar, md5: MD5_CHECKSUM, sha1: 'invalid'
95
+
96
+ def bar
97
+ "patched bar"
98
+ end
99
+ end
100
+ }.to raise_error(
101
+ SafeMonkeypatch::UpstreamChanged,
102
+ /Foo#bar expected to have sha1 expected: "invalid", but has: "#{SHA1_CHECKSUM}"/
103
+ )
104
+ end
105
+
106
+ it "works with mutlipatch" do
107
+ expect(Kernel).to receive(:puts).once
108
+
109
+ class Foo
110
+ safe_monkeypatch :bar, md5: MD5_CHECKSUM, sha1: SHA1_CHECKSUM do
111
+ Kernel.puts
112
+
113
+ def bar
114
+ "patched bar"
115
+ end
116
+ end
117
+ end
118
+
119
+ expect(subject.bar).to eq "patched bar"
120
+ end
121
+ end
122
+
123
+ describe "multipatching" do
124
+ it "works" do
125
+ class Foo
126
+ safe_monkeypatch :bar, md5: 'invalid_checksum' do
127
+ def bar
128
+ "invalid patch"
129
+ end
130
+ end
131
+
132
+ safe_monkeypatch :bar, md5: MD5_CHECKSUM do
133
+ def bar
134
+ "patched bar"
135
+ end
136
+ end
137
+
138
+ safe_monkeypatch :bar, md5: 'another_checksum' do
139
+ def bar
140
+ "another patch"
141
+ end
142
+ end
143
+ end
144
+
145
+ expect(subject.bar).to eq "patched bar"
146
+ end
147
+
148
+ it "doesn't complain if no matching block found" do
149
+ class Foo
150
+ safe_monkeypatch :bar, md5: 'invalid_checksum' do
151
+ def bar
152
+ "invalid patch"
153
+ end
154
+ end
155
+ end
156
+
157
+ expect(subject.bar).to eq "bar"
158
+ end
159
+
160
+ it "complains if no matching block found if array given" do
161
+ expect {
162
+ class Foo
163
+ safe_monkeypatch :bar, md5: ['invalid_checksum', 'another_checksum']
164
+
165
+ safe_monkeypatch :bar, md5: 'invalid_checksum' do
166
+ def bar
167
+ "invalid patch"
168
+ end
169
+ end
170
+
171
+ safe_monkeypatch :bar, md5: 'another_checksum' do
172
+ def bar
173
+ "invalid patch"
174
+ end
175
+ end
176
+ end
177
+ }.to raise_error(
178
+ SafeMonkeypatch::UpstreamChanged,
179
+ /Foo#bar expected to have md5 expected: \["invalid_checksum", "another_checksum"\], but has: "#{MD5_CHECKSUM}"/
180
+ )
181
+ end
182
+ end
76
183
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_monkeypatch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vlad Bokov