diff --git a/CHANGELOG.md b/CHANGELOG.md index a776238..0ec099c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## unreleased - * add RSpec matcher `transition_from` (see [issue #178](https://github.com/aasm/aasm/issues/178) for details, thanks to [@thomasstephane](https://github.com/thomasstephane)) + * add RSpec matcher `have_state` (see [issue #147](https://github.com/aasm/aasm/issues/147) for details) + * add RSpec matcher `transition_from` (see [issue #178](https://github.com/aasm/aasm/issues/178) for details, thanks to [@thomasstephane](https://github.com/thomasstephane)) ## 4.4.1 diff --git a/README.md b/README.md index 2f9f13a..233b282 100644 --- a/README.md +++ b/README.md @@ -723,20 +723,26 @@ Job.aasm.states_for_select ### Testing -AASM provides some matchers for [RSpec](http://rspec.info). Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this +AASM provides some matchers for [RSpec](http://rspec.info): `transition_from`, `have_state`. Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this ```ruby # classes with only the default state machine job = Job.new expect(job).to transition_from(:sleeping).to(:running).on_event(:run) expect(job).not_to transition_from(:sleeping).to(:cleaning).on_event(:run) +expect(job).to have_state(:sleeping) +expect(job).not_to have_state(:running) # classes with multiple state machine multiple = SimpleMultipleExample.new expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move) expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move) +expect(multiple).to have_state(:standing).on(:move) +expect(multiple).not_to have_state(:walking).on(:move) expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work) expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work) +expect(multiple).to have_state(:sleeping).on(:work) +expect(multiple).not_to have_state(:processing).on(:work) ``` ## Installation ## diff --git a/lib/aasm/rspec/have_state.rb b/lib/aasm/rspec/have_state.rb new file mode 100644 index 0000000..bba9c73 --- /dev/null +++ b/lib/aasm/rspec/have_state.rb @@ -0,0 +1,22 @@ +RSpec::Matchers.define :have_state do |state| + match do |obj| + @state_machine_name ||= :default + obj.aasm(@state_machine_name).current_state == state.to_sym + end + + chain :on do |state_machine_name| + @state_machine_name = state_machine_name + end + + description do + "have state #{expected} (on :#{@state_machine_name})" + end + + failure_message do |obj| + "expected that :#{obj.aasm(@state_machine_name).current_state} would be :#{expected} (on :#{@state_machine_name})" + end + + failure_message_when_negated do |obj| + "expected that :#{obj.aasm(@state_machine_name).current_state} would not be :#{expected} (on :#{@state_machine_name})" + end +end diff --git a/spec/unit/rspec_matcher_spec.rb b/spec/unit/rspec_matcher_spec.rb index 3ac3e3e..4170d41 100644 --- a/spec/unit/rspec_matcher_spec.rb +++ b/spec/unit/rspec_matcher_spec.rb @@ -18,4 +18,26 @@ describe 'state machine' do expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work) end end + + describe "have_state" do + it "works for simple state machines" do + expect(simple).to have_state :initialised + expect(simple).to_not have_state :filled_out + simple.fill_out + expect(simple).to have_state :filled_out + end + + it "works for multiple state machines" do + expect(multiple).to have_state(:standing).on(:move) + expect(multiple).to_not have_state(:walking).on(:move) + multiple.walk + expect(multiple).to have_state(:walking).on(:move) + + expect(multiple).to have_state(:sleeping).on(:work) + expect(multiple).to_not have_state(:processing).on(:work) + multiple.start + expect(multiple).to have_state(:processing).on(:work) + end + end + end