diff --git a/lib/statesman/machine.rb b/lib/statesman/machine.rb index 153059a6..ab3053eb 100644 --- a/lib/statesman/machine.rb +++ b/lib/statesman/machine.rb @@ -233,12 +233,20 @@ def array_to_s_or_nil(input) def initialize(object, options = { transition_class: Statesman::Adapters::MemoryTransition, + initial_transition: false, }) @object = object @transition_class = options[:transition_class] @storage_adapter = adapter_class(@transition_class).new( @transition_class, object, self, options ) + + if options[:initial_transition] + if history.empty? && self.class.initial_state + @storage_adapter.create(nil, self.class.initial_state) + end + end + send(:after_initialize) if respond_to? :after_initialize end diff --git a/spec/statesman/machine_spec.rb b/spec/statesman/machine_spec.rb index b8527ffa..aefb516a 100644 --- a/spec/statesman/machine_spec.rb +++ b/spec/statesman/machine_spec.rb @@ -478,12 +478,83 @@ it_behaves_like "a callback store", :after_guard_failure, :after_guard_failure end + shared_examples "initial transition is not created" do + it "doesn't call .create on storage adapter" do + expect_any_instance_of(Statesman.storage_adapter).to_not receive(:create) + machine.new(my_model, options) + end + end + + shared_examples "initial transition is created" do + it "calls .create on storage adapter" do + expect_any_instance_of(Statesman.storage_adapter).to receive(:create).with(nil, "x") + machine.new(my_model, options) + end + + it "creates a new transition object" do + instance = machine.new(my_model, options) + + expect(instance.history.count).to eq(1) + expect(instance.history.first.to_state).to eq("x") + end + end + describe "#initialize" do it "accepts an object to manipulate" do machine_instance = machine.new(my_model) expect(machine_instance.object).to be(my_model) end + context "initial_transition is not provided" do + let(:options) { {} } + + it_behaves_like "initial transition is not created" + end + + context "initial_transition is provided" do + context "initial_transition is true" do + let(:options) do + { initial_transition: true, + transition_class: Statesman::Adapters::MemoryTransition } + end + + context "history is empty" do + context "initial state is defined" do + before { machine.state(:x, initial: true) } + + it_behaves_like "initial transition is created" + end + + context "initial state is not defined" do + it_behaves_like "initial transition is not created" + end + end + + context "history is not empty" do + before do + allow_any_instance_of(Statesman.storage_adapter).to receive(:history). + and_return([{}]) + end + + context "initial state is defined" do + before { machine.state(:x, initial: true) } + + it_behaves_like "initial transition is not created" + end + + context "initial state is not defined" do + it_behaves_like "initial transition is not created" + end + end + end + + context "initial_transition is false" do + let(:options) { { initial_transition: false } } + + it_behaves_like "initial transition is not created" + end + end + context "transition class" do it "sets a default" do expect(Statesman.storage_adapter).to receive(:new).once.