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 +4 -4
- data/README.md +1 -1
- data/Rakefile +4 -0
- data/after_do-loader.gemspec +1 -1
- data/lib/after_do/loader.rb +9 -1
- data/lib/after_do/loader/aspect_applier.rb +35 -0
- data/lib/after_do/loader/config.rb +2 -0
- data/lib/after_do/loader/errors.rb +9 -0
- data/lib/after_do/loader/errors/cannot_apply_aspect.rb +11 -0
- data/lib/after_do/loader/errors/invalid_config.rb +11 -0
- data/lib/after_do/loader/version.rb +1 -1
- data/spec/after_do/loader/aspect_applier_spec.rb +55 -0
- data/spec/after_do/loader/config_spec.rb +42 -31
- data/spec/after_do/loader_spec.rb +35 -0
- metadata +12 -5
- data/lib/after_do/loader/aspect_loader.rb +0 -42
- data/spec/after_do/loader/aspect_loader_spec.rb +0 -44
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 8886a319c67b5a858d2f29df695a1de315542452
         | 
| 4 | 
            +
              data.tar.gz: 4e860cf562ecb03f436ba361d146a86235bc0d66
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/after_do-loader.gemspec
    CHANGED
    
    | @@ -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 |  | 
    
        data/lib/after_do/loader.rb
    CHANGED
    
    | @@ -3,10 +3,18 @@ require 'recursive_open_struct' | |
| 3 3 |  | 
| 4 4 | 
             
            require_relative 'loader/version'
         | 
| 5 5 |  | 
| 6 | 
            -
            require_relative '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
         | 
| @@ -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 | 
| 2 | 
            -
               | 
| 3 | 
            -
             | 
| 1 | 
            +
            module AfterDo
         | 
| 2 | 
            +
              module Loader
         | 
| 3 | 
            +
                class AdvisedClass; end
         | 
| 4 | 
            +
                class CoolAspect; end
         | 
| 4 5 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 6 | 
            +
                describe Config do
         | 
| 7 | 
            +
                  subject(:config) { Config.new(config_path) }
         | 
| 7 8 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
                         | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                           | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 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 | 
            -
             | 
| 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. | 
| 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/ | 
| 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/ | 
| 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/ | 
| 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
         |