Skip to content
This repository has been archived by the owner on Mar 15, 2021. It is now read-only.

Remove global Fabrication.manager reference in Defintion #313

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
14 changes: 1 addition & 13 deletions lib/fabricate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,20 @@ def self.attributes_for_times(count, name, overrides={}, &block)
end

def self.attributes_for(name, overrides={}, &block)
fail_if_initializing(name)
schematic(name).to_attributes(overrides, &block)
end

def self.to_params(name, overrides={}, &block)
fail_if_initializing(name)
schematic(name).to_params(overrides, &block)
end

def self.build(name, overrides={}, &block)
fail_if_initializing(name)
schematic(name).build(overrides, &block).tap do |object|
Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps?
end
end

def self.create(name, overrides={}, &block)
fail_if_initializing(name)
schematic(name).fabricate(overrides, &block)
end

Expand All @@ -38,14 +34,6 @@ def self.sequence(name=Fabrication::Sequencer::DEFAULT, start=nil, &block)
end

def self.schematic(name)
Fabrication.manager.load_definitions if Fabrication.manager.empty?
Fabrication.manager[name] || raise(Fabrication::UnknownFabricatorError.new(name))
Fabrication.manager.load_schematic name
end

private

def self.fail_if_initializing(name)
raise Fabrication::MisplacedFabricateError.new(name) if Fabrication.manager.initializing?
end

end
3 changes: 2 additions & 1 deletion lib/fabrication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module Schematic
autoload :Manager, 'fabrication/schematic/manager'
autoload :Evaluator, 'fabrication/schematic/evaluator'
autoload :Runner, 'fabrication/schematic/runner'
autoload :Loader, 'fabrication/schematic/loader'
end

autoload :Config, 'fabrication/config'
Expand Down Expand Up @@ -48,7 +49,7 @@ def self.configure(&block)
end

def self.manager
@manager ||= Fabrication::Schematic::Manager.instance
@manager ||= Fabrication::Schematic::Manager.new
end

def self.schematics
Expand Down
31 changes: 16 additions & 15 deletions lib/fabrication/schematic/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ class Fabrication::Schematic::Definition
Fabrication::Generator::Base
]

attr_accessor :name, :options, :block
def initialize(name, options={}, &block)
attr_accessor :name, :options, :block, :manager
def initialize(name, manager, options={}, &block)
self.name = name
self.options = options
self.block = block
self.manager = manager
end

def process_block(&block)
Expand Down Expand Up @@ -54,47 +55,47 @@ def sorted_attributes
end

def build(overrides={}, &block)
Fabrication.manager.prevent_recursion!
if Fabrication.manager.to_params_stack.any?
manager.prevent_recursion!
if manager.to_params_stack.any?
to_params(overrides, &block)
else
begin
Fabrication.manager.build_stack << name
manager.build_stack << name
merge(overrides, &block).instance_eval do
generator.new(klass).build(sorted_attributes, callbacks)
end
ensure
Fabrication.manager.build_stack.pop
manager.build_stack.pop
end
end
end

def fabricate(overrides={}, &block)
Fabrication.manager.prevent_recursion!
if Fabrication.manager.build_stack.any?
manager.prevent_recursion!
if manager.build_stack.any?
build(overrides, &block)
elsif Fabrication.manager.to_params_stack.any?
elsif manager.to_params_stack.any?
to_params(overrides, &block)
else
begin
Fabrication.manager.create_stack << name
manager.create_stack << name
merge(overrides, &block).instance_eval do
generator.new(klass).create(sorted_attributes, callbacks)
end
ensure
Fabrication.manager.create_stack.pop
manager.create_stack.pop
end
end
end

def to_params(overrides={}, &block)
Fabrication.manager.prevent_recursion!
Fabrication.manager.to_params_stack << name
manager.prevent_recursion!
manager.to_params_stack << name
merge(overrides, &block).instance_eval do
generator.new(klass).to_params(sorted_attributes)
end
ensure
Fabrication.manager.to_params_stack.pop
manager.to_params_stack.pop
end

def to_attributes(overrides={}, &block)
Expand Down Expand Up @@ -159,6 +160,6 @@ def load_body
end

