after_do-loader 0.0.1 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc03471141f4bf6a67f011746a49f8bc5c938f81
4
- data.tar.gz: 7934725beb90a64261ae6ec595c8384a230014d1
3
+ metadata.gz: 8886a319c67b5a858d2f29df695a1de315542452
4
+ data.tar.gz: 4e860cf562ecb03f436ba361d146a86235bc0d66
5
5
  SHA512:
6
- metadata.gz: 70edc0bd393849c1cbe7e2a03f235c5f24aad4808334ed14d87fd4f890c16f4f3543b7e1efabce1763dbe1284c25b2526862d7d6530875637f5ad03a1f656a25
7
- data.tar.gz: 442c50496680bdf0c58f5f339e11f8535ce5cd16c9c88a188957e61031d946ca2189d2df5f9d0ed02680f52d4906b8d012da12393a3355e4328d32be56abb5dc
6
+ metadata.gz: 9ca6f8c29186ef6c7705d515d1a7e23dc87be195ff9ae37cb26ccf0db5cc36bb062d44bb5056a511730dc81b4e9c9c1de6423bcc408778d2d5dd6c3c0838181f
7
+ data.tar.gz: f6015716c4c9481f06f0e638a82334c5d17d0a80b12e1b83dbeabcf234286ffd6989aa7deed5a74680d5fc0bdaf9a831459cecafdd11338d0e49d1d871e0b632
data/README.md CHANGED
@@ -26,7 +26,7 @@ In order to use this gem, you need to add a `aspects.yml` file to your
26
26
  application. This file must define the classes that will implement the callbacks
27
27
  used by `after_do`'s methods.
28
28
 
29
- Example:
29
+ ### Example:
30
30
 
31
31
  Suppose I want to log every method call to `AdvisedClass#initialize`, before and
32
32
  after it's invocation. What will be logged is defined in the
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['Renan Ranelli', 'Rafael Almeida']
9
9
  spec.email = ['renanranelli@gmail.com', 'rubygems@rafaelalmeida.net']
10
10
  spec.summary = 'Apply after_do methods dynamically based on a config file.'
11
- spec.description = 'Apply after_do methods dynamically based on a config file.'
11
+ spec.description = 'Apply after_do methods dynamically based on a config file'
12
12
  spec.homepage = ''
13
13
  spec.license = 'MIT'
14
14
 
@@ -3,10 +3,18 @@ require 'recursive_open_struct'
3
3
 
4
4
  require_relative 'loader/version'
5
5
 
6
- require_relative 'loader/aspect_loader'
6
+ require_relative 'loader/aspect_applier'
7
7
  require_relative 'loader/config'
8
+ require_relative 'loader/errors'
8
9
 
9
10
  module AfterDo
10
11
  module Loader
12
+ def self.load(config_path)
13
+ config = Config.new(config_path)
14
+
15
+ config.aspects.each do |aspect|
16
+ AspectApplier.new(aspect).apply
17
+ end
18
+ end
11
19
  end
12
20
  end
@@ -0,0 +1,35 @@
1
+ module AfterDo
2
+ module Loader
3
+ class AspectApplier
4
+ def initialize(aspect)
5
+ @aspect = aspect
6
+ end
7
+
8
+ def apply
9
+ aspect.advices.each do |advice|
10
+ advice.targets.each do |target|
11
+ target.klass.extend(AfterDo)
12
+
13
+ methods = target.target_methods
14
+
15
+ apply_aspect_to_target(aspect.klass, advice, target.klass, methods)
16
+ end
17
+ end
18
+ rescue
19
+ raise Errors::CannotApplyAspect
20
+ end
21
+
22
+ protected
23
+
24
+ attr_reader :aspect
25
+
26
+ def apply_aspect_to_target(aspect_klass, advice, target, methods)
27
+ methods.each do |method|
28
+ advice.names.each do |advice_name|
29
+ aspect_klass.new(target).send(advice_name, method)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -17,6 +17,8 @@ module AfterDo
17
17
  config = constantize_classes!(config_hash)
18
18
 
19
19
  RecursiveOpenStruct.new(config, recurse_over_arrays: true)
20
+ rescue
21
+ raise Errors::InvalidConfig
20
22
  end
21
23
 
22
24
  def constantize_classes!(config_hash)
@@ -0,0 +1,9 @@
1
+ require_relative 'errors/invalid_config'
2
+ require_relative 'errors/cannot_apply_aspect'
3
+
4
+ module AfterDo
5
+ module Loader
6
+ module Errors
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module AfterDo
2
+ module Loader
3
+ module Errors
4
+ class CannotApplyAspect < StandardError
5
+ def initialize
6
+ super('Cannot apply aspect. Check your config file.')
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module AfterDo
2
+ module Loader
3
+ module Errors
4
+ class InvalidConfig < StandardError
5
+ def initialize
6
+ super('Invalid config error')
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
1
  module AfterDo
2
2
  module Loader
3
- VERSION = '0.0.1'
3
+ VERSION = '0.1'
4
4
  end
