durable_decorator 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -33,7 +33,7 @@ class ExampleClass
33
33
  end
34
34
  end
35
35
 
36
- class ExampleClass
36
+ ExampleClass.class_eval do
37
37
  durably_decorate :string_method do
38
38
  string_method_original + " and new"
39
39
  end
@@ -62,13 +62,9 @@ Armed with this knowledge, we can enforce a strict mode:
62
62
  ```ruby
63
63
  DurableDecorator::Base.determine_sha('ExampleClass#no_param_method')
64
64
  # => 'ba3114b2d46caa684b3f7ba38d6f74b2'
65
- ExampleClass.class_eval do
66
- meta = {
67
- mode: 'strict',
68
- sha: 'WE-IGNORE-THE-ABOVE'
69
- }
70
65
 
71
- durably_decorate :string_method, meta do
66
+ ExampleClass.class_eval do
67
+ durably_decorate :string_method, mode: 'strict', sha: 'ba3114b2d46caa684b3f7ba38d6f74b2' do
72
68
  string_method_original + " and new"
73
69
  end
74
70
  end
@@ -76,6 +72,26 @@ end
76
72
  DurableDecorator::TamperedDefinitionError: Method SHA mismatch, the definition has been tampered with
77
73
  ```
78
74
 
75
+ DurableDecorator may also decorate methods with params like so:
76
+
77
+ ```ruby
78
+ class ExampleClass
79
+ def string_method(text)
80
+ "original #{text}"
81
+ end
82
+ end
83
+
84
+ ExampleClass.class_eval do
85
+ durably_decorate :string_method, mode: 'strict', sha: 'ba3114b2d46caa684b3f7ba38d6f74b2' do |text|
86
+ string_method_original(text) + " and new"
87
+ end
88
+ end
89
+
90
+ instance = ExampleClass.new
91
+ instance.string_method('test')
92
+ # => "original test and new"
93
+ ```
94
+
79
95
  DurableDecorator also maintains explicit versions of each method overriden by creating aliases with appended SHAs of the form ```some_method_1234abcd``` so you can always target explicit method versions without relying on ```some_method_original```.
80
96
 
81
97
  DurableDecorator maintains 3 versions of aliases to previous method versions, 2 of which are short-SHA versions, akin to Github:
@@ -35,8 +35,27 @@ module DurableDecorator
35
35
  def logger
36
36
  return @logger if @logger
37
37
 
38
- @logger = Logging.logger(STDOUT)
38
+ Logging.color_scheme( 'bright',
39
+ :levels => {
40
+ :info => :green,
41
+ :warn => :yellow,
42
+ :error => :red,
43
+ :fatal => [:white, :on_red]
44
+ }
45
+ )
46
+
47
+ Logging.appenders.stdout(
48
+ 'stdout',
49
+ :layout => Logging.layouts.pattern(
50
+ :pattern => '%-5l %c: %m\n',
51
+ :color_scheme => 'bright'
52
+ )
53
+ )
54
+
55
+ @logger = Logging.logger['DurableDecorator']
39
56
  @logger.level = :warn
57
+
58
+ Logging.logger.root.appenders = Logging.appenders.stdout
40
59
  @logger
41
60
  end
42
61
  end
@@ -1,15 +1,28 @@
1
1
  module DurableDecorator
2
2
  class Validator
3
3
  class << self
4
- DECORATION_MODES = ['strict']
4
+ DECORATION_MODES = ['strict', 'soft']
5
5
 
6
6
  def validate_decoration_meta clazz, method_name, old_method, meta
7
7
  return unless meta
8
8
 
9
9
  chill_meta = Util.symbolized_hash(meta)
10
+ provided_mode = chill_meta[:mode]
11
+ provided_sha = chill_meta[:sha]
12
+ expected_sha = Util.method_sha(old_method)
10
13
 
