support RSpec match transition_from

This commit is contained in:
Thorsten Böttger 2015-10-30 23:47:13 +13:00
parent 2377cbfd8a
commit 9e9f3d0a76
6 changed files with 76 additions and 20 deletions

View File

@ -1,5 +1,9 @@
# CHANGELOG
## 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))
## 4.4.1
* add support for rejecting certain events on inspection (see [issue #272](https://github.com/aasm/aasm/issues/272) for details, thanks to [@dubroe](https://github.com/dubroe))

View File

@ -723,28 +723,21 @@ Job.aasm.states_for_select
### Testing
AASM provides matchers for [RSpec](http://rspec.info).
AASM provides some matchers for [RSpec](http://rspec.info). Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this
job = Job.new
job.should have_state :sleeping
job.should allow_transition_to :running
job.should allow_event :run
job.should allow_event :run!
job.should_not allow_event :clean
job.should_not allow_event :clean!
simple = SimpleMultipleExample.new
simple.should have_state :standing, :on => :move
simple.should allow_transition_to :walking, :on => :move
simple.should allow_event :run
simple.should allow_event :run!
simple.should have_state :sleeping, :on => :work
simple.should allow_transition_to :processing, :on => :work
simple.should allow_event :start
simple.should allow_event :start!
simple.should_not allow_event :stop
simple.should_not allow_event :stop!
```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)
# 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 transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
```
## <a id="installation">Installation ##

5
lib/aasm/rspec.rb Normal file
View File

@ -0,0 +1,5 @@
# relative-require all rspec files
Dir[File.dirname(__FILE__) + '/rspec/*.rb'].each do |file|
require 'aasm/rspec/' + File.basename(file, File.extname(file))
end

View File

@ -0,0 +1,32 @@
RSpec::Matchers.define :transition_from do |from_state|
match do |obj|
@state_machine_name ||= :default
obj.aasm(@state_machine_name).current_state = from_state.to_sym
# expect(obj).to receive(:broadcast_event).with(@event.to_s, obj, from_state, @to_state)
obj.send(@event) && obj.aasm(@state_machine_name).current_state == @to_state.to_sym
end
chain :on do |state_machine_name|
@state_machine_name = state_machine_name
end
chain :to do |state|
@to_state = state
end
chain :on_event do |event|
@event = event
end
description do
"transition state to :#{@to_state} from :#{expected} on event :#{@event} (on :#{@state_machine_name})"
end
failure_message do |obj|
"expected that :#{obj.aasm(@state_machine_name).current_state} would be :#{@to_state} (on :#{@state_machine_name})"
end
failure_message_when_negated do |obj|
"expected that :#{obj.aasm(@state_machine_name).current_state} would not be :#{@to_state} (on :#{@state_machine_name})"
end
end

View File

@ -2,6 +2,7 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
require 'aasm'
require 'rspec'
require 'aasm/rspec'
# require 'ruby-debug'; Debugger.settings[:autoeval] = true; debugger; rubys_debugger = 'annoying'
# require 'ruby-debug/completion'

View File

@ -0,0 +1,21 @@
require 'spec_helper'
describe 'state machine' do
let(:simple) { SimpleExample.new }
let(:multiple) { SimpleMultipleExample.new }
describe 'transition_from' do
it "works for simple state machines" do
expect(simple).to transition_from(:initialised).to(:filled_out).on_event(:fill_out)
expect(simple).to_not transition_from(:initialised).to(:authorised).on_event(:fill_out)
end
it "works for multiple state machines" do
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 transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
end
end
end