5
5
  end
@@ -0,0 +1,55 @@
1
+ module AfterDo
2
+ module Loader
3
+ class AdvisedClass; end
4
+ class CoolAspect; end
5
+
6
+ describe AspectApplier do
7
+ subject(:applier) { described_class.new(aspect_config) }
8
+
9
+ let(:aspect_config) { config.aspects.first }
10
+ let(:config) do
11
+ Config.new(fixture_path('aspect_config.yml'))
12
+ end
13
+
14
+ let(:aspect_instance) { CoolAspect.new }
15
+ let(:aspect_class) { CoolAspect }
16
+ let(:target_class) { AdvisedClass }
17
+
18
+ describe '#apply' do
19
+ subject(:apply) { applier.apply }
20
+
21
+ before do
22
+ allow(aspect_class).to receive(:new).and_return(aspect_instance)
23
+ allow(aspect_instance).to receive(:add_callback)
24
+ end
25
+
26
+ it 'extends the target class with the AfterDo library' do
27
+ expect(target_class).to receive(:extend).with(AfterDo)
28
+
29
+ apply
30
+ end
31
+
32
+ it 'creates an Aspect object of the correct class' do
33
+ expect(aspect_class).to receive(:new).with(target_class)
34
+
35
+ apply
36
+ end
37
+
38
+ it 'applies the right advice to the target class' do
39
+ expect(aspect_instance).to receive(:add_callback).with('initialize')
40
+ expect(aspect_instance).to receive(:add_callback).with('merge')
41
+
42
+ apply
43
+ end
44
+
45
+ context 'when applying goes wrong' do
46
+ before do
47
+ allow(aspect_config).to receive(:advices).and_raise(StandardError)
48
+ end
49
+
50
+ it { expect { apply }.to raise_error(Errors::CannotApplyAspect) }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,36 +1,47 @@
1
- module AfterDo::Loader
2
- class AdvisedClass; end
3
- class CoolAspect; end
1
+ module AfterDo
2
+ module Loader
3
+ class AdvisedClass; end
4
+ class CoolAspect; end
4
5
 
5
- describe Config do
6
- subject(:config) { Config.new(fixture_path('aspect_config.yml')) }
6
+ describe Config do
7
+ subject(:config) { Config.new(config_path) }
7
8
 
8
- let(:config_hash) do
9
- {
10
- 'aspects' => [
11
- {
12
- 'name' => 'CoolAspect',
13
- 'klass' => AfterDo::Loader::CoolAspect,
14
- 'description' => 'This aspect adds after_do callbacks to its target classes',
15
- 'advices' => [
16
- {
17
- 'names' => %w(add_callback),
18
- 'targets' => [
19
- {
20
- 'klass' => AfterDo::Loader::AdvisedClass,
21
- 'target_methods' => %w(initialize merge)
22
- }
23
- ]
24
- }
25
- ]
26
- }
27
- ]
28
- }
29
- end
30
- let(:config_os) do
31
- RecursiveOpenStruct.new(config_hash, recurse_over_arrays: true)
32
- end
9
+ let(:config_path) { fixture_path('aspect_config.yml') }
10
+
11
+ let(:config_hash) do
12
+ {
13
+ 'aspects' => [
14
+ {
15
+ 'name' => 'CoolAspect',
16
+ 'klass' => AfterDo::Loader::CoolAspect,
17
+ 'description' => "This aspect adds after_do callbacks to its \
18
+ target classes",
19
+ 'advices' => [
20
+ {
21
+ 'names' => %w(add_callback),
22
+ 'targets' => [
23
+ {
24
+ 'klass' => AfterDo::Loader::AdvisedClass,
25
+ 'target_methods' => %w(initialize merge)
26
+ }
27
+ ]
28
+ }
29
+ ]
30
+ }
31
+ ]
32
+ }
33
+ end
34
+ let(:config_os) do
35
+ RecursiveOpenStruct.new(config_hash, recurse_over_arrays: true)
36
+ end
33
37
 
34
- it { expect(config.aspects).to eq(config_os.aspects) }
38
+ it { expect(config.aspects).to eq(config_os.aspects) }
39
+
40
+ context 'when parsing goes wrong' do
41
+ let(:config_path) { fixture_path('bad_aspect_config.yml') }
42
+
43
+ it { expect { config }.to raise_error(Errors::InvalidConfig) }
44
+ end
45
+ end
35
46
  end
36
47
  end
