micromachine 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 707ffde016887ae675ddd25388e8ca9376cb1547
4
- data.tar.gz: 301bcfd9f251f538dbc5b170660e022f1aa6089c
3
+ metadata.gz: 695548d56ffdf4666ad19b2fb55af4a647f2f364
4
+ data.tar.gz: 4331c9df0cd25f86ccdadbfe6070fcfbd31a2d21
5
5
  SHA512:
6
- metadata.gz: 2f2c63e4af76fe25a6aa7ecf16d3731f9513745a8fe74fb626961340edb63be2f5ded471194d0334b0c2f0581e7151e961ef98ad858c9b9e43ad37c54e2fc549
7
- data.tar.gz: 8acbe242c04c4f96b6e981a8ef15275dbf6fdb5297dbb6120d7d55d0432ebe9e2f1a91f2f4bb5b6485bd71bde66ccc2b85b5db03d301e8bab5bc3586e2ffa290
6
+ metadata.gz: b98dae4b90be60013ad87c90db67d6c232fcc5632d038d47e691c85efb6ac5f63296f06dd94725988c36adb1715470484b5c42d87ce54c4f5bebbc3755822015
7
+ data.tar.gz: b7ed4f8bf6f5a2d62589e4acb964f0f5fec4b4a773cda49cbcc367bfacb077656fa3ec4504919218a3a5df55c6ad24296503f26504609139b342f370c6ee33d0
data/.gems ADDED
@@ -0,0 +1 @@
1
+ cutest -v 1.2.2
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Michel Martens
1
+ Copyright (c) 2009-2015 Michel Martens
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -62,6 +62,14 @@ machine.trigger?(:reset) #=> true
62
62
  machine.state #=> :ignored
63
63
  ```
64
64
 
65
+ If you want to force an Exception when trying to trigger a event from a
66
+ non compatible state use the `trigger!` method:
67
+
68
+ ``` ruby
69
+ machine.trigger?(:ignore) #=> false
70
+ machine.trigger!(:ignore) #=> MicroMachine::InvalidState raised
71
+ ```
72
+
65
73
  It can also have callbacks when entering some state:
66
74
 
67
75
  ``` ruby
@@ -0,0 +1,23 @@
1
+ require 'micromachine'
2
+
3
+ # This example can be run with ruby -I lib/ example/advanced.rb
4
+
5
+ fsm = MicroMachine.new(:pending)
6
+
7
+ fsm.when(:confirm, :pending => :confirmed)
8
+ fsm.when(:ignore, :pending => :ignored)
9
+ fsm.when(:reset, :confirmed => :pending, :ignored => :pending)
10
+
11
+ puts "Should print Confirmed, Pending and Ignored:"
12
+
13
+ fsm.on(:any) do
14
+ puts fsm.state.capitalize
15
+ end
16
+
17
+ fsm.trigger(:confirm)
18
+
19
+ fsm.trigger(:ignore)
20
+
21
+ fsm.trigger(:reset)
22
+
23
+ fsm.trigger(:ignore)
data/examples/basic.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'micromachine'
2
+
3
+ # This example can be run with ruby -I lib/ example/basic.rb
4
+
5
+ fsm = MicroMachine.new(:pending)
6
+
7
+ fsm.when(:confirm, :pending => :confirmed)
8
+ fsm.when(:ignore, :pending => :ignored)
9
+ fsm.when(:reset, :confirmed => :pending, :ignored => :pending)
10
+
11
+ puts "Should print Confirmed, Reset and Ignored:"
12
+
13
+ if fsm.trigger(:confirm)
14
+ puts "Confirmed"
15
+ end
16
+
17
+ if fsm.trigger(:ignore)
18
+ puts "Ignored"
19
+ end
20
+
21
+ if fsm.trigger(:reset)
22
+ puts "Reset"
23
+ end
24
+
25
+ if fsm.trigger(:ignore)
26
+ puts "Ignored"
27
+ end
@@ -0,0 +1,31 @@
1
+ require 'micromachine'
2
+
3
+ # This example can be run with ruby -I lib/ example/callbacks.rb
4
+
5
+ fsm = MicroMachine.new(:pending)
6
+
7
+ fsm.when(:confirm, :pending => :confirmed)
8
+ fsm.when(:ignore, :pending => :ignored)
9
+ fsm.when(:reset, :confirmed => :pending, :ignored => :pending)
10
+
11
+ puts "Should print Confirmed, Reset and Ignored:"
12
+
13
+ fsm.on(:confirmed) do
14
+ puts "Confirmed"
15
+ end
16
+
17
+ fsm.on(:ignored) do
18
+ puts "Ignored"
19
+ end
20
+
21
+ fsm.on(:pending) do
22
+ puts "Reset"
23
+ end
24
+
25
+ fsm.trigger(:confirm)
26
+
27
+ fsm.trigger(:ignore)
28
+
29
+ fsm.trigger(:reset)
30
+
31
+ fsm.trigger(:ignore)
data/lib/micromachine.rb CHANGED
@@ -1,16 +1,17 @@
1
1
  class MicroMachine
