statesman 3.5.0 → 7.4.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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +49 -250
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +26 -6
- data/CHANGELOG.md +106 -0
- data/Gemfile +10 -4
- data/Guardfile +2 -0
- data/README.md +78 -48
- data/Rakefile +2 -4
- data/lib/generators/statesman/active_record_transition_generator.rb +2 -0
- data/lib/generators/statesman/generator_helpers.rb +2 -0
- data/lib/generators/statesman/migration_generator.rb +2 -0
- data/lib/statesman.rb +14 -4
- data/lib/statesman/adapters/active_record.rb +259 -37
- data/lib/statesman/adapters/active_record_queries.rb +100 -36
- data/lib/statesman/adapters/active_record_transition.rb +2 -0
- data/lib/statesman/adapters/memory.rb +2 -0
- data/lib/statesman/adapters/memory_transition.rb +2 -0
- data/lib/statesman/callback.rb +2 -0
- data/lib/statesman/config.rb +28 -0
- data/lib/statesman/exceptions.rb +34 -2
- data/lib/statesman/guard.rb +3 -4
- data/lib/statesman/machine.rb +29 -7
- data/lib/statesman/railtie.rb +2 -0
- data/lib/statesman/utils.rb +2 -0
- data/lib/statesman/version.rb +3 -1
- data/lib/tasks/statesman.rake +3 -1
- data/spec/fixtures/add_constraints_to_most_recent_for_bacon_transitions_with_partial_index.rb +2 -0
- data/spec/fixtures/add_constraints_to_most_recent_for_bacon_transitions_without_partial_index.rb +2 -0
- data/spec/fixtures/add_most_recent_to_bacon_transitions.rb +2 -0
- data/spec/generators/statesman/active_record_transition_generator_spec.rb +2 -0
- data/spec/generators/statesman/migration_generator_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -30
- data/spec/statesman/adapters/active_record_queries_spec.rb +167 -91
- data/spec/statesman/adapters/active_record_spec.rb +15 -1
- data/spec/statesman/adapters/active_record_transition_spec.rb +2 -0
- data/spec/statesman/adapters/memory_spec.rb +2 -0
- data/spec/statesman/adapters/memory_transition_spec.rb +2 -0
- data/spec/statesman/adapters/shared_examples.rb +2 -0
- data/spec/statesman/callback_spec.rb +2 -0
- data/spec/statesman/config_spec.rb +2 -0
- data/spec/statesman/exceptions_spec.rb +88 -0
- data/spec/statesman/guard_spec.rb +2 -0
- data/spec/statesman/machine_spec.rb +79 -4
- data/spec/statesman/utils_spec.rb +2 -0
- data/spec/support/active_record.rb +9 -12
- data/spec/support/generators_shared_examples.rb +2 -0
- data/statesman.gemspec +19 -7
- metadata +40 -32
- data/lib/generators/statesman/mongoid_transition_generator.rb +0 -25
- data/lib/generators/statesman/templates/mongoid_transition_model.rb.erb +0 -14
- data/lib/statesman/adapters/mongoid.rb +0 -66
- data/lib/statesman/adapters/mongoid_transition.rb +0 -10
- data/spec/generators/statesman/mongoid_transition_generator_spec.rb +0 -23
- data/spec/statesman/adapters/mongoid_spec.rb +0 -86
- data/spec/support/mongoid.rb +0 -28
@@ -1,25 +0,0 @@
|
|
1
|
-
require "rails/generators"
|
2
|
-
require "generators/statesman/generator_helpers"
|
3
|
-
|
4
|
-
module Statesman
|
5
|
-
class MongoidTransitionGenerator < Rails::Generators::Base
|
6
|
-
include Statesman::GeneratorHelpers
|
7
|
-
|
8
|
-
desc "Create a Mongoid-based transition model with the required attributes"
|
9
|
-
|
10
|
-
argument :parent, type: :string, desc: "Your parent model name"
|
11
|
-
argument :klass, type: :string, desc: "Your transition model name"
|
12
|
-
|
13
|
-
source_root File.expand_path("templates", __dir__)
|
14
|
-
|
15
|
-
def create_model_file
|
16
|
-
template("mongoid_transition_model.rb.erb", model_file_name)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def collection_name
|
22
|
-
klass.underscore.pluralize
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
class <%= klass %>
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps
|
4
|
-
|
5
|
-
field :to_state, type: String
|
6
|
-
field :sort_key, type: Integer
|
7
|
-
field :statesman_metadata, type: Hash
|
8
|
-
|
9
|
-
include Statesman::Adapters::MongoidTransition
|
10
|
-
|
11
|
-
index({ sort_key: 1 })
|
12
|
-
|
13
|
-
belongs_to :<%= parent %><%= class_name_option %>, index: true
|
14
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require_relative "../exceptions"
|
2
|
-
|
3
|
-
module Statesman
|
4
|
-
module Adapters
|
5
|
-
class Mongoid
|
6
|
-
attr_reader :transition_class
|
7
|
-
attr_reader :parent_model
|
8
|
-
|
9
|
-
def initialize(transition_class, parent_model, observer, _opts = {})
|
10
|
-
@transition_class = transition_class
|
11
|
-
@parent_model = parent_model
|
12
|
-
@observer = observer
|
13
|
-
unless transition_class_hash_fields.include?("statesman_metadata")
|
14
|
-
raise UnserializedMetadataError, metadata_field_error_message
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def create(from, to, metadata = {})
|
19
|
-
from = from.to_s
|
20
|
-
to = to.to_s
|
21
|
-
transition = transitions_for_parent.build(to_state: to,
|
22
|
-
sort_key: next_sort_key,
|
23
|
-
statesman_metadata: metadata)
|
24
|
-
|
25
|
-
@observer.execute(:before, from, to, transition)
|
26
|
-
transition.save!
|
27
|
-
@last_transition = transition
|
28
|
-
@observer.execute(:after, from, to, transition)
|
29
|
-
@observer.execute(:after_commit, from, to, transition)
|
30
|
-
transition
|
31
|
-
ensure
|
32
|
-
@last_transition = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
def history(*)
|
36
|
-
transitions_for_parent.asc(:sort_key)
|
37
|
-
end
|
38
|
-
|
39
|
-
def last(force_reload: false)
|
40
|
-
if force_reload
|
41
|
-
@last_transition = history.last
|
42
|
-
else
|
43
|
-
@last_transition ||= history.last
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def transition_class_hash_fields
|
50
|
-
transition_class.fields.select { |_, v| v.type == Hash }.keys
|
51
|
-
end
|
52
|
-
|
53
|
-
def metadata_field_error_message
|
54
|
-
"#{transition_class.name}#statesman_metadata is not of type 'Hash'"
|
55
|
-
end
|
56
|
-
|
57
|
-
def transitions_for_parent
|
58
|
-
@parent_model.send(@transition_class.collection_name)
|
59
|
-
end
|
60
|
-
|
61
|
-
def next_sort_key
|
62
|
-
(last && last.sort_key + 10) || 10
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "support/generators_shared_examples"
|
3
|
-
require "generators/statesman/mongoid_transition_generator"
|
4
|
-
|
5
|
-
describe Statesman::MongoidTransitionGenerator, type: :generator do
|
6
|
-
describe "the model contains the correct words" do
|
7
|
-
subject { file("app/models/yummy/bacon_transition.rb") }
|
8
|
-
|
9
|
-
before { run_generator %w[Yummy::Bacon Yummy::BaconTransition] }
|
10
|
-
|
11
|
-
it { is_expected.to_not contain(%r{:yummy/bacon}) }
|
12
|
-
it { is_expected.to contain(/class_name: 'Yummy::Bacon'/) }
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "the model contains the correct words" do
|
16
|
-
subject { file("app/models/bacon_transition.rb") }
|
17
|
-
|
18
|
-
before { run_generator %w[Bacon BaconTransition] }
|
19
|
-
|
20
|
-
it { is_expected.to_not contain(/class_name:/) }
|
21
|
-
it { is_expected.to_not contain(/CreateYummy::Bacon/) }
|
22
|
-
end
|
23
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "statesman/adapters/shared_examples"
|
3
|
-
require "statesman/exceptions"
|
4
|
-
require "support/mongoid"
|
5
|
-
require "mongoid"
|
6
|
-
|
7
|
-
describe Statesman::Adapters::Mongoid, mongo: true do
|
8
|
-
after { Mongoid.purge! }
|
9
|
-
|
10
|
-
let(:observer) { double(Statesman::Machine, execute: nil) }
|
11
|
-
let(:model) { MyMongoidModel.create(current_state: :pending) }
|
12
|
-
|
13
|
-
it_behaves_like "an adapter", described_class, MyMongoidModelTransition
|
14
|
-
|
15
|
-
describe "#initialize" do
|
16
|
-
context "with unserialized metadata" do
|
17
|
-
before do
|
18
|
-
allow_any_instance_of(described_class).
|
19
|
-
to receive_messages(transition_class_hash_fields: [])
|
20
|
-
end
|
21
|
-
|
22
|
-
it "raises an exception if metadata is not serialized" do
|
23
|
-
expect do
|
24
|
-
described_class.new(MyMongoidModelTransition, MyMongoidModel,
|
25
|
-
observer)
|
26
|
-
end.to raise_exception(Statesman::UnserializedMetadataError)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "#last" do
|
32
|
-
let(:adapter) do
|
33
|
-
described_class.new(MyMongoidModelTransition, model, observer)
|
34
|
-
end
|
35
|
-
|
36
|
-
context "with a previously looked up transition" do
|
37
|
-
before { adapter.create(:x, :y) }
|
38
|
-
|
39
|
-
before { adapter.last }
|
40
|
-
|
41
|
-
it "caches the transition" do
|
42
|
-
expect_any_instance_of(MyMongoidModel).
|
43
|
-
to_not receive(:my_mongoid_model_transitions)
|
44
|
-
adapter.last
|
45
|
-
end
|
46
|
-
|
47
|
-
context "and a new transition" do
|
48
|
-
before { adapter.create(:y, :z) }
|
49
|
-
|
50
|
-
it "retrieves the new transition from the database" do
|
51
|
-
expect(adapter.last.to_state).to eq("z")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when a new transition has been created elsewhere" do
|
57
|
-
let(:alternate_adapter) do
|
58
|
-
described_class.new(MyMongoidModelTransition, model, observer)
|
59
|
-
end
|
60
|
-
|
61
|
-
context "when explicitly not using the cache" do
|
62
|
-
context "when the transitions are in memory" do
|
63
|
-
before do
|
64
|
-
model.my_mongoid_model_transitions.entries
|
65
|
-
alternate_adapter.create(:y, :z)
|
66
|
-
end
|
67
|
-
|
68
|
-
it "reloads the value" do
|
69
|
-
expect(adapter.last(force_reload: true).to_state).to eq("z")
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context "when the transitions are not in memory" do
|
74
|
-
before do
|
75
|
-
model.my_mongoid_model_transitions.reset
|
76
|
-
alternate_adapter.create(:y, :z)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "reloads the value" do
|
80
|
-
expect(adapter.last(force_reload: true).to_state).to eq("z")
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/spec/support/mongoid.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require "mongoid"
|
2
|
-
|
3
|
-
Mongoid.configure do |config|
|
4
|
-
config.connect_to("statesman_test")
|
5
|
-
end
|
6
|
-
|
7
|
-
class MyMongoidModel
|
8
|
-
include Mongoid::Document
|
9
|
-
|
10
|
-
field :current_state, type: String
|
11
|
-
|
12
|
-
has_many :my_mongoid_model_transitions
|
13
|
-
end
|
14
|
-
|
15
|
-
class MyMongoidModelTransition
|
16
|
-
include Mongoid::Document
|
17
|
-
include Mongoid::Timestamps
|
18
|
-
|
19
|
-
field :to_state, type: String
|
20
|
-
field :sort_key, type: Integer
|
21
|
-
field :statesman_metadata, type: Hash
|
22
|
-
|
23
|
-
index(sort_key: 1)
|
24
|
-
|
25
|
-
belongs_to :my_mongoid_model, index: true
|
26
|
-
|
27
|
-
include Statesman::Adapters::MongoidTransition
|
28
|
-
end
|