simple_states 1.0.2 → 1.1.0.pre

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: af301cceac699e1a5316adefc530a637427e231f
4
- data.tar.gz: 6c332396fce2c5c567d0a80d2983997cec2e3c5a
3
+ metadata.gz: 441bc5305dd74b7fcf14cd4cd9c65bdfdf1b2a57
4
+ data.tar.gz: 398464da79ae54350d267a57cfc42a1bfd567fbb
5
5
  SHA512:
6
- metadata.gz: 6c86dc1eedb47699e3376f0197d2685b3e114ae5cd256352c3ed90b884d90280d2946b9ff0e0b9c11e4e11f5ecf215d9241d2229d1e2837065785f4aba0d1a19
7
- data.tar.gz: d6e6a16d345cc618996421dc56930f91b0826351826788924d860df2ba340a283f166e4dc1cae4e97688747a2e3b9447659716ae46d22fb833228ad2b10954df
6
+ metadata.gz: 79e01af136e6dc890c3cc94ea9971d78f34fd8ba4332a3afb6a62a333a956b835cc87c463d9ae1065f47961403ccd14964448e50a3dd79a88846175a02887d7a
7
+ data.tar.gz: 87d6031b6fd68f2e6c8c010fadf7d9130af544661e2ecb3df9eb6051cfa1c26a9f675fca4589b6737e21138f6935c070d470bb5fa9b7fe62163ea9ffcf8235c2
data/Gemfile CHANGED
@@ -2,13 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- # group :test do
6
- # platforms :mri_18 do
7
- # gem "require_relative", "~> 1.0.1"
8
- # gem 'ruby-debug'
9
- # end
10
- #
11
- # platforms :mri_19 do
12
- # gem 'ruby-debug19', :platforms => :mri_19 unless RUBY_VERSION == '1.9.3'
13
- # end
14
- # end
5
+ group :test do
6
+ gem 'minitest'
7
+ end
@@ -1,41 +1,41 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple_states (1.0.2)
4
+ simple_states (1.0.1)
5
5
  activesupport
6
+ hashr (~> 0.0.10)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
- activesupport (5.0.2)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ activesupport (4.2.4)
12
12
  i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
13
14
  minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
14
16
  tzinfo (~> 1.1)
15
- concurrent-ruby (1.0.5)
16
- i18n (0.8.1)
17
- metaclass (0.0.4)
18
- minitest (5.10.1)
19
- mocha (1.2.1)
17
+ hashr (0.0.22)
18
+ i18n (0.7.0)
19
+ json (1.8.3)
20
+ json (1.8.3-java)
21
+ metaclass (0.0.1)
22
+ minitest (5.8.0)
23
+ mocha (0.14.0)
20
24
  metaclass (~> 0.0.1)
21
- power_assert (1.0.1)
22
25
  rake (0.9.6)
23
- test-unit (3.2.3)
24
- power_assert
25
26
  test_declarative (0.0.5)
26
- thread_safe (0.3.6)
27
+ thread_safe (0.3.5)
28
+ thread_safe (0.3.5-java)
27
29
  tzinfo (1.2.2)
28
30
  thread_safe (~> 0.1)
29
31
 
30
32
  PLATFORMS
33
+ java
31
34
  ruby
32
35
 
33
36
  DEPENDENCIES
37
+ minitest
34
38
  mocha
35
39
  rake (~> 0.9.2)
36
40
  simple_states!
37
- test-unit
38
41
  test_declarative
39
-
40
- BUNDLED WITH
41
- 1.14.5
@@ -6,21 +6,28 @@ module SimpleStates
6
6
  autoload :Event, 'simple_states/event'
7
7
  autoload :States, 'simple_states/states'
8
8
 
9
- def self.included(base)
10
- base.extend SimpleStates::ClassMethods
11
- # Add class level attribute accessors
12
- added_class_accessors = [ :state_names, :initial_state, :events ]
13
- base.singleton_class.send :attr_accessor, *added_class_accessors
14
- base.public_class_method *added_class_accessors
15
- base.public_class_method *added_class_accessors.map{|att| "#{att}=".to_sym }
16
- # default states
17
- base.after_initialize :init_state if base.respond_to?(:after_initialize)
18
- base.initial_state = :created
19
- base.events = []
9
+ class << self
10
+ def included(base)
11
+ base.extend(SimpleStates::ClassMethods)
12
+ define_accessors(base, :state_names, :state_options, :initial_state, :events)
13
+ set_defaults(base)
14
+ end
15
+
16
+ def define_accessors(base, *names)
17
+ base.singleton_class.send(:attr_accessor, *names)
18
+ base.public_class_method(*names + names.map { |name| "#{name}=".to_sym })
19
+ end
20
+
21
+ def set_defaults(base)
22
+ base.after_initialize(:init_state) if base.respond_to?(:after_initialize)
23
+ base.initial_state = :created
24
+ base.state_names = []
25
+ base.state_options = {}
26
+ base.events = []
27
+ end
20
28
  end
21
29
 
22
30
  module ClassMethods
23
-
24
31
  def new(*)
