blueprints_boy 1.0.0

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +20 -0
  5. data/Appraisals +37 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +20 -0
  8. data/README.md +26 -0
  9. data/Rakefile +76 -0
  10. data/blueprints_boy.gemspec +27 -0
  11. data/gemfiles/ar3.1.gemfile +8 -0
  12. data/gemfiles/ar3.2.gemfile +8 -0
  13. data/gemfiles/ar4.0.gemfile +8 -0
  14. data/gemfiles/ar4.1.gemfile +8 -0
  15. data/gemfiles/mongoid2.gemfile +8 -0
  16. data/gemfiles/mongoid3.gemfile +8 -0
  17. data/gemfiles/mongoid4.gemfile +8 -0
  18. data/gemfiles/noorm.gemfile +5 -0
  19. data/integration/active_record/active_record_spec.rb +38 -0
  20. data/integration/active_record/active_record_truncation_spec.rb +26 -0
  21. data/integration/active_record/blueprints.rb +1 -0
  22. data/integration/active_record/setup.rb +8 -0
  23. data/integration/cucumber/blueprints.feature +20 -0
  24. data/integration/cucumber/step_definitions/blueprints_steps.rb +17 -0
  25. data/integration/cucumber/support/env.rb +11 -0
  26. data/integration/minitest/blueprints.rb +11 -0
  27. data/integration/minitest/test_minispec.rb +41 -0
  28. data/integration/minitest/test_minitest.rb +28 -0
  29. data/integration/mongoid/blueprints.rb +1 -0
  30. data/integration/mongoid/mongoid_spec.rb +50 -0
  31. data/integration/rspec/blueprints.rb +13 -0
  32. data/integration/rspec/rspec_spec.rb +113 -0
  33. data/integration/shared.rb +9 -0
  34. data/lib/blueprints_boy/blueprint.rb +59 -0
  35. data/lib/blueprints_boy/configuration.rb +48 -0
  36. data/lib/blueprints_boy/context.rb +53 -0
  37. data/lib/blueprints_boy/dependency.rb +23 -0
  38. data/lib/blueprints_boy/errors.rb +10 -0
  39. data/lib/blueprints_boy/factories.rb +18 -0
  40. data/lib/blueprints_boy/helper.rb +47 -0
  41. data/lib/blueprints_boy/integration/active_record.rb +11 -0
  42. data/lib/blueprints_boy/integration/cucumber.rb +9 -0
  43. data/lib/blueprints_boy/integration/minitest.rb +23 -0
  44. data/lib/blueprints_boy/integration/mongoid.rb +11 -0
  45. data/lib/blueprints_boy/integration/rspec.rb +20 -0
  46. data/lib/blueprints_boy/manager.rb +87 -0
  47. data/lib/blueprints_boy/railtie.rb +24 -0
  48. data/lib/blueprints_boy/registry.rb +28 -0
  49. data/lib/blueprints_boy/version.rb +3 -0
  50. data/lib/blueprints_boy.rb +62 -0
  51. data/spec/spec_helper.rb +25 -0
  52. data/spec/support/empty_file.rb +0 -0
  53. data/spec/support/fixtures.rb +41 -0
  54. data/spec/support/manager_fixture.rb +3 -0
  55. data/spec/unit/blueprint_spec.rb +102 -0
  56. data/spec/unit/blueprints_boy_spec.rb +15 -0
  57. data/spec/unit/configuration_spec.rb +41 -0
  58. data/spec/unit/context_spec.rb +145 -0
  59. data/spec/unit/dependency_spec.rb +56 -0
  60. data/spec/unit/factories_spec.rb +27 -0
  61. data/spec/unit/manager_spec.rb +122 -0
  62. data/spec/unit/registry_spec.rb +47 -0
  63. metadata +189 -0