11
- raise InvalidDecorationError, "The hash provided to the decorator is invalid" unless DECORATION_MODES.include? chill_meta[:mode] and chill_meta[:sha] and !chill_meta[:sha].empty?
12
- raise TamperedDefinitionError, "Method SHA mismatch, the definition has been tampered with" unless Util.method_sha(old_method) == chill_meta[:sha]
14
+ raise InvalidDecorationError, "The :mode provided is invalid. Possible modes are: #{DECORATION_MODES.join(", ")}" unless DECORATION_MODES.include? provided_mode
15
+ raise InvalidDecorationError, "The SHA provided appears to be empty" unless provided_sha and !provided_sha.empty?
16
+ send("handle_#{chill_meta[:mode]}_fault", clazz, method_name, expected_sha, provided_sha) unless expected_sha == provided_sha
17
+ end
18
+
19
+ def handle_strict_fault(clazz, method_name, expected_sha, provided_sha)
20
+ raise TamperedDefinitionError, "Method SHA mismatch, the definition has been tampered with. #{expected_sha} is expected but #{provided_sha} was provided."
21
+ end
22
+
23
+ def handle_soft_fault(clazz, method_name, expected_sha, provided_sha)
24
+ Util.logger.fatal "#{clazz}##{method_name} decoration uses an invalid SHA. The original method definition could have been tampered with!"
25
+ Util.logger.fatal "Expected SHA was #{expected_sha} but the provided SHA is #{provided_sha}"
13
26
  end
14
27
 
15
28
  def validate_method_arity clazz, method_name, old_method, &block
@@ -1,3 +1,3 @@
1
1
  module DurableDecorator
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -125,6 +125,58 @@ describe DurableDecorator::Base do
125
125
  end
126
126
  end
127
127
  end
128
+
129
+ context 'for soft definitions' do
130
+ context 'with the correct SHA' do
131
+ it 'guarantees access to #method_original' do
132
+ ExampleClass.class_eval do
133
+ meta = {
134
+ :mode => 'soft',
135
+ :sha => 'd54f9c7ea2038fac0ae2ff9af49c56f35761725d'
136
+ }
137
+ durably_decorate :no_param_method, meta do
138
+ no_param_method_original + " and a new string"
139
+ end
140
+ end
141
+
142
+ instance = ExampleClass.new
143
+ instance.no_param_method.should == "original and a new string"
144
+ end
145
+ end
146
+
147
+ context 'with the wrong SHA' do
148
+ it 'logs a warning but does not raise an error' do
149
+ DurableDecorator::Util.stub(:logger).and_return(Logging.logger['SuperLogger'])
150
+ lambda{
151
+ ExampleClass.class_eval do
152
+ meta = {
153
+ :mode => 'soft',
154
+ :sha => '1234wrong'
155
+ }
156
+ durably_decorate :no_param_method, meta do
157
+ no_param_method_original + " and a new string"
158
+ end
159
+ end
160
+ @log_output.readline.should match(/invalid SHA/)
161
+ }.should_not raise_error
162
+ end
163
+ end
164
+
165
+ context 'for an invalid config' do
166
+ it 'raises an error' do
167
+ lambda{
168
+ ExampleClass.class_eval do
169
+ meta = {
170
+ :mode => 'soft'
171
+ }
172
+ durably_decorate :no_param_method, meta do
173
+ no_param_method_original + " and a new string"
174
+ end
175
+ end
176
+ }.should raise_error(DurableDecorator::InvalidDecorationError)
177
+ end
178
+ end
179
+ end
128
180
  end
129
181
 
130
182
  context 'for methods not yet defined' do
@@ -1,7 +1,11 @@
1
1
  require 'rspec'
2
2
  require 'durable_decorator'
3
+ require 'rspec/logging_helper'
3
4
 
4
5
  RSpec.configure do |config|
6
+ include RSpec::LoggingHelper
7
+ config.capture_log_messages
8
+
5
9
  config.before(:each) do
6
10
  load 'example_class.rb'
7
11
  load 'sample_module.rb'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: durable_decorator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2013-08-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: method_source