2
2
  InvalidEvent = Class.new(NoMethodError)
3
+ InvalidState = Class.new(ArgumentError)
3
4
 
4
5
  attr :transitions_for
5
6
  attr :state
6
7
 
7
- def initialize initial_state
8
+ def initialize(initial_state)
8
9
  @state = initial_state
9
10
  @transitions_for = Hash.new
10
11
  @callbacks = Hash.new { |hash, key| hash[key] = [] }
11
12
  end
12
13
 
13
- def on key, &block
14
+ def on(key, &block)
14
15
  @callbacks[key] << block
15
16
  end
16
17
 
@@ -18,17 +19,25 @@ class MicroMachine
18
19
  transitions_for[event] = transitions
19
20
  end
20
21
 
21
- def trigger event
22
+ def trigger(event)
22
23
  if trigger?(event)
23
24
  @state = transitions_for[event][@state]
24
25
  callbacks = @callbacks[@state] + @callbacks[:any]
25
- callbacks.each { |callback| callback.call }
26
+ callbacks.each { |callback| callback.call(event) }
26
27
  true
27
28
  else
28
29
  false
29
30
  end
30
31
  end
31
32
 
33
+ def trigger!(event)
34
+ if trigger(event)
35
+ true
36
+ else
37
+ raise InvalidState.new("Event '#{event}' not valid from state '#{@state}'")
38
+ end
39
+ end
40
+
32
41
  def trigger?(event)
33
42
  raise InvalidEvent unless transitions_for.has_key?(event)
34
43
  transitions_for[event][state] ? true : false
data/makefile ADDED
@@ -0,0 +1,5 @@
1
+ .DEFAULT_GOAL := test
2
+ .PHONY: test
3
+
4
+ test:
5
+ cutest ./test/*.rb
data/micromachine.gemspec CHANGED
@@ -1,11 +1,14 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = 'micromachine'
3
- s.version = '1.1.0'
2
+ s.name = "micromachine"
3
+ s.version = "1.2.0"
4
4
  s.summary = %{Minimal Finite State Machine.}
5
5
  s.description = %Q{There are many finite state machine implementations for Ruby, and they all provide a nice DSL for declaring events, exceptions, callbacks, and all kinds of niceties in general.\n\nBut if all you want is a finite state machine, look no further: this has less than 50 lines of code and provides everything a finite state machine must have, and nothing more.}
6
- s.author = "Michel Martens"
7
- s.email = "michel@soveran.com"
6
+ s.author = ["Michel Martens"]
7
+ s.email = ["michel@soveran.com"]
8
8
  s.homepage = "http://github.com/soveran/micromachine"
9
- s.files = Dir["lib/**/*.rb", "README*", "LICENSE", "Rakefile", "*.gemspec", "example/**/*.*"]
10
- s.add_development_dependency 'contest'
9
+ s.license = "MIT"
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_development_dependency "cutest"
11
14
  end
