statesman-events 0.0.1
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 +12 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +3 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +6 -0
- data/lib/statesman/event_transitions.rb +32 -0
- data/lib/statesman/events.rb +51 -0
- data/lib/statesman/events/version.rb +5 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/statesman/events_spec.rb +167 -0
- data/statesman-events.gemspec +26 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c7a41793f54b53f461686fbe163233c2d268e7d
|
4
|
+
data.tar.gz: 17c393eb70b31a656c7777cbc3d34362cd7d717b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dcb60ad78a61130a3628f3030ea67a193692705747f721b013aeb5b0685ba7aa20d6901e4523cf3680d1aa2af9c383d2dcfe0ab61befd50b0a7a4cd7188f6175
|
7
|
+
data.tar.gz: c636be370afa76f3871c1f8da47a0863af25a6042c8b444729d8be787891f2ef0bb2673ba3128df275c9ca9bd8b469e703e3c65b4e6e4086b5bb680653810038
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# For all options see https://github.com/bbatsov/rubocop/tree/master/config
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
Include:
|
5
|
+
- Rakefile
|
6
|
+
- statesman.gemfile
|
7
|
+
- lib/tasks/*.rake
|
8
|
+
Exclude:
|
9
|
+
- vendor/**/*
|
10
|
+
- .*/**
|
11
|
+
- spec/fixtures/**/*
|
12
|
+
|
13
|
+
StringLiterals:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Documentation:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
SignalException:
|
20
|
+
EnforcedStyle: only_raise
|
21
|
+
|
22
|
+
# Avoid methods longer than 15 lines of code
|
23
|
+
MethodLength:
|
24
|
+
CountComments: false
|
25
|
+
Max: 15
|
26
|
+
|
27
|
+
AbcSize:
|
28
|
+
Max: 25
|
29
|
+
|
30
|
+
# Don't require utf-8 encoding comment
|
31
|
+
Encoding:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
LineLength:
|
35
|
+
Max: 80
|
36
|
+
|
37
|
+
GuardClause:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
SingleSpaceBeforeFirstArg:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
DotPosition:
|
44
|
+
EnforcedStyle: trailing
|
45
|
+
|
46
|
+
# Allow class and message or instance raises
|
47
|
+
Style/RaiseArgs:
|
48
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, all_on_start: true, cmd: 'bundle exec rspec --color' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
9
|
+
|
10
|
+
guard :rubocop, all_on_start: true, cli: ['--format', 'clang'] do
|
11
|
+
watch(%r{.+\.rb$})
|
12
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
13
|
+
watch(%r{(?:.+/)?\rubocop-todo\.yml$}) { |m| File.dirname(m[0]) }
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Grey Baker
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
Event support for [Statesman](https://github.com/gocardless/statesman).
|
2
|
+
|
3
|
+
## TL;DR Usage
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
class TaskStateMachine
|
7
|
+
include Statesman::Machine
|
8
|
+
include Statesman::Events
|
9
|
+
|
10
|
+
state :unstarted, initial: true
|
11
|
+
state :started
|
12
|
+
state :finished
|
13
|
+
state :cancelled
|
14
|
+
|
15
|
+
event :start do
|
16
|
+
transition from: :unstarted, to: :started
|
17
|
+
end
|
18
|
+
|
19
|
+
event :finish do
|
20
|
+
transition from: :started, to: :finished
|
21
|
+
end
|
22
|
+
|
23
|
+
event :cancel do
|
24
|
+
transition from: :unstarted, to: :cancelled
|
25
|
+
transition from: :started, to: :cancelled
|
26
|
+
end
|
27
|
+
|
28
|
+
event :restart do
|
29
|
+
transition from: :finished, to: :started
|
30
|
+
transition from: :cancelled, to: :started
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Task < ActiveRecord::Base
|
35
|
+
delegate :current_state, :trigger, :available_events, to: :state_machine
|
36
|
+
|
37
|
+
def state_machine
|
38
|
+
@state_machine ||= TaskStateMachine.new(self)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task = Task.new
|
43
|
+
|
44
|
+
task.current_state # => "unstarted"
|
45
|
+
task.trigger(:start) # => true/false
|
46
|
+
task.current_state # => "started"
|
47
|
+
task.available_events # => [:finish, :cancel]
|
48
|
+
```
|
49
|
+
|
50
|
+
## Class methods
|
51
|
+
|
52
|
+
#### `Events.event`
|
53
|
+
```ruby
|
54
|
+
ExampleMachine.event(:some_event) do
|
55
|
+
transition from: :some_state, to: :another_state
|
56
|
+
transition from: :some_other_state, to: :yet_another_state
|
57
|
+
end
|
58
|
+
```
|
59
|
+
Define an event rule. When triggered, the first available transition from the
|
60
|
+
current state will be called.
|
61
|
+
|
62
|
+
## Instance methods
|
63
|
+
|
64
|
+
#### `Event#trigger`
|
65
|
+
```ruby
|
66
|
+
instance.trigger(:some_event)
|
67
|
+
```
|
68
|
+
Triggers the passed event, returning `true` on success. Returns false on
|
69
|
+
failure.
|
70
|
+
|
71
|
+
#### `Event#trigger!`
|
72
|
+
```ruby
|
73
|
+
instance.trigger(:some_event)
|
74
|
+
```
|
75
|
+
Triggers the passed event, returning `true` on success. Raises
|
76
|
+
`Statesman::GuardFailedError` or `Statesman::TransitionFailedError` on failure.
|
77
|
+
|
78
|
+
#### `Event#available_events`
|
79
|
+
```ruby
|
80
|
+
instance.available_events
|
81
|
+
```
|
82
|
+
Returns an array of events you can `trigger` from the current state.
|
83
|
+
|
84
|
+
---
|
85
|
+
|
86
|
+
GoCardless ♥ open source. If you do too, come [join us](https://gocardless.com/jobs#software-engineer).
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Statesman
|
2
|
+
class EventTransitions
|
3
|
+
attr_reader :machine, :event_name
|
4
|
+
|
5
|
+
def initialize(machine, event_name, &block)
|
6
|
+
@machine = machine
|
7
|
+
@event_name = event_name
|
8
|
+
instance_eval(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def transition(from: nil, to: nil)
|
12
|
+
from = to_s_or_nil(from)
|
13
|
+
to = array_to_s_or_nil(to)
|
14
|
+
|
15
|
+
machine.transition(from: from, to: to)
|
16
|
+
|
17
|
+
machine.events[event_name] ||= {}
|
18
|
+
machine.events[event_name][from] ||= []
|
19
|
+
machine.events[event_name][from] += to
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def to_s_or_nil(input)
|
25
|
+
input.nil? ? input : input.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def array_to_s_or_nil(input)
|
29
|
+
Array(input).map { |item| to_s_or_nil(item) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative "event_transitions"
|
2
|
+
|
3
|
+
# Adds support for events when `extend`ed into state machine classes
|
4
|
+
module Statesman
|
5
|
+
module Events
|
6
|
+
def self.included(base)
|
7
|
+
unless base.respond_to?(:states)
|
8
|
+
raise "Statesman::Events included before/without Statesman::Machine"
|
9
|
+
end
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def events
|
15
|
+
@events ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def event(name, &block)
|
19
|
+
EventTransitions.new(self, name, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def trigger!(event_name, metadata = {})
|
24
|
+
transitions = self.class.events.fetch(event_name) do
|
25
|
+
raise Statesman::TransitionFailedError,
|
26
|
+
"Event #{event_name} not found"
|
27
|
+
end
|
28
|
+
|
29
|
+
new_state = transitions.fetch(current_state) do
|
30
|
+
raise Statesman::TransitionFailedError,
|
31
|
+
"State #{current_state} not found for Event #{event_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
transition_to!(new_state.first, metadata)
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def trigger(event_name, metadata = {})
|
39
|
+
self.trigger!(event_name, metadata)
|
40
|
+
rescue Statesman::TransitionFailedError, Statesman::GuardFailedError
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
def available_events
|
45
|
+
state = current_state
|
46
|
+
self.class.events.select do |_, transitions|
|
47
|
+
transitions.key?(state)
|
48
|
+
end.map(&:first)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Statesman::Events do
|
4
|
+
let(:machine) do
|
5
|
+
Class.new do
|
6
|
+
include Statesman::Machine
|
7
|
+
include Statesman::Events
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:my_model) { Class.new { attr_accessor :current_state }.new }
|
11
|
+
|
12
|
+
describe "inclusion" do
|
13
|
+
context "after Statesman::Machine" do
|
14
|
+
let(:machine) do
|
15
|
+
Class.new do
|
16
|
+
include Statesman::Machine
|
17
|
+
include Statesman::Events
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
specify { expect { machine.events }.to_not raise_error }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "without Statesman::Machine" do
|
25
|
+
let(:machine) { Class.new { include Statesman::Events } }
|
26
|
+
|
27
|
+
it "raises a descriptive error" do
|
28
|
+
expect { machine.events }.to raise_error(/without Statesman::Machine/)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "before Statesman::Machine" do
|
33
|
+
let(:machine) do
|
34
|
+
Class.new do
|
35
|
+
include Statesman::Events
|
36
|
+
include Statesman::Machine
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises a descriptive error" do
|
41
|
+
expect { machine.events }.to raise_error(/without Statesman::Machine/)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#event" do
|
47
|
+
before do
|
48
|
+
machine.class_eval do
|
49
|
+
state :x, initial: true
|
50
|
+
state :y
|
51
|
+
state :z
|
52
|
+
|
53
|
+
event :event_1 do
|
54
|
+
transition from: :x, to: :y
|
55
|
+
end
|
56
|
+
|
57
|
+
event :event_2 do
|
58
|
+
transition from: :y, to: :z
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:instance) { machine.new(my_model) }
|
64
|
+
|
65
|
+
context "when the state cannot be transitioned to" do
|
66
|
+
it "raises an error" do
|
67
|
+
expect { instance.trigger!(:event_2) }.
|
68
|
+
to raise_error(Statesman::TransitionFailedError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when the state can be transitioned to" do
|
73
|
+
it "changes state" do
|
74
|
+
instance.trigger!(:event_1)
|
75
|
+
expect(instance.current_state).to eq("y")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "creates a new transition object" do
|
79
|
+
expect { instance.trigger!(:event_1) }.
|
80
|
+
to change(instance.history, :count).by(1)
|
81
|
+
|
82
|
+
expect(instance.history.first).
|
83
|
+
to be_a(Statesman::Adapters::MemoryTransition)
|
84
|
+
expect(instance.history.first.to_state).to eq("y")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "sends metadata to the transition object" do
|
88
|
+
meta = { "my" => "hash" }
|
89
|
+
instance.trigger!(:event_1, meta)
|
90
|
+
expect(instance.history.first.metadata).to eq(meta)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "sets an empty hash as the metadata if not specified" do
|
94
|
+
instance.trigger!(:event_1)
|
95
|
+
expect(instance.history.first.metadata).to eq({})
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns true" do
|
99
|
+
expect(instance.trigger!(:event_1)).to eq(true)
|
100
|
+
end
|
101
|
+
|
102
|
+
context "with a guard" do
|
103
|
+
let(:result) { true }
|
104
|
+
# rubocop:disable UnusedBlockArgument
|
105
|
+
let(:guard_cb) { ->(*args) { result } }
|
106
|
+
# rubocop:enable UnusedBlockArgument
|
107
|
+
before { machine.guard_transition(from: :x, to: :y, &guard_cb) }
|
108
|
+
|
109
|
+
context "and an object to act on" do
|
110
|
+
let(:instance) { machine.new(my_model) }
|
111
|
+
|
112
|
+
it "passes the object to the guard" do
|
113
|
+
expect(guard_cb).to receive(:call).once.
|
114
|
+
with(my_model, instance.last_transition, {}).and_return(true)
|
115
|
+
instance.trigger!(:event_1)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "which passes" do
|
120
|
+
it "changes state" do
|
121
|
+
expect { instance.trigger!(:event_1) }.
|
122
|
+
to change { instance.current_state }.to("y")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "which fails" do
|
127
|
+
let(:result) { false }
|
128
|
+
|
129
|
+
it "raises an exception" do
|
130
|
+
expect { instance.trigger!(:event_1) }.
|
131
|
+
to raise_error(Statesman::GuardFailedError)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#available_events" do
|
139
|
+
before do
|
140
|
+
machine.class_eval do
|
141
|
+
state :x, initial: true
|
142
|
+
state :y
|
143
|
+
state :z
|
144
|
+
|
145
|
+
event :event_1 do
|
146
|
+
transition from: :x, to: :y
|
147
|
+
end
|
148
|
+
|
149
|
+
event :event_2 do
|
150
|
+
transition from: :y, to: :z
|
151
|
+
end
|
152
|
+
|
153
|
+
event :event_3 do
|
154
|
+
transition from: :x, to: :y
|
155
|
+
transition from: :y, to: :x
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
let(:instance) { machine.new(my_model) }
|
161
|
+
it "should return list of available events for the current state" do
|
162
|
+
expect(instance.available_events).to eq([:event_1, :event_3])
|
163
|
+
instance.trigger!(:event_1)
|
164
|
+
expect(instance.available_events).to eq([:event_2, :event_3])
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'statesman/events/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "statesman-events"
|
7
|
+
spec.version = Statesman::Events::VERSION
|
8
|
+
spec.authors = ["Grey Baker"]
|
9
|
+
spec.email = ["developers@gocardless.com"]
|
10
|
+
spec.description = %q{Event support for Statesman}
|
11
|
+
spec.summary = spec.description
|
12
|
+
spec.homepage = "https://github.com/gocardless/statesman-events"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "statesman", ">= 1.3"
|
21
|
+
|
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,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: statesman-events
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Grey Baker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: statesman
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
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: Event support for Statesman
|
84
|
+
email:
|
85
|
+
- developers@gocardless.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .rubocop.yml
|
92
|
+
- .travis.yml
|
93
|
+
- CHANGELOG.md
|
94
|
+
- Gemfile
|
95
|
+
- Guardfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- lib/statesman/event_transitions.rb
|
100
|
+
- lib/statesman/events.rb
|
101
|
+
- lib/statesman/events/version.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/statesman/events_spec.rb
|
104
|
+
- statesman-events.gemspec
|
105
|
+
homepage: https://github.com/gocardless/statesman-events
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.2.2
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Event support for Statesman
|
129
|
+
test_files:
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
- spec/statesman/events_spec.rb
|