micromachine 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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