25
32
  super.tap { |object| States.init(object) }
26
33
  end
@@ -30,23 +37,24 @@ module SimpleStates
30
37
  end
31
38
 
32
39
  def states(*args)
33
- if args.empty?
34
- self.state_names ||= add_states(self.initial_state)
35
- else
36
- options = args.last.is_a?(Hash) ? args.pop : {}
37
- self.initial_state = options[:initial].to_sym if options.key?(:initial)
38
- add_states(*[self.initial_state].concat(args))
39
- end
40
+ options = args.last.is_a?(Hash) ? args.pop : {}
41
+ self.initial_state = options.delete(:initial).to_sym if options.key?(:initial)
42
+ self.state_options = options
43
+ add_states(*[self.initial_state].concat(args))
40
44
  end
41
45
 
42
- def add_states(*states)
43
- self.state_names = (self.state_names || []).concat(states.compact.map(&:to_sym)).uniq
46
+ def add_states(*names)
47
+ self.state_names = self.state_names.concat(names.compact.map(&:to_sym)).uniq
44
48
  end
45
49
 
46
50
  def event(name, options = {})
47
51
  add_states(options[:to], *options[:from])
48
52
  self.events += [Event.new(name, options)]
49
53
  end
54
+
55
+ def states_module
56
+ const_defined?(*args) ? self::StatesProxy : const_set(:StatesProxy, Module.new)
57
+ end
50
58
  end
51
59
 
52
60
  attr_reader :past_states
@@ -66,13 +74,4 @@ module SimpleStates
66
74
  def was_state?(state)
67
75
  past_states.concat([self.state.try(:to_sym)]).compact.include?(state.to_sym)
68
76
  end