def parent
@parent ||= Fabrication.manager[options[:from].to_s] if options[:from]
@parent ||= manager[options[:from].to_s] if options[:from]
end
end
39 changes: 39 additions & 0 deletions lib/fabrication/schematic/loader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class Fabrication::Schematic::Loader
def initialize(manager)
@manager = manager
end

def preinitialize
@initializing = true
@manager.clear
end

def initializing?
@initializing ||= nil
end

def freeze
@initializing = false
end

def load_definitions
preinitialize
Fabrication::Config.path_prefixes.each do |prefix|
Fabrication::Config.fabricator_paths.each do |folder|
Dir.glob(File.join(prefix.to_s, folder, '**', '*.rb')).sort.each do |file|
load file
end
end
end
rescue Exception => e
raise e
ensure
freeze
end

def load_schematic(name)
raise Fabrication::MisplacedFabricateError.new(name) if initializing?
load_definitions if @manager.empty?
@manager[name] || raise(Fabrication::UnknownFabricatorError.new(name))
end
end
41 changes: 12 additions & 29 deletions lib/fabrication/schematic/manager.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
require 'singleton'

class Fabrication::Schematic::Manager
include Singleton
require 'forwardable'

def preinitialize
@initializing = true
clear
end
class Fabrication::Schematic::Manager
extend Forwardable
def_delegators :@loader,
:load_definitions,
:load_schematic,
:preinitialize,
:initializing?,
:freeze

def initializing?
@initializing ||= nil
def initialize
@loader = Fabrication::Schematic::Loader.new(self)
end

def schematics
Expand All @@ -19,10 +21,6 @@ def schematics
def clear; schematics.clear end
def empty?; schematics.empty? end

def freeze
@initializing = false
end

def register(name, options, &block)
name = name.to_sym
raise_if_registered(name)
Expand All @@ -45,21 +43,6 @@ def to_params_stack
@to_params_stack ||= []
end

def load_definitions
preinitialize
Fabrication::Config.path_prefixes.each do |prefix|
Fabrication::Config.fabricator_paths.each do |folder|
Dir.glob(File.join(prefix.to_s, folder, '**', '*.rb')).sort.each do |file|
load file
end
end
end
rescue Exception => e
raise e
ensure
freeze
end

def prevent_recursion!
(create_stack + build_stack + to_params_stack).group_by(&:to_sym).each do |name, values|
raise Fabrication::InfiniteRecursionError.new(name) if values.length > Fabrication::Config.recursion_limit
Expand All @@ -73,7 +56,7 @@ def raise_if_registered(name)
end

def store(name, aliases, options, &block)
schematic = schematics[name] = Fabrication::Schematic::Definition.new(name, options, &block)
schematic = schematics[name] = Fabrication::Schematic::Definition.new(name, self, options, &block)
aliases.each { |as| schematics[as.to_sym] = schematic }
end

Expand Down
17 changes: 9 additions & 8 deletions spec/fabrication/generator/base_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'spec_helper'

describe Fabrication::Generator::Base do
let(:manager) { Fabrication.manager }

describe ".supports?" do
subject { Fabrication::Generator::Base }
Expand All @@ -14,7 +15,7 @@
let(:generator) { Fabrication::Generator::Base.new(ParentRubyObject) }

let(:attributes) do
Fabrication::Schematic::Definition.new('ParentRubyObject') do
Fabrication::Schematic::Definition.new('ParentRubyObject', manager) do
string_field 'different content'
extra_fields(count: 4) { |attrs, index| "field #{index}" }
end.attributes
Expand All @@ -39,7 +40,7 @@

context "using init_with" do
let(:schematic) do
Fabrication::Schematic::Definition.new('ClassWithInit') do
Fabrication::Schematic::Definition.new('ClassWithInit', manager) do
on_init { init_with(:a, :b) }
end
end
Expand All @@ -52,7 +53,7 @@

context "not using init_with" do
let(:schematic) do
Fabrication::Schematic::Definition.new('ClassWithInit') do
Fabrication::Schematic::Definition.new('ClassWithInit', manager) do
on_init { [ :a, :b ] }
end
end
Expand All @@ -70,7 +71,7 @@

