statesmin 1.0.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 +7 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +48 -0
- data/.travis.yml +15 -0
- data/CONTRIBUTING.md +28 -0
- data/Gemfile +3 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +556 -0
- data/Rakefile +6 -0
- data/lib/statesmin.rb +8 -0
- data/lib/statesmin/callback.rb +52 -0
- data/lib/statesmin/exceptions.rb +21 -0
- data/lib/statesmin/guard.rb +13 -0
- data/lib/statesmin/machine.rb +276 -0
- data/lib/statesmin/railtie.rb +5 -0
- data/lib/statesmin/transition_helper.rb +41 -0
- data/lib/statesmin/version.rb +3 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/statesmin/callback_spec.rb +120 -0
- data/spec/statesmin/guard_spec.rb +22 -0
- data/spec/statesmin/machine_spec.rb +704 -0
- data/spec/statesmin/transition_helper_spec.rb +170 -0
- data/statesmin.gemspec +26 -0
- metadata +142 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Statesmin::TransitionHelper do
|
4
|
+
let(:transition_class) { Class.new { include Statesmin::TransitionHelper } }
|
5
|
+
let(:state_machine) do
|
6
|
+
Class.new do
|
7
|
+
include Statesmin::Machine
|
8
|
+
state :x, initial: true
|
9
|
+
state :y
|
10
|
+
transition from: :x, to: :y
|
11
|
+
end.new(Object.new)
|
12
|
+
end
|
13
|
+
let(:instance) do
|
14
|
+
transition_class.new.tap do |instance|
|
15
|
+
allow(instance).to receive(:state_machine).and_return(state_machine)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'delegated methods' do
|
20
|
+
context 'when no state_machine method is defined' do
|
21
|
+
let(:unimplemented_instance) { transition_class.new }
|
22
|
+
|
23
|
+
Statesmin::TransitionHelper::DELEGATED_METHODS.each do |method|
|
24
|
+
describe "##{method}" do
|
25
|
+
it 'raises a NotImplementedError' do
|
26
|
+
expect { unimplemented_instance.send(method) }.
|
27
|
+
to raise_error(Statesmin::NotImplementedError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when a state_machine method is defined' do
|
34
|
+
Statesmin::TransitionHelper::DELEGATED_METHODS.each do |method|
|
35
|
+
describe "##{method}" do
|
36
|
+
it 'calls that method on the state_machine' do
|
37
|
+
needs_arg = state_machine.method(method).arity == 0
|
38
|
+
expect(state_machine).to receive(method)
|
39
|
+
needs_arg ? instance.send(method) : instance.send(method, :y)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
shared_examples 'a transition method' do |method|
|
47
|
+
context 'when no transition method is defined' do
|
48
|
+
it 'raises a NotImplementedError' do
|
49
|
+
expect { instance.send(method, :y) }.
|
50
|
+
to raise_error(Statesmin::NotImplementedError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when a transition method is defined' do
|
55
|
+
before do
|
56
|
+
instance.define_singleton_method :transition, -> (_state, _) { nil }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when the next_state argument is a valid transition' do
|
60
|
+
it 'calls the transition method' do
|
61
|
+
expect(instance).to receive(:transition)
|
62
|
+
instance.send(method, :y)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'updates the current_state of the state_machine' do
|
66
|
+
instance.send(method, :y)
|
67
|
+
expect(state_machine.current_state).to eq('y')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns the value of the transition method' do
|
71
|
+
allow(instance).to receive(:transition).and_return(42)
|
72
|
+
expect(instance.send(method, :y)).to eq(42)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#transition_to!' do
|
79
|
+
it_behaves_like 'a transition method', :transition_to!
|
80
|
+
|
81
|
+
context 'when a valid transition method is defined' do
|
82
|
+
before do
|
83
|
+
instance.define_singleton_method :transition, -> (_state, _) { nil }
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'and the next_state argument is not a valid transition' do
|
87
|
+
it 'raises a TransitionFailedError' do
|
88
|
+
expect { instance.transition_to!(:z) }.
|
89
|
+
to raise_error(Statesmin::TransitionFailedError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'does not call the transition method' do
|
93
|
+
expect(instance).to_not receive(:transition)
|
94
|
+
expect { instance.transition_to!(:z) }.to raise_error
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'does not update the current_state of the state_machine' do
|
98
|
+
expect { instance.transition_to!(:z) }.to raise_error
|
99
|
+
expect(state_machine.current_state).to eq('x')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when a error raising transition method is defined' do
|
105
|
+
before do
|
106
|
+
instance.define_singleton_method :transition, -> (_state, _) { raise }
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'and the next_state argument is a valid' do
|
110
|
+
it 'raises a RuntimeError' do
|
111
|
+
expect { instance.transition_to!(:y) }.to raise_error(RuntimeError)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#transition_to' do
|
118
|
+
it_behaves_like 'a transition method', :transition_to
|
119
|
+
|
120
|
+
context 'when a valid transition method is defined' do
|
121
|
+
before do
|
122
|
+
instance.define_singleton_method :transition, -> (_state, _) { nil }
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'and the next_state argument is not a valid transition' do
|
126
|
+
it 'returns false' do
|
127
|
+
expect(instance.transition_to(:z)).to eq(false)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'does not call the transition method' do
|
131
|
+
expect(instance).to_not receive(:transition)
|
132
|
+
instance.transition_to(:z)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'does not update the current_state of the state_machine' do
|
136
|
+
instance.transition_to(:z)
|
137
|
+
expect(state_machine.current_state).to eq('x')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when a transition method raises a RuntimeError' do
|
143
|
+
before do
|
144
|
+
instance.define_singleton_method :transition do |_state, _|
|
145
|
+
raise RuntimeError
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'and the next_state argument is a valid' do
|
150
|
+
it 'raises a RuntimeError' do
|
151
|
+
expect { instance.transition_to(:y) }.to raise_error(RuntimeError)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when a transition method raises a TransitionFailedError' do
|
157
|
+
before do
|
158
|
+
instance.define_singleton_method :transition do |_state, _|
|
159
|
+
raise Statesmin::TransitionFailedError
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'and the next_state argument is a valid' do
|
164
|
+
it 'returns false' do
|
165
|
+
expect(instance.transition_to(:y)).to eq(false)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
data/statesmin.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'statesmin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "statesmin"
|
8
|
+
spec.version = Statesmin::VERSION
|
9
|
+
spec.authors = ["Chris Ewald"]
|
10
|
+
spec.email = ["chrisewald@gmail.com"]
|
11
|
+
spec.description = %q{A minimal statesmanlike state machine library}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = "https://github.com/mkcode/statesmin"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
24
|
+
spec.add_development_dependency "rspec-its", "~> 1.1"
|
25
|
+
spec.add_development_dependency "rubocop", "~> 0.30.0"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: statesmin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Ewald
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-its
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.30.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.30.0
|
83
|
+
description: A minimal statesmanlike state machine library
|
84
|
+
email:
|
85
|
+
- chrisewald@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rubocop.yml"
|
92
|
+
- ".travis.yml"
|
93
|
+
- CONTRIBUTING.md
|
94
|
+
- Gemfile
|
95
|
+
- Guardfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- lib/statesmin.rb
|
100
|
+
- lib/statesmin/callback.rb
|
101
|
+
- lib/statesmin/exceptions.rb
|
102
|
+
- lib/statesmin/guard.rb
|
103
|
+
- lib/statesmin/machine.rb
|
104
|
+
- lib/statesmin/railtie.rb
|
105
|
+
- lib/statesmin/transition_helper.rb
|
106
|
+
- lib/statesmin/version.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/statesmin/callback_spec.rb
|
109
|
+
- spec/statesmin/guard_spec.rb
|
110
|
+
- spec/statesmin/machine_spec.rb
|
111
|
+
- spec/statesmin/transition_helper_spec.rb
|
112
|
+
- statesmin.gemspec
|
113
|
+
homepage: https://github.com/mkcode/statesmin
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.4.5.1
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: A minimal statesmanlike state machine library
|
137
|
+
test_files:
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/statesmin/callback_spec.rb
|
140
|
+
- spec/statesmin/guard_spec.rb
|
141
|
+
- spec/statesmin/machine_spec.rb
|
142
|
+
- spec/statesmin/transition_helper_spec.rb
|