@@ -0,0 +1,113 @@
1
+ require 'bundler/setup'
2
+ require 'rspec'
3
+ require 'blueprints_boy'
4
+ require_relative '../shared'
5
+
6
+ BlueprintsBoy.enable do |config|
7
+ config.root = File.dirname(__FILE__)
8
+ config.global = :global_cherry
9
+ end
10
+
11
+ describe 'rspec integration' do
12
+ describe "set" do
13
+ it "should allow setting methods directly" do
14
+ set :apple, 'apple'
15
+ apple.should == 'apple'
16
+ end
17
+
18
+ it "should return value that is set" do
19
+ set(:apple, 'apple').should == 'apple'
20
+ end
21
+
22
+ it "should auto set variable" do
23
+ autoset :apple, 'apple'
24
+ apple.should == 'apple'
25
+ end
26
+
27
+ it "should not auto set variable if it's already set" do
28
+ set :variable, :correct
29
+ autoset :variable, :incorrect
30
+ variable.should == :correct
31
+ end
32
+
33
+ it "should still autoset variable in blueprint_data even if environment defines method with same name" do
34
+ def self.variable
35
+ end
36
+
37
+ autoset :variable, :correct
38
+ variable.should be_nil
39
+ blueprint_data(:variable).should == :correct
40
+ end
41
+
42
+ it "should still return new value if variable is already set" do
43
+ set :variable, :correct
44
+ autoset(:variable, :incorrect).should == :incorrect
45
+ end
46
+
47
+ it "should allow reaching fixtures through fixtures method" do
48
+ set :apple, 'apple'
49
+ blueprint_data(:apple).should == 'apple'
50
+ end
51
+ end
52
+
53
+ describe "build" do
54
+ it "should allow building blueprint" do
55
+ build :apple
56
+ apple.should == 'apple'
57
+ end
58
+
59
+ it "should allow building several blueprints" do
60
+ build :apple, :orange
61
+ apple.should == 'apple'
62
+ orange.should == 'orange'
63
+ end
64
+
65
+ it "should not allow to reach blueprints from previous specs" do
66
+ blueprint_data(:apple).should be_nil
67
+ end
68
+ end
69
+
70
+ describe "build with" do
71
+ it "should allow building using different strategy" do
72
+ build_with :attributes, :orange
73
+ orange.should == {name: 'orange'}
74
+ end
75
+ end
76
+
77
+ describe "build!" do
78
+ it "allows building blueprint twice" do
79
+ orange1 = build! :orange
80
+ orange2 = build! :orange => {name: 'not apple'}
81
+ orange1.should == 'orange'
82
+ orange2.should == 'not apple'
83
+ end
84
+ end
85
+
86
+ describe "build_new" do
87
+ it "builds blueprint using :new strategy" do
88
+ build_new :orange
89
+ orange.should == 'new orange'
90
+ end
91
+ end
92
+
93
+ describe "build_attributes" do
94
+ it "returns attributes for building" do
95
+ build_attributes :orange => {size: 2}
96
+ orange.should == {name: 'orange', size: 2}
97
+ end
98
+ end
99
+
100
+ describe "class level set" do
101
+ build :apple
102
+
103
+ it "should build blueprints in before filter" do
104
+ apple.should == 'apple'
105
+ end
106
+ end
107
+
108
+ describe "global" do
109
+ it "should build global blueprints" do
110
+ global_cherry.should == 'cherry'
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |c|
3
+ c.syntax = :should, :expect
4
+ end
5
+
6
+ config.mock_with :rspec do |c|
7
+ c.syntax = :should, :expect
8
+ end
9
+ end
@@ -0,0 +1,59 @@
1
+ class BlueprintsBoy::Blueprint
2
+ Data = Struct.new(:name, :options, :attributes, :factory)
3
+ attr_reader :name, :context
4
+
5
+ def initialize(context, name, attrs = {}, &block)
6
+ @context = context
7
+ @name = name.to_sym
8
+ @strategies = {
9
+ create: block,
10
+ attributes: proc { |data| data.attributes }
11
+ }
12
+ attributes(attrs)
13
+ end
14
+
15
+ def build(environment, strategy, options = {})
16
+ data = Data.new(@name, options, normalized_attributes(environment).merge(options), @context.factory_class)
17
+ block = @strategies[strategy]
18
+ block ||= BlueprintsBoy.factories[@context.factory_class, strategy] if @context.factory_class
19
+ if block
20
+ environment.autoset(@name, environment.instance_exec(data, &block))
21
+ else
22
+ raise BlueprintsBoy::StrategyNotFound, "Blueprint #{@name.inspect} does not define strategy #{strategy.inspect}"
23
+ end
24
+ end
25
+
26
+ def depends_on(*dependencies)
27
+ update_context dependencies, nil, nil
28
+ end
29
+
30
+ def attributes(attributes)
31
+ update_context nil, attributes, nil
32
+ end
33
+
34
+ def factory(factory_class)
35
+ update_context nil, nil, factory_class
36
+ end
37
+
38
+ def blueprint(strategy, &block)
39
+ @strategies[strategy] = block
40
+ end
41
+
42
+ private
43
+
44
+ def normalized_attributes(environment)
45
+ @context.attrs.each_with_object({}) do |(key, value), normalized|
46
+ normalized[key] = case value
47
+ when BlueprintsBoy::Dependency
48
+ environment.instance_eval(&value)
49
+ else
50
+ value
51
+ end
52
+ end
53
+ end
54
+
55
+ def update_context(dependencies, attributes, factory_class)
56
+ @context = @context.chain(dependencies, attributes, factory_class)
57
+ self
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ module BlueprintsBoy
2
+ # Contains configuration of blueprints. Instance of this is yielded in Blueprints.enable block.
3
+ # @example Configuring through Blueprints.enable block
4
+ # Blueprints.enable do |config|
5
+ # config.prebuild = :user, :profile
6
+ # end
7
+ # @example Configuring directly
8
+ # Blueprints.config.transactions = false
9
+ class Configuration
10
+ # Allows passing custom filename pattern in case blueprints are held in place other than spec/blueprint, test/blueprint, blueprint.
11
+ attr_reader :filenames
12
+ # Allows passing scenarios that should be prebuilt and available in all tests. Works similarly to fixtures.
13
+ attr_accessor :prebuild
14
+ # Allows passing custom root folder to use in case of non rails project. Defaults to Rails.root or current folder if Rails is not defined.
15
+ attr_reader :root
16
+ # By default blueprints runs each test in it's own transaction. This may sometimes be not desirable so this options allows to turn this off.
17
+ attr_accessor :transactions
18
+ # Define global blueprints that are prebuilt in all tests
19
+ attr_reader :global
20
+
21
+ # Initializes new Configuration object with default attributes.
22
+ # By defaults filename patterns are: blueprint.rb and blueprint/*.rb in spec, test and root directories.
23
+ # Also by default prebuildable blueprints list is empty, transactions are enabled and root is set to Rails.root or current directory.
24
+ def initialize
25
+ self.filenames = [nil, "spec", "test"].map do |dir|
26
+ ['blueprints.rb', 'blueprints/*.rb'].map do |pattern|
27
+ File.join([dir, pattern].compact)
28
+ end
29
+ end
30
+ @prebuild = []
31
+ @transactions = true
32
+ @root = defined?(Rails) ? Rails.root : Pathname.pwd
33
+ @global = []
34
+ end
35
+
36
+ def filenames=(value)
37
+ @filenames = Array(value).flatten.collect { |path| Pathname.new(path) }
38
+ end
39
+
40
+ def root=(value)
41
+ @root = Pathname.new(value)
42
+ end
43
+
44
+ def global=(value)
45
+ @global = Array(value)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,53 @@
1
+ module BlueprintsBoy
2
+ class Context
3
+ attr_accessor :dependencies, :attrs, :factory_class
4
+
5
+ def initialize(file_name, &added_callback)
6
+ @file_name = file_name
7
+ @added_callback = added_callback
8
+ @dependencies = []
9
+ @attrs = {}
10
+ @factory_class = nil
11
+ instance_eval(File.read(file_name), file_name)
12
+ end
13
+
14
+ def depends_on(*dependencies, &block)
15
+ chain(dependencies, nil, nil, &block)
16
+ end
17
+
18
+ def attributes(attributes, &block)
19
+ chain(nil, attributes, nil, &block)
20
+ end
21
+
22
+ def factory(factory_class, &block)
23
+ chain(nil, nil, factory_class, &block)
24
+ end
25
+
26
+ def chain(dependencies, attributes, factory, &block)
27
+ dup.tap do |context|
28
+ context.dependencies |= dependencies if dependencies
29
+ context.attrs = context.attrs.merge(attributes) if attributes
30
+ context.factory_class = factory if factory
31
+ context.instance_eval(&block) if block
32
+ end
33
+ end
34
+
35
+ def blueprint(*args, &block)
36
+ Blueprint.new(self, *args, &block).tap do |blueprint|
37
+ @added_callback.call blueprint if @added_callback
38
+ end
39
+ end
40
+
41
+ def group(groups)
42
+ groups.collect do |name, children|
43
+ blueprint(name) { build(*children) }
44
+ end
45
+ end
46
+
47
+ def dependency(name, *args, &block)
48
+ BlueprintsBoy::Dependency.new(name, *args, &block)
49
+ end
50
+
51
+ alias_method :method_missing, :dependency
52
+ end
53
+ end
@@ -0,0 +1,23 @@
1
+ class BlueprintsBoy::Dependency < BasicObject
2
+ def initialize(name, *args)
3
+ @name = name
4
+ @options = args.extract_options!
5
+ @blueprint_name = args.first || @name
6
+ @registry = []
7
+ end
8
+
9
+ def to_proc
10
+ name, options, registry, blueprint_name = @name, @options, @registry, @blueprint_name
11
+ ::Proc.new do
12
+ build blueprint_name => options
13
+ registry.inject(blueprint_data(name)) do |value, (method, args, block)|
14
+ value.send(method, *args, &block)
15
+ end
16
+ end
17
+ end
18
+
19
+ def method_missing(method, *args, &block)
20
+ @registry << [method, args, block]
21
+ self
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module BlueprintsBoy
2
+ class BlueprintNotFound < StandardError
3
+ end
4
+
5
+ class FactoryNotFound < StandardError
6
+ end
7
+
8
+ class StrategyNotFound < StandardError
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ module BlueprintsBoy
2
+ class Factories
3
+ def initialize
4
+ @factories = Hash.new { |hash, key| hash[key] = {} }
5
+ end
6
+
7
+ def add(factory_class, strategy, &block)
8
+ @factories[factory_class][strategy] = block
9
+ end
10
+
11
+ def [](factory_class, strategy)
12
+ factory_class.ancestors.each do |ancestor|
13
+ return @factories[ancestor][strategy] if @factories.key?(ancestor)
14
+ end
15
+ raise FactoryNotFound, "Factory for #{factory_class} can't be located"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ module BlueprintsBoy::Helper
2
+ def set(name, value)
3
+ instance_eval <<-RUBY, __FILE__, __LINE__ + 1
4
+ def self.#{name}
5
+ @_blueprint_data[:#{name}]
6
+ end
7
+ RUBY
8
+ @_blueprint_data[name] = value
9
+ end
10
+
11
+ def autoset(name, value)
12
+ if respond_to?(name)
13
+ @_blueprint_data[name] ||= value
14
+ else
15
+ set(name, value)
16
+ end
17
+ value
18
+ end
19
+
20
+ def blueprint_data(name = nil)
21
+ if name
22
+ @_blueprint_data[name]
23
+ else
24
+ @_blueprint_data
25
+ end
26
+ end
27
+
28
+ def build(*names)
29
+ build_with nil, *names
30
+ end
31
+
32
+ def build!(*names)
33
+ build_with :create, *names
34
+ end
35
+
36
+ def build_new(*names)
37
+ build_with :new, *names
38
+ end
39
+
40
+ def build_attributes(*names)
41
+ build_with :attributes, *names
42
+ end
43
+
44
+ def build_with(strategy, *names)
45
+ BlueprintsBoy.manager.build(self, names, strategy: strategy)
46
+ end
47
+ end
@@ -0,0 +1,11 @@
1
+ if ActiveRecord::VERSION::MAJOR < 4
2
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :create) { |data| data.factory.create!(data.attributes, without_protection: true) }
3
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :new) { |data| data.factory.new(data.attributes, without_protection: true) }
4
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :update) { |data| blueprint_data(data.name).update_attributes!(data.options, without_protection: true) }
5
+ else
6
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :create) { |data| data.factory.create!(data.attributes) }
7
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :new) { |data| data.factory.new(data.attributes) }
8
+ BlueprintsBoy.factories.add(ActiveRecord::Base, :update) { |data| blueprint_data(data.name).update_attributes!(data.options) }
9
+ end
10
+
11
+ DatabaseCleaner[:active_record].strategy = BlueprintsBoy.config.transactions ? :transaction : :truncation
@@ -0,0 +1,9 @@
1
+ World BlueprintsBoy::Helper
2
+
3
+ Before do
4
+ BlueprintsBoy.manager.setup(self)
5
+ end
6
+
7
+ After do
8
+ BlueprintsBoy.manager.teardown
9
+ end
@@ -0,0 +1,23 @@
1
+ module BlueprintsBoy::MinitestHelper
2
+ def before_setup
3
+ super
4
+ BlueprintsBoy.manager.setup(self)
5
+ end
6
+
7
+ def after_teardown
8
+ super
9
+ BlueprintsBoy.manager.teardown
10
+ end
11
+
12
+ module ClassMethods
13
+ def build(*args)
14
+ before do
15
+ build(*args)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ MiniTest::Unit::TestCase.send :include, BlueprintsBoy::Helper, BlueprintsBoy::MinitestHelper if defined?(MiniTest::Unit::TestCase)
22
+ MiniTest::Test.send :include, BlueprintsBoy::Helper, BlueprintsBoy::MinitestHelper if defined?(MiniTest::Test)
23
+ MiniTest::Spec.send :extend, BlueprintsBoy::MinitestHelper::ClassMethods if defined?(MiniTest::Spec)
@@ -0,0 +1,11 @@
1
+ if Mongoid::VERSION.to_i < 4
2
+ BlueprintsBoy.factories.add(Mongoid::Document, :create) { |data| data.factory.create!(data.attributes, without_protection: true) }
3
+ BlueprintsBoy.factories.add(Mongoid::Document, :new) { |data| data.factory.new(data.attributes, without_protection: true) }
4
+ BlueprintsBoy.factories.add(Mongoid::Document, :update) { |data| blueprint_data(data.name).update_attributes!(data.options, without_protection: true) }
5
+ else
6
+ BlueprintsBoy.factories.add(Mongoid::Document, :create) { |data| data.factory.create!(data.attributes) }
7
+ BlueprintsBoy.factories.add(Mongoid::Document, :new) { |data| data.factory.new(data.attributes) }
8
+ BlueprintsBoy.factories.add(Mongoid::Document, :update) { |data| blueprint_data(data.name).update_attributes!(data.options) }
9
+ end
10
+
11
+ DatabaseCleaner[:mongoid].strategy = :truncation
@@ -0,0 +1,20 @@
1
+ module BlueprintsBoy::RSpecHelper
2
+ def build(*args)
3
+ before do
4
+ build(*args)
5
+ end
6
+ end
7
+ end
8
+
9
+ RSpec.configure do |config|
10
+ config.include BlueprintsBoy::Helper
11
+ config.extend BlueprintsBoy::RSpecHelper
12
+
13
+ config.before do
14
+ BlueprintsBoy.manager.setup(self)
15
+ end
16
+
17
+ config.after do
18
+ BlueprintsBoy.manager.teardown
19
+ end
20
+ end if RSpec.respond_to?(:configure) # Otherwise db:seed might crash
@@ -0,0 +1,87 @@
1
+ module BlueprintsBoy
2
+ class Manager
3
+ attr_reader :blueprints, :registry
4
+
5
+ def initialize
6
+ @blueprints = {}
7
+ @registry = nil
8
+ end
9
+
10
+ def add(blueprint)
11
+ @blueprints[blueprint.name] = blueprint
12
+ end
13
+
14
+ def find(name)
15
+ @blueprints[name] or raise BlueprintNotFound, "Blueprint :#{name} cannot be found"
16
+ end
17
+
18
+ alias_method :[], :find
19
+
20
+ def build(environment, names, options = {})
21
+ result = parse_names(names).collect do |name, attributes|
22
+ build_blueprint(environment, name, attributes, options)
23
+ end
24
+ result.size > 1 ? result : result.first
25
+ end
26
+
27
+ def setup(environment)
28
+ prepare_env(environment)
29
+ push_registry
30
+ @registry.restore.each { |name, value| environment.set name, value }
31
+
32
+ DatabaseCleaner.start
33
+ rescue DatabaseCleaner::NoORMDetected
34
+ # ignored
35
+ end
36
+
37
+ def teardown
38
+ @registry = @registry.parent
39
+ DatabaseCleaner.clean
40
+ rescue DatabaseCleaner::NoORMDetected
41
+ # ignored
42
+ end
43
+
44
+ def push_registry(blueprint_names = [])
45
+ @registry = Registry.new(blueprint_names, @registry)
46
+
47
+ environment = Object.new
48
+ environment.singleton_class.send(:include, BlueprintsBoy::Helper)
49
+ prepare_env(environment)
50
+ build(environment, @registry.names)
51
+ @registry.store environment.blueprint_data
52
+ end
53
+
54
+ private
55
+
56
+ def prepare_env(environment)
57
+ environment.instance_variable_set(:@_blueprint_data, {})
58
+ end
59
+
60
+ def build_blueprint(environment, name, attributes, options)
61
+ strategy = options[:strategy] || default_strategy_for(name, attributes)
62
+ return environment.blueprint_data(name) if strategy.nil? # Blueprint is already built
63
+
64
+ @registry.built << name
65
+ blueprint = find(name)
66
+ build environment, blueprint.context.dependencies if blueprint.context.dependencies.present?
67
+ blueprint.build(environment, strategy, attributes || {})
68
+ end
69
+
70
+ def default_strategy_for(name, attributes)
71
+ if @registry.built.include?(name)
72
+ if attributes.present?
73
+ :update
74
+ else
75
+ nil
76
+ end
77
+ else
78
+ :create
79
+ end
80
+ end
81
+
82
+ def parse_names(names)
83
+ names_with_options = names.extract_options!
84
+ names.push(*names_with_options)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,24 @@
1
+ class BlueprintsBoy::Railtie < Rails::Railtie
2
+ class Seeder
3
+ def initialize(parent)
4
+ @parent = parent
5
+ end
6
+
7
+ def load_seed
8
+ BlueprintsBoy.enable
9
+
10
+ TOPLEVEL_BINDING.eval('self').instance_eval do
11
+ @_blueprint_data = {}
12
+ include BlueprintsBoy::Helper
13
+ end
14
+
15
+ @parent.load_seed
16
+ end
17
+ end
18
+
19
+ initializer 'blueprints_boy.set_seed_loader' do
20
+ if defined?(ActiveRecord::Tasks::DatabaseTasks)
21
+ ActiveRecord::Tasks::DatabaseTasks.seed_loader = Seeder.new(ActiveRecord::Tasks::DatabaseTasks.seed_loader)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module BlueprintsBoy
2
+ class Registry
3
+ attr_reader :built, :parent, :names
4
+
5
+ def initialize(names, parent)
6
+ @names = names
7
+ @parent = parent
8
+ @built = Set.new
9
+ @built.merge(parent.built) if parent
10
+
11
+ @stored = {}
12
+ end
13
+
14
+ def store(data)
15
+ data.each do |name, value|
16
+ @stored[name] = Marshal.dump(value)
17
+ end
18
+ end
19
+
20
+ def restore
21
+ data = @stored.each_with_object({}) do |(name, dump), result|
22
+ result[name] = Marshal.load(dump)
23
+ end
24
+ data.reverse_merge!(@parent.restore) if @parent
25
+ data
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module BlueprintsBoy
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,62 @@
1
+ require 'active_support/dependencies/autoload'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'active_support/core_ext/hash/reverse_merge'
5
+ require 'database_cleaner'
6
+ require 'blueprints_boy/version'
7
+ require 'blueprints_boy/railtie' if defined?(Rails)
8
+
9
+ module BlueprintsBoy
10
+ extend ActiveSupport::Autoload
11
+
12
+ autoload :BlueprintNotFound, 'blueprints_boy/errors'
13
+ autoload :FactoryNotFound, 'blueprints_boy/errors'
14
+ autoload :StrategyNotFound, 'blueprints_boy/errors'
15
+
16
+ autoload :Configuration
17
+ autoload :Helper
18
+ autoload :Context
19
+ autoload :Manager
20
+ autoload :Factories
21
+ autoload :Blueprint
22
+ autoload :Dependency
23
+ autoload :Registry
24
+
25
+ def self.enable
26
+ yield config if block_given?
27
+ require 'blueprints_boy/integration/minitest' if defined?(MiniTest)
28
+ require 'blueprints_boy/integration/rspec' if defined?(RSpec)
29
+ require 'blueprints_boy/integration/cucumber' if defined?(Cucumber)
30
+ require 'blueprints_boy/integration/active_record' if defined?(ActiveRecord)
31
+ require 'blueprints_boy/integration/mongoid' if defined?(Mongoid)
32
+ prepare
33
+ manager.push_registry(config.global)
34
+ end
35
+
36
+ def self.prepare
37
+ read_files
38
+ DatabaseCleaner.clean_with(:truncation)
39
+ rescue DatabaseCleaner::NoORMDetected
40
+ # ignored
41
+ end
42
+
43
+ def self.read_files
44
+ config.filenames.each do |pattern|
45
+ Dir[config.root.join(pattern)].each do |file_name|
46
+ Context.new(file_name) { |blueprint| manager.add(blueprint) } if File.file?(file_name)
47
+ end
48
+ end
49
+ end
50
+
51
+ def self.manager
52
+ @manager ||= Manager.new
53
+ end
54
+
55
+ def self.config
56
+ @config ||= Configuration.new
57
+ end
58
+
59
+ def self.factories
60
+ @factories ||= Factories.new
61
+ end
62
+ end