69
-
70
- def respond_to?(method, include_private = false)
71
- method.to_s =~ /(was_|^)(#{self.class.states.join('|')})\?$/ && self.class.state_names.include?($2.to_sym) || super
72
- end
73
-
74
- def method_missing(method, *args, &block)
75
- method.to_s =~ /(was_|^)(#{self.class.states.join('|')})\?$/ ? send(:"#{$1}state?", $2, *args) : super
76
- end
77
77
  end
78
-
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/module/delegation'
2
+ require 'hashr'
2
3
 
3
4
  module SimpleStates
4
5
  class Event
@@ -6,7 +7,11 @@ module SimpleStates
6
7
 
7
8
  def initialize(name, options = {})
8
9
  @name = name
9
- @options = options
10
+ @options = Hashr.new(options) do
11
+ def except
12
+ self[:except]
13
+ end
14
+ end
10
15
  end
11
16
 
12
17
  def saving
@@ -40,29 +45,35 @@ module SimpleStates
40
45
 
41
46
  def skip?(object, args)
42
47
  result = false
43
- result ||= !send_methods(object, options[:if], args) if options.key?(:if)
44
- result ||= send_methods(object, options[:unless], args) if options.key?(:unless)
48
+ result ||= !send_methods(object, options.if, args) if options.if?
49
+ result ||= send_methods(object, options.unless, args) if options.unless?
45
50
  result
46
51
  end
47
52
 
48
53
  def can_transition?(object)
49
- !options[:from] || object.state && Array(options[:from]).include?(object.state.to_sym)
54
+ !options.from || object.state && Array(options.from).include?(object.state.to_sym)
50
55
  end
51
56
 
52
57
  def run_callbacks(object, type, args)
53
58
  object.save! if @saving
54
- send_methods(object, options[type.to_sym], args)
59
+ send_methods(object, options.send(type), args)
55
60
  end
56
61
 
57
62
  def set_state(object)
58
63
  state = target_state
59
64
  object.past_states << object.state if object.state
60
- object.state = state.to_sym
65
+ object.state = state.to_sym if set_state?(object, state)
61
66
  object.send(:"#{state}_at=", now) if object.respond_to?(:"#{state}_at=") && object.respond_to?(:"#{state}_at") && object.send(:"#{state}_at").nil?
62
67
  end
63
68
 
69
+ def set_state?(object, state)
70
+ return true unless object.class.state_options[:ordered]
71
+ states = object.class.state_names
72
+ states.index(object.state.try(:to_sym)) < states.index(state)
73
+ end
74
+
64
75
  def target_state
65
- options[:to] || :"#{name}ed"
76
+ options.to || :"#{name}ed"
66
77
  end
67
78
 
68
79
  def send_methods(object, methods, args)
@@ -84,7 +95,7 @@ module SimpleStates
84
95
  end
85
96
 
86
97
  def known_target_state?(object)
87
- object.state && object.class.states.include?(object.state.to_sym)
98
+ object.state && object.class.state_names.include?(object.state.to_sym)
88
99
  end
89
100
 
90
101
  def raise_invalid_transition(object)
@@ -2,46 +2,55 @@ module SimpleStates
2
2
  class States < Module
3
3
  class << self
4
4
  def init(object)
5
- object.singleton_class.send(:include, proxy_for(object.class))
5
+ object.class.state_names = [object.class.initial_state] if object.class.state_names.empty?
6
+ respond_to?(:prepend) ? prepend_module(object.class) : include_module(object)
6
7
  object.init_state unless object.singleton_class.respond_to?(:after_initialize)
7
8
  end
8
9
 
9
- def proxy_for(klass)
10
- args = [:StatesProxy].concat(klass.method(:const_defined?).arity != 1 ? [false] : [])
11
- klass.const_defined?(*args) ? klass::StatesProxy : klass.const_set(:StatesProxy, new(klass.events))
10
+ def prepend_module(const)
11
+ const.prepend(module_for(const)) unless const.const_defined?(:StatesProxy)
12
12
  end
13
- end
14
-
15
- attr_reader :events
16
13
 
17
- def initialize(events)
18
- @events = merge_events(events)
19
- setup
20
- end
14
+ def include_module(object)
15
+ object.singleton_class.send(:include, module_for(object.class))
16
+ end
21
17
 
22
- protected
18
+ def module_for(const)
19
+ args = [:StatesProxy].concat(const.method(:const_defined?).arity != 1 ? [false] : [])
20
+ const.const_defined?(*args) ? const::StatesProxy : const.const_set(:StatesProxy, create_module(const))
21
+ end
23
22
 
24
- def setup
25
- events.each do |event|
26
- define_event(event)
23
+ def create_module(const)
24
+ new.tap do |mod|
25
+ merge_events(const.events).each { |event| define_event(mod, event) }
26
+ const.state_names.each { |name| define_state(mod, name) }
27
27
  end
28
28
  end
29
29
 
30
-
31
- def define_event(event)
32
- define_method(event.name) do |*args|
30
+ def define_event(const, event)
31
+ const.send(:define_method, event.name) do |*args|
33
32
  event.send(:call, self, *args) do
34
- super(*args) if self.class.method_defined?(event.name)
33
+ super(*args) if defined?(super)
35
34
  end
36
35
  end
37
36
 
38
- define_method(:"#{event.name}!") do |*args|
37
+ const.send(:define_method, :"#{event.name}!") do |*args|
39
38
  event.saving do
40
39
  send(event.name, *args)
41
40
  end
42
41
  end
43
42
  end
44
43
 
44
+ def define_state(const, state)
45
+ const.send(:define_method, :"#{state}?") do |*args|
46
+ defined?(super) ? super() : state?(state, *args)
47
+ end
48
+
49
+ const.send(:define_method, :"was_#{state}?") do |*args|
50
+ defined?(super) ? super() : was_state?(state, *args)
51
+ end
52
+ end
53
+
45
54
  def merge_events(events)
46
55
  if merge_ix = events.index { |event| event.name == :all }
47
56
  merge = events.slice!(merge_ix)
@@ -53,5 +62,6 @@ module SimpleStates
53
62
  events
54
63
  end
55
64
  end
65
+ end
56
66
  end
57
67
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleStates
2
- VERSION = '1.0.2'
2
+ VERSION = '1.1.0.pre'
3
3
  end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'simple_states/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "simple_states"
8
+ s.version = SimpleStates::VERSION
9
+ s.authors = ["Sven Fuchs"]
10
+ s.email = "svenfuchs@artweb-design.de"
11
+ s.homepage = "https://github.com/svenfuchs/simple_states"
12
+ s.summary = "[summary]"
13
+ s.description = "[description]"
14
+
15
+ s.files = Dir.glob("{lib/**/*,[A-Z]*}")
16
+ s.platform = Gem::Platform::RUBY
17
+ s.require_path = 'lib'
18
+ s.rubyforge_project = '[none]'
19
+
20
+ s.add_dependency 'activesupport'
21
+ s.add_dependency 'hashr', '~> 0.0.10'
22
+
23
+ s.add_development_dependency 'rake', '~> 0.9.2'
24
+ s.add_development_dependency 'test_declarative'
25
+ s.add_development_dependency 'mocha'
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_states
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-02 00:00:00.000000000 Z
11
+ date: 2015-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: hashr
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.2
34
- type: :development
33
+ version: 0.0.10
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.9.2
40
+ version: 0.0.10
41
41
  - !ruby/object:Gem::Dependency
42
- name: test-unit
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.9.2
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.9.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: test_declarative
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -96,6 +96,7 @@ files:
96
96
  - lib/simple_states/event.rb
97
97
  - lib/simple_states/states.rb
98
98
  - lib/simple_states/version.rb
99
+ - simple_states.gemspec
99
100
  homepage: https://github.com/svenfuchs/simple_states
100
101
  licenses: []
101
102
  metadata: {}
@@ -110,13 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
111
  version: '0'
111
112
  required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  requirements:
113
- - - ">="
114
+ - - ">"
114
115
  - !ruby/object:Gem::Version
115
- version: '0'
116
+ version: 1.3.1
116
117
  requirements: []
117
118
  rubyforge_project: "[none]"
118
- rubygems_version: 2.5.2
119
+ rubygems_version: 2.4.5
119
120
  signing_key:
120
121
  specification_version: 4
121
122
  summary: "[summary]"
122
123
  test_files: []
124
+ has_rdoc: