action_factory 0.1.1

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.
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