Skip to content
This repository was archived by the owner on Mar 15, 2021. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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