data/test/callbacks.rb ADDED
@@ -0,0 +1,44 @@
1
+ require_relative "helper"
2
+
3
+ setup do
4
+ machine = MicroMachine.new(:pending)
5
+ machine.when(:confirm, pending: :confirmed)
6
+ machine.when(:reset, confirmed: :pending)
7
+
8
+ machine.on(:pending) { @state = "Pending" }
9
+ machine.on(:confirmed) { @state = "Confirmed" }
10
+ machine.on(:any) { @current = @state }
11
+
12
+ machine
13
+ end
14
+
15
+ test "executes callbacks when entering a state" do |machine|
16
+ machine.trigger(:confirm)
17
+ assert_equal "Confirmed", @state
18
+
19
+ machine.trigger(:reset)
20
+ assert_equal "Pending", @state
21
+ end
22
+
23
+ test "executes the callback on any transition" do |machine|
24
+ machine.trigger(:confirm)
25
+ assert_equal "Confirmed", @current
26
+
27
+ machine.trigger(:reset)
28
+ assert_equal "Pending", @current
29
+ end
30
+
31
+ test "passing the event name to the callbacks" do
32
+ event_name = nil
33
+
34
+ machine = MicroMachine.new(:pending)
35
+ machine.when(:confirm, pending: :confirmed)
36
+
37
+ machine.on(:confirmed) do |event|
38
+ event_name = event
39
+ end
40
+
41
+ machine.trigger(:confirm)
42
+
43
+ assert_equal(:confirm, event_name)
44
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "cutest"
2
+ require_relative "../lib/micromachine"
@@ -0,0 +1,27 @@
1
+ require_relative "helper"
2
+
3
+ setup do
4
+ machine = MicroMachine.new(:pending)
5
+
6
+ machine.when(:confirm, pending: :confirmed)
7
+ machine.when(:ignore, pending: :ignored)
8
+ machine.when(:reset, confirmed: :pending, ignored: :pending)
9
+
10
+ machine
11
+ end
12
+
13
+ test "returns an array with the defined events" do |machine|
14
+ assert_equal [:confirm, :ignore, :reset], machine.events
15
+ end
16
+
17
+ test "returns an array with the defined states" do |machine|
18
+ assert_equal [:pending, :confirmed, :ignored], machine.states
19
+ end
20
+
21
+ test "returns false if compared state is not equal to current" do |machine|
22
+ assert !(machine == :confirmed)
23
+ end
24
+
25
+ test "returns true if compared state is equal to current" do |machine|
26
+ assert machine == :pending
27
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "helper"
2
+
3
+ setup do
4
+ machine = MicroMachine.new(:pending)
5
+
6
+ machine.when(:confirm, pending: :confirmed)
7
+ machine.when(:ignore, pending: :ignored)
8
+ machine.when(:reset, confirmed: :pending, ignored: :pending)
9
+
10
+ machine
11
+ end
12
+
13
+ test "defines initial state" do |machine|
14
+ assert_equal :pending, machine.state
15
+ end
16
+
17
+ test "raises an error if an invalid event is triggered" do |machine|
18
+ assert_raise(MicroMachine::InvalidEvent) do
19
+ machine.trigger(:random_event)
20
+ end
21
+ end
22
+
23
+ test "preserves the state if transition is not possible" do |machine|
24
+ assert !machine.trigger?(:reset)
25
+ assert !machine.trigger(:reset)
26
+ assert_equal :pending, machine.state
27
+ end
28
+
29
+ test "changes the state if transition is possible" do |machine|
30
+ assert machine.trigger?(:confirm)
31
+ assert machine.trigger(:confirm)
32
+ assert_equal :confirmed, machine.state
33
+ end
34
+
35
+ test "discerns multiple transitions" do |machine|
36
+ machine.trigger(:confirm)
37
+ assert_equal :confirmed, machine.state
38
+
39
+ machine.trigger(:reset)
40
+ assert_equal :pending, machine.state
41
+
42
+ machine.trigger(:ignore)
43
+ assert_equal :ignored, machine.state
44
+
45
+ machine.trigger(:reset)
46
+ assert_equal :pending, machine.state
47
+ end
48
+
49
+ test "raises an error if event is triggered from/to a non complatible state" do |machine|
50
+ assert_raise(MicroMachine::InvalidState) do
51
+ machine.trigger!(:reset)
52
+ end
53
+ end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: micromachine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Martens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-08 00:00:00.000000000 Z
11
+ date: 2015-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: contest
14
+ name: cutest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '>='
@@ -28,18 +28,28 @@ description: |-
28
28
  There are many finite state machine implementations for Ruby, and they all provide a nice DSL for declaring events, exceptions, callbacks, and all kinds of niceties in general.
29
29
 
30
30
  But if all you want is a finite state machine, look no further: this has less than 50 lines of code and provides everything a finite state machine must have, and nothing more.
31
- email: michel@soveran.com
31
+ email:
32
+ - michel@soveran.com
32
33
  executables: []
33
34
  extensions: []
34
35
  extra_rdoc_files: []
35
36
  files:
36
- - lib/micromachine.rb
37
- - README.md
37
+ - .gems
38
38
  - LICENSE
39
- - Rakefile
39
+ - README.md
40
+ - examples/advanced.rb
41
+ - examples/basic.rb
42
+ - examples/callbacks.rb
43
+ - lib/micromachine.rb
44
+ - makefile
40
45
  - micromachine.gemspec
46
+ - test/callbacks.rb
47
+ - test/helper.rb
48
+ - test/introspection.rb
49
+ - test/transitions.rb
41
50
  homepage: http://github.com/soveran/micromachine
42
- licenses: []
51
+ licenses:
52
+ - MIT
43
53
  metadata: {}
44
54
  post_install_message:
45
55
  rdoc_options: []
@@ -57,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
67
  version: '0'
58
68
  requirements: []
59
69
  rubyforge_project:
60
- rubygems_version: 2.0.3
70
+ rubygems_version: 2.0.14
61
71
  signing_key:
62
72
  specification_version: 4
63
73
  summary: Minimal Finite State Machine.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- task :default => :test
4
-
5
- Rake::TestTask.new(:test) do |t|
6
- t.pattern = 'test/**/*_test.rb'
7
- t.verbose = false
8
- end