action_factory 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 45042f5597609edaa5fbf3a24b85f970f67718a99072f32fbb4b2ec3a331eb42
4
+ data.tar.gz: 9f09d6f30142805d35c36940811c46a0c1bfe4c392edd4cffef3e2fddd372511
5
+ SHA512:
6
+ metadata.gz: '008726cf59ddd69261213220f38887d9baca503e14c9db2aac61cf96fdadaa185e04ce2c34602c4365ed49f1c306ad3c7fbeb98d58acf88ad47a45805f8cf980'
7
+ data.tar.gz: 7db5bfe669686ce793af26aab8927f0b3ee7e168f4ae2411fa10adf7335c228dc91a0b2dd4a303423539e64e90cff5903cdfc12dd8023c41b0e6e39ed118de2e
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # ActionFactory
2
+ A Simple OOO Factory lib for Ruby (and Rails)
3
+
4
+ ## Usage
5
+
6
+ ### Setup
7
+ Create a base factory class
8
+ ```ruby
9
+ class ApplicationFactory < ActionFactory::Base
10
+ end
11
+ ```
12
+
13
+ If you're using `ActiveRecord`, add the `association` helpers
14
+ ```ruby
15
+ class ApplicationFactory < ActionFactory::Base
16
+ include ActionFactory::ActiveRecord
17
+ end
18
+ ```
19
+
20
+ ### Creating your first factory
21
+ ```ruby
22
+ class UserFactory < ApplicationFactory
23
+ attribute(:name) { "Hank Green" }
24
+ sequence(:email) { |i| "hgreen#{i}@example.com" }
25
+
26
+ trait(:activated) do
27
+ instance.activate!
28
+ end
29
+ end
30
+ ```
31
+
32
+ ### Callbacks
33
+ `ActionFactory::Base` uses `ActiveModel::Callbacks` to add the following lifecycle events:
34
+ ```
35
+ after_initialize
36
+ before_assign_attributes
37
+ around_assign_attributes
38
+ after_assign_attributes
39
+ before_create
40
+ around_create
41
+ after_create
42
+ ```
43
+
44
+ For example
45
+ ```ruby
46
+ class MyModelFactory < ApplicationFactory
47
+ after_initialize :do_the_thing
48
+
49
+ private
50
+
51
+ def do_the_thing
52
+ instance.some_attribute = true if attributes[:some_attribute].blank?
53
+ end
54
+ end
55
+ ```
56
+
57
+ ### Including helpers
58
+ You can use `ActionFactory::Helpers` to call `create(:my_factory_name)` and `build(:my_factory_name)`.
59
+ Here's an example for setting it up with RSpec:
60
+ ```ruby
61
+ RSpec.configure do |config|
62
+ config.include ActionFactory::Helpers
63
+ end
64
+ ```
65
+
66
+ ## Installation
67
+ Via bundler:
68
+ ```bash
69
+ bundle add action_factory
70
+ ```
71
+
72
+ Or install it yourself as:
73
+ ```bash
74
+ $ gem install action_factory
75
+ ```
76
+
77
+ ## Contributing
78
+ Contributions welcome
79
+
80
+ ## License
81
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
5
+ require "action_factory/runner"
6
+
7
+ module ActionFactory
8
+ module ActiveRecord
9
+
10
+ class Association
11
+ def initialize(strategy:, factory_name:, traits:, block:)
12
+ @strategy = strategy
13
+ @factory_name = factory_name
14
+ @traits = traits
15
+ @block = block
16
+ end
17
+
18
+ def generate(strategy)
19
+ @block ? @block.call(runner) : runner.run(strategy)
20
+ end
21
+
22
+ def runner
23
+ @runner ||= ActionFactory::Runner.new(@factory_name, *@traits, strategy: @strategy)
24
+ end
25
+ end
26
+
27
+ def self.included(base)
28
+ base.extend ClassMethods
29
+ base.class_exec do
30
+ after_assign_attributes :build_associations
31
+ end
32
+ end
33
+
34
+ module ClassMethods
35
+ def associations
36
+ @associations ||= {}.with_indifferent_access
37
+ end
38
+
39
+ def association(name, strategy: nil, factory: name, traits: [], &block)
40
+ associations[name] = Association.new(strategy:, factory_name: factory, traits:, block:)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def build_associations
47
+ self.class.associations.except(*@attributes.keys).each do |name, association|
48
+ associated_record = association.generate(@strategy)
49
+ @instance.association(name).writer(associated_record)
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionFactory
4
+ class AssignmentCompiler
5
+
6
+ def initialize(factory)
7
+ @factory = factory
8
+ end
9
+
10
+ def compile(assignments, only: nil, except: [])
11
+ if only.present? && except.present?
12
+ raise ArgumentError, "Cannot use both 'only' and 'except' options"
13
+ end
14
+
15
+ assignments = assignments.slice(*only) unless only.nil?
16
+
17
+ assignments.except(*except).transform_values do |assignment|
18
+ assignment.compile(@factory)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionFactory
4
+ module Assignments
5
+ class Attribute
6
+ def initialize(block)
7
+ @block = block
8
+ end
9
+
10
+ def compile(factory)
11
+ factory.instance_exec(&@block)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionFactory
4
+ module Assignments
5
+ class Sequence
6
+ def initialize(block)
7
+ @count = 0
8
+ @block = block
9
+ end
10
+
11
+ def compile(factory)
12
+ # @count += 1
13
+ factory.instance_exec(@count += 1, &@block)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionFactory
4
+ module Assignments
5
+ class Trait
6
+ def initialize(block)
7
+ @block = block
8
+ end
9
+
10
+ def compile(factory)
11
+ factory.instance_exec(factory.instance, &@block)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ require "action_factory/assignments/attribute"
2
+ require "action_factory/assignments/sequence"
3
+ require "action_factory/assignments/trait"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionFactory
4
+ class AttributeAssigner
5
+
6
+ def initialize(instance)
7
+ @instance = instance
8
+ end
9
+
10
+ def assign(attributes)
11
+ attributes.each do |name, value|
12
+ @instance.public_send("#{name}=", value)
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+ require "active_support/core_ext/module/delegation"
5
+ require "active_support/core_ext/object/deep_dup"
6
+
7
+ require "active_model/callbacks"
8
+
9
+ require "action_factory/assignment_compiler"
10
+ require "action_factory/attribute_assigner"
11
+ require "action_factory/assignments"
12
+
13
+ module ActionFactory
14
+ class Base
15
+ extend ActiveModel::Callbacks
16
+
17
+ define_model_callbacks :initialize, only: [:after]
18
+ define_model_callbacks :assign_attributes, :create
19
+
20
+ ClassNotFound = Class.new(StandardError)
21
+
22
+ class << self
23
+ attr_reader :initializer, :creator
24
+
25
+ def factory(name)
26
+ Registry.register(name, self.name)
27
+ end
28
+
29
+ def class_name(name)
30
+ @klass_name = name
31
+ end
32
+
33
+ def klass_name
34
+ @klass_name ||= name.delete_suffix('Factory')
35
+ end
36
+
37
+ def klass
38
+ @klass ||= klass_name.constantize
39
+ rescue NameError
40
+ raise ClassNotFound, "Class with name #{class_name.inspect} not found"
41
+ end
42
+
43
+ def to_initialize(&block)
44
+ raise ArgumentError, 'Block required' unless block_given?
45
+ @initializer = block
46
+ end
47
+
48
+ def to_create(&block)
49
+ raise ArgumentError, 'Block required' unless block_given?
50
+ @creator = block
51
+ end
52
+
53
+ def attribute(name, &block)
54
+ assignments[:attributes][name] = ActionFactory::Assignments::Attribute.new(block)
55
+ end
56
+
57
+ def sequence(name, &block)
58
+ assignments[:attributes][name] = ActionFactory::Assignments::Sequence.new(block)
59
+ end
60
+
61
+ def trait(name, &block)
62
+ assignments[:traits][name] = ActionFactory::Assignments::Trait.new(block)
63
+ end
64
+
65
+ def assignments
66
+ @assignments ||= begin
67
+ if self.superclass.respond_to?(:assignments)
68
+ self.superclass.assignments.deep_dup
69
+ else
70
+ ActiveSupport::HashWithIndifferentAccess.new { |hash, key| hash[key] = {}.with_indifferent_access }
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ delegate :initializer, :creator, :klass, :assignments, to: :class
77
+
78
+ attr_reader :traits, :attributes, :instance
79
+
80
+ def initialize(*traits, **attributes)
81
+ @traits = traits
82
+ @attributes = attributes
83
+ @instance = build_instance_with_callbacks
84
+ end
85
+
86
+ def run(strategy)
87
+ @strategy = strategy
88
+ public_send(@strategy)
89
+ end
90
+
91
+ def build
92
+ run_callbacks :assign_attributes do
93
+ assign_attributes
94
+ end
95
+ instance
96
+ end
97
+
98
+ def create
99
+ build
100
+ run_callbacks :create do
101
+ persist_instance
102
+ end
103
+ instance
104
+ end
105
+
106
+ def factory_attributes
107
+ @factory_attributes ||= assignment_compiler.compile(assignments[:attributes], except: @attributes.keys)
108
+ end
109
+
110
+ private
111
+
112
+ def build_instance_with_callbacks
113
+ run_callbacks :initialize do
114
+ build_instance
115
+ end
116
+ end
117
+
118
+ def build_instance
119
+ return klass.class_exec(self, &initializer) if initializer
120
+
121
+ klass.public_send(ActionFactory.configuration.initialize_method)
122
+ end
123
+
124
+ def persist_instance
125
+ return @instance.instance_exec(self, &creator) if creator
126
+
127
+ @instance.public_send(ActionFactory.configuration.persist_method)
128
+ end
129
+
130
+ def assign_attributes
131
+ attribute_assigner.assign(@attributes)
132
+ attribute_assigner.assign(factory_attributes)
133
+ assignment_compiler.compile(assignments[:traits], only: @traits)
134
+ end
135
+
136
+ def assignment_compiler
137
+ @assignment_compiler ||= AssignmentCompiler.new(self)
138
+ end
139
+
140
+ def attribute_assigner
141
+ @attribute_assigner ||= AttributeAssigner.new(instance)
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_factory/registry"
4
+
5
+ module ActionFactory
6
+ class FactoryFinder
7
+ FactoryNotFound = Class.new(StandardError)
8
+
9
+ class << self
10
+ def factory_class_for(name)
11
+ new(name).factory_class
12
+ end
13
+ end
14
+
15
+ def initialize(name)
16
+ @name = name
17
+ end
18
+
19
+ def factory_class
20
+ factory_class_name = Registry.factory_class_name(@name)
21
+ factory_class_name.constantize
22
+ rescue NameError
23
+ raise FactoryNotFound, "Factory with class name #{factory_class_name.inspect} not found"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require "action_factory/factory_finder"
4
+ require "action_factory/runner"
5
+
6
+ module ActionFactory
7
+ module Helpers
8
+ def build(factory_name, *traits, **attributes)
9
+ ActionFactory::Runner.run(factory_name, *traits, strategy: :build, **attributes)
10
+ end
11
+
12
+ def create(factory_name, *traits, **attributes)
13
+ ActionFactory::Runner.run(factory_name, *traits, strategy: :create, **attributes)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/inflections"
4
+
5
+ module ActionFactory
6
+ module Registry
7
+ class << self
8
+ def register(factory_name, factory_class_name)
9
+ factories[factory_name.to_sym] = factory_class_name
10
+ end
11
+
12
+ def factories
13
+ @factories ||= Hash.new { |factories, name| factories[name.to_sym] = name.to_s.classify }
14
+ end
15
+
16
+ def factory_class_name(factory_name)
17
+ "#{class_name(factory_name)}Factory"
18
+ end
19
+
20
+ def class_name(factory_name)
21
+ factories[factory_name.to_sym]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+
5
+ require "action_factory/factory_finder"
6
+
7
+ module ActionFactory
8
+ class Runner
9
+ class << self
10
+ def run(...)
11
+ new(...).run
12
+ end
13
+ end
14
+
15
+ attr_reader :factory, :factory_name, :strategy
16
+ delegate :traits, :attributes, to: :factory
17
+
18
+ def initialize(factory_name, *traits, strategy: nil, **attributes)
19
+ @factory_name = factory_name
20
+ @strategy = strategy
21
+ factory_class = FactoryFinder.factory_class_for(@factory_name)
22
+ @factory = factory_class.new(*traits, **attributes)
23
+ end
24
+
25
+ def run(strategy = nil)
26
+ @factory.run(strategy || @strategy)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module ActionFactory
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+
5
+ require "action_factory/version"
6
+ require "action_factory/helpers"
7
+ require "action_factory/base"
8
+
9
+ module ActionFactory
10
+ class Configuration
11
+ attr_accessor :persist_method, :initialize_method
12
+
13
+ def initialize
14
+ @persist_method = :save!
15
+ @initialize_method = :new
16
+ end
17
+ end
18
+
19
+ class << self
20
+ def configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ def configure
25
+ yield(configuration)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,66 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory::AssignmentCompiler do
4
+ let(:factory) { double }
5
+
6
+ subject(:compiler) { described_class.new(factory) }
7
+
8
+ describe "#compile" do
9
+ let(:name_attribute_assignment) { instance_double(ActionFactory::Assignments::Attribute) }
10
+ let(:uid_sequence_assignment) { instance_double(ActionFactory::Assignments::Sequence) }
11
+ let(:unique_trait_assignment) { instance_double(ActionFactory::Assignments::Sequence) }
12
+ let(:assignments) do
13
+ {
14
+ name: name_attribute_assignment,
15
+ uid: uid_sequence_assignment,
16
+ unique: unique_trait_assignment
17
+ }
18
+ end
19
+ let(:name) { "John" }
20
+ let(:uid) { "123" }
21
+ let(:unique) { "unique" }
22
+
23
+ let(:expected_attributes) do
24
+ {
25
+ name: name,
26
+ uid: uid,
27
+ unique: unique
28
+ }
29
+ end
30
+
31
+ it "compiles the assignments" do
32
+ assignments.each do |key, assignment|
33
+ expect(assignment).to receive(:compile).with(factory).and_return(send(key))
34
+ end
35
+ expect(compiler.compile(assignments)).to eq(expected_attributes)
36
+ end
37
+
38
+ context "when 'only' is given" do
39
+ let(:only) { [:name] }
40
+
41
+ it "compiles only the given assignments" do
42
+ expect(name_attribute_assignment).to receive(:compile).with(factory).and_return(name)
43
+ expect(compiler.compile(assignments, only: only)).to eq(name: name)
44
+ end
45
+ end
46
+
47
+ context "when 'except' is given" do
48
+ let(:except) { [:name] }
49
+
50
+ it "compiles all except the given assignments" do
51
+ expect(uid_sequence_assignment).to receive(:compile).with(factory).and_return(uid)
52
+ expect(unique_trait_assignment).to receive(:compile).with(factory).and_return(unique)
53
+ expect(compiler.compile(assignments, except: except)).to eq(uid: uid, unique: unique)
54
+ end
55
+ end
56
+
57
+ context "when both 'only' and 'except' are given" do
58
+ let(:only) { [:name] }
59
+ let(:except) { [:uid] }
60
+
61
+ it "raises an ArgumentError" do
62
+ expect { compiler.compile(assignments, only: only, except: except) }.to raise_error(ArgumentError)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory::AttributeAssigner do
4
+ let(:instance) { double }
5
+
6
+ subject(:assigner) { described_class.new(instance) }
7
+
8
+ describe "#assign" do
9
+ let(:attributes) { { name: "John" } }
10
+
11
+ it "assigns the attributes to the instance" do
12
+ expect(instance).to receive(:name=).with("John")
13
+ assigner.assign(attributes)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory::FactoryFinder do
4
+ describe ".factory_class_for" do
5
+ let(:factory_class) { Class.new(ActionFactory::Base) }
6
+
7
+ before do
8
+ stub_const("UserFactory", factory_class)
9
+ end
10
+
11
+ it "returns the factory class for the given name" do
12
+ expect(described_class.factory_class_for(:user)).to eq(factory_class)
13
+ end
14
+ end
15
+
16
+ describe "#factory_class" do
17
+ let(:factory_class) { Class.new(ActionFactory::Base) }
18
+ let(:factory_name) { :user }
19
+
20
+ before do
21
+ stub_const("UserFactory", factory_class)
22
+ end
23
+
24
+ subject(:factory_finder) { described_class.new(factory_name) }
25
+
26
+ it "returns the factory class for the given name" do
27
+ expect(factory_finder.factory_class).to eq(factory_class)
28
+ end
29
+
30
+ context "when the factory class is not found" do
31
+ let(:factory_name) { :foo }
32
+
33
+ it "raises an error" do
34
+ expect { factory_finder.factory_class }.to raise_error(ActionFactory::FactoryFinder::FactoryNotFound)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory::Registry do
4
+ let(:factory_name) { :user }
5
+ let(:model_name) { "CustomUser" }
6
+ let(:default_factory_class_name) { "UserFactory" }
7
+ let(:expected_factory_class_name) { "CustomUserFactory" }
8
+
9
+ describe ".register" do
10
+ subject(:register) { described_class.register(factory_name, model_name) }
11
+
12
+ it "registers the factory class name for the given factory name" do
13
+ expect { register }.to(
14
+ change { described_class.factory_class_name(factory_name) }.from(
15
+ default_factory_class_name
16
+ ).to(
17
+ expected_factory_class_name
18
+ )
19
+ )
20
+ end
21
+ end
22
+
23
+ describe ".factories" do
24
+ subject { described_class.factories }
25
+
26
+ it { is_expected.to be_a(Hash) }
27
+
28
+ it "returns a hash with default values" do
29
+ expect(subject.default_proc).to be_a(Proc)
30
+ expect(subject[:foo]).to eq("Foo")
31
+ end
32
+ end
33
+
34
+ describe ".factory_class_name" do
35
+ before do
36
+ described_class.register(factory_name, model_name)
37
+ end
38
+
39
+ subject(:factory_class_name) { described_class.factory_class_name(factory_name) }
40
+
41
+ it "returns the factory class name for the given factory name" do
42
+ expect(factory_class_name).to eq(expected_factory_class_name)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory::Runner do
4
+ describe "#run" do
5
+ let(:factory_class) { Class.new(ActionFactory::Base) }
6
+ let(:factory_name) { :user }
7
+ let(:attributes) { { name: "John" } }
8
+ let(:traits) { [:admin] }
9
+ let(:factory) { instance_double(ActionFactory::Base) }
10
+ let(:instance) { double }
11
+
12
+ before do
13
+ stub_const("UserFactory", factory_class)
14
+ allow(ActionFactory::FactoryFinder).to receive(:factory_class_for).with(factory_name).and_return(factory_class)
15
+ allow(factory_class).to receive(:new).with(*traits, **attributes).and_return(factory)
16
+ end
17
+
18
+ subject(:runner) { described_class.new(factory_name, *traits, **attributes) }
19
+
20
+ it "runs the factory" do
21
+ allow(factory).to receive(:run).with(nil).and_return(instance)
22
+ expect(runner.run).to eq(instance)
23
+ end
24
+
25
+ context "when a strategy is given" do
26
+ subject(:runner) { described_class.new(factory_name, *traits, strategy: strategy, **attributes) }
27
+
28
+ let(:strategy) { :create }
29
+
30
+ it "runs the factory with the given strategy" do
31
+ allow(factory).to receive(:run).with(strategy).and_return(instance)
32
+ expect(runner.run(strategy)).to eq(instance)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe ActionFactory do
4
+ it "has a version number" do
5
+ expect(ActionFactory::VERSION).to eq "0.1.1"
6
+ end
7
+
8
+ describe ".configuration" do
9
+ subject { described_class.configuration }
10
+
11
+ it { is_expected.to be_a(ActionFactory::Configuration) }
12
+ end
13
+
14
+ describe ".configure" do
15
+ subject(:configure) { described_class.configure { |config| config.persist_method = :save } }
16
+
17
+ it "configures the gem" do
18
+ expect { configure }.to change { described_class.configuration.persist_method }.from(:save!).to(:save)
19
+ end
20
+ end
21
+
22
+ describe ActionFactory::Configuration do
23
+ subject(:configuration) { described_class.new }
24
+
25
+ describe "#persist_method" do
26
+ subject { configuration.persist_method }
27
+
28
+ it { is_expected.to eq :save! }
29
+ end
30
+
31
+ describe "#initialize_method" do
32
+ subject { configuration.initialize_method }
33
+
34
+ it { is_expected.to eq :new }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,97 @@
1
+ ENV["RAILS_ENV"] ||= "test"
2
+
3
+ require "action_factory"
4
+ # This file was generated by the `rails generate rspec:install` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
7
+ # this file to always be loaded, without a need to explicitly require it in any
8
+ # files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need
16
+ # it.
17
+ #
18
+ # See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.expect_with :rspec do |expectations|
24
+ # This option will default to `true` in RSpec 4. It makes the `description`
25
+ # and `failure_message` of custom matchers include text for helper methods
26
+ # defined using `chain`, e.g.:
27
+ # be_bigger_than(2).and_smaller_than(4).description
28
+ # # => "be bigger than 2 and smaller than 4"
29
+ # ...rather than:
30
+ # # => "be bigger than 2"
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ end
33
+
34
+ # rspec-mocks config goes here. You can use an alternate test double
35
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
36
+ config.mock_with :rspec do |mocks|
37
+ # Prevents you from mocking or stubbing a method that does not exist on
38
+ # a real object. This is generally recommended, and will default to
39
+ # `true` in RSpec 4.
40
+ mocks.verify_partial_doubles = true
41
+ end
42
+
43
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
44
+ # have no way to turn it off -- the option exists only for backwards
45
+ # compatibility in RSpec 3). It causes shared context metadata to be
46
+ # inherited by the metadata hash of host groups and examples, rather than
47
+ # triggering implicit auto-inclusion in groups with matching metadata.
48
+ config.shared_context_metadata_behavior = :apply_to_host_groups
49
+
50
+ # The settings below are suggested to provide a good initial experience
51
+ # with RSpec, but feel free to customize to your heart's content.
52
+ =begin
53
+ # This allows you to limit a spec run to individual examples or groups
54
+ # you care about by tagging them with `:focus` metadata. When nothing
55
+ # is tagged with `:focus`, all examples get run. RSpec also provides
56
+ # aliases for `it`, `describe`, and `context` that include `:focus`
57
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
58
+ config.filter_run_when_matching :focus
59
+
60
+ # Allows RSpec to persist some state between runs in order to support
61
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
62
+ # you configure your source control system to ignore this file.
63
+ config.example_status_persistence_file_path = "spec/examples.txt"
64
+
65
+ # Limits the available syntax to the non-monkey patched syntax that is
66
+ # recommended. For more details, see:
67
+ # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
68
+ config.disable_monkey_patching!
69
+
70
+ # Many RSpec users commonly either run the entire suite or an individual
71
+ # file, and it's useful to allow more verbose output when running an
72
+ # individual spec file.
73
+ if config.files_to_run.one?
74
+ # Use the documentation formatter for detailed output,
75
+ # unless a formatter has already been configured
76
+ # (e.g. via a command-line flag).
77
+ config.default_formatter = "doc"
78
+ end
79
+
80
+ # Print the 10 slowest examples and example groups at the
81
+ # end of the spec run, to help surface which specs are running
82
+ # particularly slow.
83
+ config.profile_examples = 10
84
+
85
+ # Run specs in random order to surface order dependencies. If you find an
86
+ # order dependency and want to debug it, you can fix the order by providing
87
+ # the seed, which is printed after each run.
88
+ # --seed 1234
89
+ config.order = :random
90
+
91
+ # Seed global randomization in this process using the `--seed` CLI option.
92
+ # Setting this allows you to use `--seed` to deterministically reproduce
93
+ # test failures related to randomization by passing the same `--seed` value
94
+ # as the one that triggered the failure.
95
+ Kernel.srand config.seed
96
+ =end
97
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: action_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Loyola
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 7.0.6
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '7.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 7.0.6
33
+ - !ruby/object:Gem::Dependency
34
+ name: activemodel
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '7.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 7.0.6
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '7.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 7.0.6
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.12'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '3.12'
67
+ - !ruby/object:Gem::Dependency
68
+ name: debug
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.8'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.8'
81
+ description: Your factories are now classes.
82
+ email:
83
+ - berna.loyola@gmail.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - README.md
89
+ - Rakefile
90
+ - lib/action_factory.rb
91
+ - lib/action_factory/active_record.rb
92
+ - lib/action_factory/assignment_compiler.rb
93
+ - lib/action_factory/assignments.rb
94
+ - lib/action_factory/assignments/attribute.rb
95
+ - lib/action_factory/assignments/sequence.rb
96
+ - lib/action_factory/assignments/trait.rb
97
+ - lib/action_factory/attribute_assigner.rb
98
+ - lib/action_factory/base.rb
99
+ - lib/action_factory/factory_finder.rb
100
+ - lib/action_factory/helpers.rb
101
+ - lib/action_factory/registry.rb
102
+ - lib/action_factory/runner.rb
103
+ - lib/action_factory/version.rb
104
+ - spec/action_factory/assignment_compiler_spec.rb
105
+ - spec/action_factory/attribute_assigner_spec.rb
106
+ - spec/action_factory/factory_finder_spec.rb
107
+ - spec/action_factory/registry_spec.rb
108
+ - spec/action_factory/runner_spec.rb
109
+ - spec/action_factory_spec.rb
110
+ - spec/spec_helper.rb
111
+ homepage: https://github.com/b-loyola/action_factory
112
+ licenses:
113
+ - MIT
114
+ metadata:
115
+ allowed_push_host: https://rubygems.org
116
+ homepage_uri: https://github.com/b-loyola/action_factory
117
+ source_code_uri: https://github.com/b-loyola/action_factory
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 3.2.2
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.4.10
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: A Simple OOO Factory lib for Ruby (and Rails)
137
+ test_files:
138
+ - spec/action_factory/assignment_compiler_spec.rb
139
+ - spec/action_factory/attribute_assigner_spec.rb
140
+ - spec/action_factory/factory_finder_spec.rb
141
+ - spec/action_factory/registry_spec.rb
142
+ - spec/action_factory/runner_spec.rb
143
+ - spec/action_factory_spec.rb
144
+ - spec/spec_helper.rb