@@ -0,0 +1,35 @@
1
+ module AfterDo
2
+ module Loader
3
+ describe AfterDo::Loader do
4
+ subject(:loader) { described_class }
5
+
6
+ let(:config_path) { '/i/am/a/fake/path/' }
7
+ let(:config) { double(Config, aspects: [aspect]) }
8
+ let(:aspect) { double(:aspect) }
9
+
10
+ let(:applier) { instance_double(AspectApplier, apply: nil) }
11
+
12
+ describe '.load' do
13
+ subject(:load) { loader.load(config_path) }
14
+
15
+ before do
16
+ allow(Config).to receive(:new).and_return(config)
17
+ allow(AspectApplier).to receive(:new).and_return(applier)
18
+ end
19
+
20
+ it 'loads config with the right path' do
21
+ expect(Config).to receive(:new).with(config_path)
22
+
23
+ load
24
+ end
25
+
26
+ it 'applies stuff' do
27
+ expect(AspectApplier).to receive(:new).with(aspect)
28
+ expect(applier).to receive(:apply)
29
+
30
+ load
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: after_do-loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renan Ranelli
@@ -137,7 +137,7 @@ dependencies:
137
137
  - - ">="
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
- description: Apply after_do methods dynamically based on a config file.
140
+ description: Apply after_do methods dynamically based on a config file
141
141
  email:
142
142
  - renanranelli@gmail.com
143
143
  - rubygems@rafaelalmeida.net
@@ -152,13 +152,18 @@ files:
152
152
  - Gemfile
153
153
  - LICENSE.txt
154
154
  - README.md
155
+ - Rakefile
155
156
  - after_do-loader.gemspec
156
157
  - lib/after_do/loader.rb
157
- - lib/after_do/loader/aspect_loader.rb
158
+ - lib/after_do/loader/aspect_applier.rb
158
159
  - lib/after_do/loader/config.rb
160
+ - lib/after_do/loader/errors.rb
161
+ - lib/after_do/loader/errors/cannot_apply_aspect.rb
162
+ - lib/after_do/loader/errors/invalid_config.rb
159
163
  - lib/after_do/loader/version.rb
160
- - spec/after_do/loader/aspect_loader_spec.rb
164
+ - spec/after_do/loader/aspect_applier_spec.rb
161
165
  - spec/after_do/loader/config_spec.rb
166
+ - spec/after_do/loader_spec.rb
162
167
  - spec/fixtures/aspect_config.yml
163
168
  - spec/spec_helper.rb
164
169
  homepage: ''
@@ -186,7 +191,9 @@ signing_key:
186
191
  specification_version: 4
187
192
  summary: Apply after_do methods dynamically based on a config file.
188
193
  test_files:
189
- - spec/after_do/loader/aspect_loader_spec.rb
194
+ - spec/after_do/loader/aspect_applier_spec.rb
190
195
  - spec/after_do/loader/config_spec.rb
196
+ - spec/after_do/loader_spec.rb
191
197
  - spec/fixtures/aspect_config.yml
192
198
  - spec/spec_helper.rb
199
+ has_rdoc:
@@ -1,42 +0,0 @@
1
- module AfterDo
2
- module Loader
3
- class AspectLoader
4
- def initialize(config)
5
- @config = config
6
- end
7
-
8
- def load
9
- config.aspects.each do |aspect|
10
- apply_advices(aspect.klass, aspect.advices)
11
- end
12
- rescue => e
13
- raise e, "Could not apply advices. Check you .yml file\
14
- for ill formatting. \n" + e.message
15
- end
16
-
17
- protected
18
-
19
- attr_reader :config
20
-
21
- def apply_advices(aspect, advices)
22
- advices.each do |advice|
23
- advice.targets.each do |target|
24
- target.klass.extend(AfterDo)
25
-
26
- methods = target.target_methods
27
-
28
- apply_aspect_to_target(aspect, advice, target.klass, methods)
29
- end
30
- end
31
- end
32
-
33
- def apply_aspect_to_target(aspect, advice, target, methods)
34
- methods.each do |method|
35
- advice.names.each do |advice_name|
36
- aspect.new(target).send(advice_name, method)
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,44 +0,0 @@
1
- module AfterDo::Loader
2
- class AdvisedClass; end
3
- class CoolAspect; end
4
-
5
- describe AspectLoader do
6
- subject(:loader) { described_class.new(config) }
7
-
8
- let(:config) do
9
- Config.new(fixture_path('aspect_config.yml'))
10
- end
11
-
12
- let(:aspect) { CoolAspect.new }
13
- let(:aspect_class) { CoolAspect }
14
- let(:target_class) { AdvisedClass }
15
-
16
- describe '#load' do
17
- subject(:load) { loader.load }
18
-
19
- before do
20
- allow(aspect_class).to receive(:new).and_return(aspect)
21
- allow(aspect).to receive(:add_callback)
22
- end
23
-
24
- it 'extends the target class with the AfterDo library' do
25
- expect(target_class).to receive(:extend).with(AfterDo)
26
-
27
- load
28
- end
29
-
30
- it 'creates an Aspect object of the correct class' do
31
- expect(aspect_class).to receive(:new).with(target_class)
32
-
33
- load
34
- end
35
-
36
- it 'applies the right advice to the target class' do
37
- expect(aspect).to receive(:add_callback).with('initialize').once
38
- expect(aspect).to receive(:add_callback).with('merge').once
39
-
40
- load
41
- end
42
- end
43
- end
44
- end