diff options
| -rw-r--r-- | spec/models/faster_specs_spec.rb | 50 | ||||
| -rw-r--r-- | spec/support/faster/model_stubber.rb | 15 | ||||
| -rw-r--r-- | spec/support/faster/model_stubber/implementation.rb | 106 | ||||
| -rw-r--r-- | spec/support/faster/model_stubber/object_cache.rb | 23 | 
4 files changed, 194 insertions, 0 deletions
| diff --git a/spec/models/faster_specs_spec.rb b/spec/models/faster_specs_spec.rb new file mode 100644 index 000000000..2c97d1055 --- /dev/null +++ b/spec/models/faster_specs_spec.rb @@ -0,0 +1,50 @@ +RSpec.describe 'Faster Specs', type: :faster do +   +  shared_examples_for 'correct behavior' do + +    it 'finds workbench' do +      expect( referential.workbench ).to eq(workbench) +    end + +    it 'finds referentials' do +      expect( workbench.referentials ).to eq([referential]) +    end + +  end + +  context 'in DB' do  +    let( :workbench ){ create :workbench } +    let( :referential ){ create(:referential, workbench: workbench) } +     +    it_behaves_like 'correct behavior' +  end + +  context 'stubbed' do  +    let( :workbench ){ stub_model Workbench } +    let( :referential ){ stub_model( Referential, workbench: workbench ) } +     +    it_behaves_like 'correct behavior' + +    context 'workbench belongs to organisation' do +      it 'workbench has no orgnaisation' do +        expect( workbench.organisation ).to be_nil +      end +      it 'but it can be set' do +        organisation = stub_model Organisation +        workbench.organisation = organisation +        expect( workbench.organisation ).to eq(organisation) +      end +      it 'and by setting it we get the reverse relation working' do +        organisation = stub_model Organisation +        workbench.organisation = organisation +        expect( organisation.workbenches ).to be_eql([workbench]) +      end +      it 'can also be constructed that way' do +        organisation = stub_model Organisation +        workbench    = stub_model Workbench, organisation: organisation +        expect( workbench.organisation ).to eq(organisation) +        expect( organisation.workbenches ).to be_eql([workbench]) +      end +    end +  end +end diff --git a/spec/support/faster/model_stubber.rb b/spec/support/faster/model_stubber.rb new file mode 100644 index 000000000..789f5c2d2 --- /dev/null +++ b/spec/support/faster/model_stubber.rb @@ -0,0 +1,15 @@ +require_relative 'model_stubber/implementation' + +module ModelStubber +  def stub_model klass, **params +    klass.new.tap do | model | +      Implementation.new(model, params).setup +    end +  end +end + + +RSpec.configure do | conf | +  # Empty Helper's cache before each example or create a helper? +  conf.include ModelStubber, type: :faster +end diff --git a/spec/support/faster/model_stubber/implementation.rb b/spec/support/faster/model_stubber/implementation.rb new file mode 100644 index 000000000..9ee1f417a --- /dev/null +++ b/spec/support/faster/model_stubber/implementation.rb @@ -0,0 +1,106 @@ +require_relative './object_cache' + +module ModelStubber + +  # Get out of RSpec's example's namespace +  class Implementation + +    attr_reader :model, :params + +    def initialize model, **params +      @model  = model +      @params = params +    end + +    def setup +      ObjectCache.add_to_cache model +      stub_all_relations +      params.each(&method(:setup_att)) +      self +    end + + +    private + +    # Workers +    def setup_att key, value +      setup_reflection( model, key, value) && return +    end + +    def setup_belongs_to reflection, model, key, value +      model.stub(key){value} +      has_manys =  +        value.class.reflect_on_all_associations(:has_many).select{|v| v.foreign_type == "#{model.class.name.underscore.pluralize}_type" } +      has_manys.each do | has_many | +        value.send( has_many.name ) << model +      end +      true +    end + +    def setup_reflection model, key, value +      case reflection = model.class.reflections[key.to_s] +      when ActiveRecord::Reflection::BelongsToReflection +        setup_belongs_to reflection, model, key, value +      # when ActiveRecord::Reflection::HasManyReflection +      #   setup_has_many reflection, model, key, value +      else +        false +      end +    end + + +    def stub_all_relations +      reflections.each(&method(:stub_relation)) +    end + +    def stub_belongs_to name +      singleton.send :attr_reader, name +      define_singleton_method "#{name}=" do |value|  +        instance_variable_set("@#{name}", value)  +        has_manys =  +          value.class.reflect_on_all_associations(:has_many).select{|v| v.foreign_type == "#{self.class.name.underscore.pluralize}_type" } +        has_manys.each do | has_many | +          value.send( has_many.name ) << self +        end +        value +      end +    end + +    def stub_has_many name +      empty = [] +      mystub(model, name){empty} +    end + +    def stub_relation name, reflection +      case reflection +      when ActiveRecord::Reflection::BelongsToReflection +        stub_belongs_to name +      when ActiveRecord::Reflection::HasManyReflection +        stub_has_many name  +      end +       +    end + +    # Meta +    def define_singleton_method name, &blk +      singleton.module_eval do +        define_method(name, &blk) +      end +    end +    def mystub rcv, name, &blk +      class << rcv; self end +        .module_eval do +          define_method(name, &blk) +        end +    end + +    # Lazy Values +    def reflections +      @__reflections__ ||= model.class.reflections +    end + +    def singleton +      @__singleton__ ||= class << model; self end +    end +  end +end diff --git a/spec/support/faster/model_stubber/object_cache.rb b/spec/support/faster/model_stubber/object_cache.rb new file mode 100644 index 000000000..5749be76f --- /dev/null +++ b/spec/support/faster/model_stubber/object_cache.rb @@ -0,0 +1,23 @@ +module ModelStubber +  module ObjectCache extend self + +    def add_to_cache model +      model.id = cache[model.class].keys.last.try(:succ) || 1 +      cache[model.class].update( model.id => model ) +    end + +    def empty_cache! +       @__cache__ = _cache +    end + +    private + +    def cache +       @__cache__ ||= _cache  +    end +    def _cache +      Hash.new { |h, k| h[k] = {} } +    end + +  end +end | 