context "using only raw values" do
let(:schematic) do
Fabrication::Schematic::Definition.new('ClassWithInit') do
Fabrication::Schematic::Definition.new('ClassWithInit', manager) do
initialize_with { Struct.new(:arg1, :arg2).new(:fixed_value) }
end
end
Expand All @@ -83,7 +84,7 @@

context "using attributes inside block" do
let(:schematic) do
Fabrication::Schematic::Definition.new('ClassWithInit') do
Fabrication::Schematic::Definition.new('ClassWithInit', manager) do
arg1 10
initialize_with { Struct.new(:arg1, :arg2).new(arg1, arg1 + 10) }
end
Expand All @@ -109,7 +110,7 @@

context "using an after_create hook" do
let(:schematic) do
Fabrication::Schematic::Definition.new('ParentRubyObject') do
Fabrication::Schematic::Definition.new('ParentRubyObject', manager) do
string_field 'something'
after_create { |k| k.string_field.upcase! }
end
Expand All @@ -127,7 +128,7 @@
context 'all the callbacks' do
subject { schematic.build }
let(:schematic) do
Fabrication::Schematic::Definition.new('ParentRubyObject') do
Fabrication::Schematic::Definition.new('ParentRubyObject', manager) do
string_field ""
after_build { |k| k.string_field += '1' }
before_validation { |k| k.string_field += '2' }
Expand Down Expand Up @@ -159,7 +160,7 @@
context 'all the callbacks' do
subject { schematic.fabricate }
let(:schematic) do
Fabrication::Schematic::Definition.new('ParentRubyObject') do
Fabrication::Schematic::Definition.new('ParentRubyObject', manager) do
string_field ""
after_build { |k| k.string_field += '1' }
before_validation { |k| k.string_field += '2' }
Expand Down
12 changes: 6 additions & 6 deletions spec/fabrication/schematic/definition_spec.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require 'spec_helper'

describe Fabrication::Schematic::Definition do

let(:manager) { Fabrication.manager }
let(:schematic) do
Fabrication::Schematic::Definition.new('OpenStruct') do
Fabrication::Schematic::Definition.new('OpenStruct', manager) do
name "Orgasmo"
something(:param => 2) { "hi!" }
another_thing { 25 }
Expand Down Expand Up @@ -165,7 +165,7 @@
let(:init_block) { lambda {} }
let(:init_schematic) do
block = init_block
Fabrication::Schematic::Definition.new('OpenStruct') do
Fabrication::Schematic::Definition.new('OpenStruct', manager) do
on_init(&block)
end
end
Expand Down Expand Up @@ -193,7 +193,7 @@
let(:init_block) { lambda {} }
let(:init_schematic) do
block = init_block
Fabrication::Schematic::Definition.new('OpenStruct') do
Fabrication::Schematic::Definition.new('OpenStruct', manager) do
initialize_with(&block)
end
end
Expand All @@ -219,7 +219,7 @@

describe '#transient' do
let(:definition) do
Fabrication::Schematic::Definition.new('OpenStruct') do
Fabrication::Schematic::Definition.new('OpenStruct', manager) do
transient :one, :two => 'with a default value', :three => 200
end
end
Expand All @@ -245,7 +245,7 @@
describe '#sorted_attributes' do
subject { definition.sorted_attributes.map(&:name) }
let(:definition) do
Fabrication::Schematic::Definition.new('OpenStruct') do
Fabrication::Schematic::Definition.new('OpenStruct', manager) do
three { nil }
one ''
transient :two
Expand Down
3 changes: 2 additions & 1 deletion spec/fabrication/schematic/evaluator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require 'spec_helper'

describe Fabrication::Schematic::Evaluator do
let(:definition) { Fabrication::Schematic::Definition.new(ParentRubyObject) }
let(:manager) { Fabrication.manager }
let(:definition) { Fabrication::Schematic::Definition.new(ParentRubyObject, manager) }
let(:evaluator) { Fabrication::Schematic::Evaluator.new }

describe 'attribute handling' do
Expand Down
2 changes: 1 addition & 1 deletion spec/fabrication/schematic/manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

describe Fabrication::Schematic::Manager do

let(:manager) { Fabrication::Schematic::Manager.instance }
let(:manager) { Fabrication::Schematic::Manager.new }
before { manager.clear }

describe "#register" do
Expand Down