state_machina 0.1.6 → 0.1.8

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
  SHA256:
3
- metadata.gz: dafbf3b6c0e98deba3f63e96af9dc514736a486e1c899ef3160085141c987a95
4
- data.tar.gz: c243f44bf6bc3c1fed703a8233ad9afe8f712081b946a7f72e3a227d621e0567
3
+ metadata.gz: da7744a0dd9bd422710ba97e8db2799be0ce7a9c2aed9da7c580f0f0941b3276
4
+ data.tar.gz: ffa9c6ab967b3490b0bc54fbd34ea51332d9d2e61470e1c07468a1f8caf81b80
5
5
  SHA512:
6
- metadata.gz: 685b1a4811ba9ce5949ade06712bb1381c88d4cec75d8677b125797e5095abc8b1de51f089450ac5e2cc335e829a2431251cf8f43924ca1fde074eee8b258360
7
- data.tar.gz: b6c32281cef34382ad98b978c9f2df9204b96e15e2ffea630fd3dabd8a88ff63a1b53944549f63a24d7a17fb20626a7a1ef2ddb36eb84635dd68b13a761f57ff
6
+ metadata.gz: ca9ee7f05f7790ebe6cedb28d7d62963f1718ac1d0baf2317640ae26b42846e06999784ebb906cc62035dc320e51520a1479204c62c98051c7989de862b83d65
7
+ data.tar.gz: 96215bace1c18c7d7a9829541e035d4cdb46f6ee136ca0f5a6621b31d49df22b44f6f9224f825863a5a84255eb4ff817ed07a769c0fa8bf32a9dccb0e5d965ce
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.2.0
1
+ ruby 4.0.2
data/Gemfile CHANGED
@@ -10,3 +10,5 @@ gem "rake", "~> 13.0"
10
10
  gem "rspec", "~> 3.0"
11
11
 
12
12
  gem "rubocop", "~> 1.21"
13
+
14
+ gem "activesupport", "< 8", require: false
data/Gemfile.lock CHANGED
@@ -1,17 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- state_machina (0.1.6)
4
+ state_machina (0.1.8)
5
+ activesupport (>= 5.0, < 8)
5
6
  concurrent-ruby (< 2)
7
+ i18n (>= 0.7, < 2)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
12
+ activesupport (7.2.4)
13
+ base64
14
+ benchmark (>= 0.3)
15
+ bigdecimal
16
+ concurrent-ruby (~> 1.0, >= 1.3.1)
17
+ connection_pool (>= 2.2.5, < 3)
18
+ drb
19
+ i18n (>= 1.6, < 2)
20
+ logger (>= 1.4.2)
21
+ minitest (>= 5.1, < 6)
22
+ securerandom (>= 0.3)
23
+ tzinfo (~> 2.0, >= 2.0.5)
10
24
  ast (2.4.2)
25
+ base64 (0.3.0)
26
+ benchmark (0.5.0)
27
+ bigdecimal (4.1.3)
11
28
  coderay (1.1.3)
12
- concurrent-ruby (1.2.3)
29
+ concurrent-ruby (1.3.8)
30
+ connection_pool (2.5.5)
13
31
  diff-lcs (1.5.0)
32
+ drb (2.2.3)
33
+ i18n (1.15.2)
34
+ concurrent-ruby (~> 1.0)
35
+ logger (1.7.0)
14
36
  method_source (1.0.0)
37
+ minitest (5.27.0)
15
38
  parallel (1.21.0)
16
39
  parser (3.1.1.0)
17
40
  ast (~> 2.4.1)
@@ -47,14 +70,20 @@ GEM
47
70
  rubocop-ast (1.16.0)
48
71
  parser (>= 3.1.1.0)
49
72
  ruby-progressbar (1.11.0)
73
+ securerandom (0.4.1)
74
+ tzinfo (2.0.6)
75
+ concurrent-ruby (~> 1.0)
50
76
  unicode-display_width (2.1.0)
51
77
 
52
78
  PLATFORMS
53
79
  arm64-darwin-21
54
80
  arm64-darwin-22
81
+ arm64-darwin-23
82
+ arm64-darwin-25
55
83
  x86_64-darwin-20
56
84
 
57
85
  DEPENDENCIES
86
+ activesupport (< 8)
58
87
  pry (< 0.15)
59
88
  rake (~> 13.0)
60
89
  rspec (~> 3.0)
@@ -2,7 +2,7 @@ module StateMachina
2
2
  module ExtendedIntegration
3
3
  module ClassMethods
4
4
  # Extends a machine on a model where the machine is already defined
5
- def extend_machine(klass, machine_name = 'default')
5
+ def extend_machine(klass, machine_name = StateMachina::Machine::DEFAULT_MACHINE_NAME)
6
6
  model_name = StateMachina::Util.normalized_klass_to_name(klass)
7
7
 
8
8
  yield(StateMachina::Registry.find_machine!(model_name, machine_name))
@@ -2,9 +2,15 @@ module StateMachina
2
2
  module Integration
3
3
  module ClassMethods
4
4
  # Defines a new machine on a model
5
- def define_machine(machine_name = 'default', column_name: :state, metadata: {})
5
+ def define_machine(machine_name = StateMachina::Machine::DEFAULT_MACHINE_NAME, column_name: :state, i18n_scope: nil, metadata: {})
6
6
  model_name = StateMachina::Util.normalized_klass_to_name(self)
7
- machine = StateMachina::Machine.new(model_name, machine_name, column_name: column_name, metadata: metadata)
7
+ machine = StateMachina::Machine.new(
8
+ model_name,
9
+ machine_name,
10
+ column_name: column_name,
11
+ i18n_scope: i18n_scope,
12
+ metadata: metadata
13
+ )
8
14
 
9
15
  yield(StateMachina::Registry.register_machine(machine))
10
16
  end
@@ -12,7 +18,7 @@ module StateMachina
12
18
  alias_method :define_state_machine, :define_machine
13
19
 
14
20
  # Extends a machine on a model where the machine is already defined
15
- def extend_machine(klass, machine_name = 'default')
21
+ def extend_machine(klass, machine_name = StateMachina::Machine::DEFAULT_MACHINE_NAME)
16
22
  model_name = StateMachina::Util.normalized_klass_to_name(klass)
17
23
 
18
24
  yield(StateMachina::Registry.find_machine!(model_name, machine_name))
@@ -21,7 +27,7 @@ module StateMachina
21
27
  alias_method :extend_state_machine, :extend_machine
22
28
 
23
29
  # Returns the defined machine on a model
24
- def machine(machine_name = 'default')
30
+ def machine(machine_name = StateMachina::Machine::DEFAULT_MACHINE_NAME)
25
31
  model_name = StateMachina::Util.normalized_klass_to_name(self)
26
32
 
27
33
  StateMachina::Registry.find_machine!(model_name, machine_name)
@@ -44,7 +50,7 @@ module StateMachina
44
50
  end
45
51
 
46
52
  # Returns the defined machine on a model instance
47
- def machine(machine_name = 'default')
53
+ def machine(machine_name = StateMachina::Machine::DEFAULT_MACHINE_NAME)
48
54
  model_name = StateMachina::Util.normalized_klass_to_name(self.class)
49
55
 
50
56
  machine = StateMachina::Registry.find_machine!(model_name, machine_name).dup
@@ -1,15 +1,32 @@
1
1
  module StateMachina
2
2
  class Machine
3
- attr_reader :model_name, :name, :column_name, :metadata
3
+ DEFAULT_MACHINE_NAME = 'default'
4
+
5
+ attr_reader :model_name, :name, :column_name, :i18n_scope, :metadata
4
6
  attr_accessor :model
5
7
 
6
- def initialize(model_name, name, column_name: :state, metadata: {})
8
+ delegate :before?, :before_inclusive?, :past?, :past_inclusive?, :between?, :between_inclusive?, to: :current_state
9
+
10
+ def initialize(model_name, name, column_name: :state, i18n_scope: nil, metadata: {})
7
11
  @model_name = model_name
8
12
  @name = name.to_s
9
13
  @column_name = column_name
14
+ @i18n_scope = i18n_scope || default_i18n_scope
10
15
  @metadata = metadata
11
16
  end
12
17
 
18
+ def default?
19
+ name == DEFAULT_MACHINE_NAME
20
+ end
21
+
22
+ def self.default_i18n_scope(model_name)
23
+ "activerecord.attributes.#{model_name}"
24
+ end
25
+
26
+ def human_name
27
+ I18n.t(name, scope: "#{i18n_scope}.machines", default: name.humanize)
28
+ end
29
+
13
30
  def state(state_name, metadata: {})
14
31
  state = StateMachina::State.new(model_name, name, state_name, metadata: metadata)
15
32
 
@@ -53,6 +70,7 @@ module StateMachina
53
70
  end
54
71
 
55
72
  def update_state(new_state)
73
+ raise(UnknownStateError, "for model: #{model_name}, with name: #{new_state}") unless states.find_by_name(new_state)
56
74
  if model.respond_to?(:update)
57
75
  model.update(column_name => new_state)
58
76
  else
@@ -61,6 +79,7 @@ module StateMachina
61
79
  end
62
80
 
63
81
  def update_state!(new_state)
82
+ raise(UnknownStateError, "for model: #{model_name}, with name: #{new_state}") unless states.find_by_name(new_state)
64
83
  if model.respond_to?(:update!)
65
84
  model.update!(column_name => new_state)
66
85
  else
@@ -70,6 +89,10 @@ module StateMachina
70
89
 
71
90
  private
72
91
 
92
+ def default_i18n_scope
93
+ self.class.default_i18n_scope(model_name)
94
+ end
95
+
73
96
  def select_possible_events(events)
74
97
  events.select(&:possible?)
75
98
  end
@@ -10,28 +10,38 @@ module StateMachina
10
10
  @metadata = metadata
11
11
  end
12
12
 
13
+ def human_name
14
+ return name.humanize if machine.nil?
15
+
16
+ I18n.t(name, scope: i18n_scope, default: name.humanize)
17
+ end
18
+
19
+ def i18n_scope
20
+ "#{machine.i18n_scope}.states.#{machine_name}"
21
+ end
22
+
13
23
  def before?(other_state_name)
14
24
  return false if machine.nil?
15
25
 
16
- !machine.states.before(machine.current_state_name).map(&:name).include?(other_state_name)
26
+ machine.states.before(other_state_name).map(&:name).include?(machine.current_state_name)
17
27
  end
18
28
 
19
29
  def before_inclusive?(other_state_name)
20
30
  return false if machine.nil?
21
31
 
22
- !machine.states.before_inclusive(machine.current_state_name).map(&:name).include?(other_state_name)
32
+ machine.states.before_inclusive(other_state_name).map(&:name).include?(machine.current_state_name)
23
33
  end
24
34
 
25
35
  def past?(other_state_name)
26
36
  return false if machine.nil?
27
37
 
28
- !machine.states.past(machine.current_state_name).map(&:name).include?(other_state_name)
38
+ machine.states.past(other_state_name).map(&:name).include?(machine.current_state_name)
29
39
  end
30
40
 
31
41
  def past_inclusive?(other_state_name)
32
42
  return false if machine.nil?
33
43
 
34
- !machine.states.past_inclusive(machine.current_state_name).map(&:name).include?(other_state_name)
44
+ machine.states.past_inclusive(other_state_name).map(&:name).include?(machine.current_state_name)
35
45
  end
36
46
 
37
47
  def between?(from_state_name, to_state_name)
@@ -21,7 +21,10 @@ module StateMachina
21
21
  end
22
22
 
23
23
  def before(state_name)
24
- to_a[..(index_by_name(state_name) - 1)]
24
+ index = index_by_name(state_name) - 1
25
+ return [] if index.negative?
26
+
27
+ to_a[..index]
25
28
  end
26
29
 
27
30
  def before_inclusive(state_name)
@@ -37,11 +40,17 @@ module StateMachina
37
40
  end
38
41
 
39
42
  def between(from_state_name, to_state_name)
40
- to_a[index_by_name(from_state_name)...index_by_name(to_state_name)]
43
+ indexes = [index_by_name(from_state_name), index_by_name(to_state_name)]
44
+ raise(ArgumentError, "to_state should be higher than from_state") if indexes != indexes.sort
45
+
46
+ to_a[indexes[0]...indexes[1]]
41
47
  end
42
48
 
43
49
  def between_inclusive(from_state_name, to_state_name)
44
- to_a[index_by_name(from_state_name)..index_by_name(to_state_name)]
50
+ indexes = [index_by_name(from_state_name), index_by_name(to_state_name)]
51
+ raise(ArgumentError, "to_state should be higher than from_state") if indexes != indexes.sort
52
+
53
+ to_a[indexes[0]..indexes[1]]
45
54
  end
46
55
 
47
56
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StateMachina
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.8"
5
5
  end
data/lib/state_machina.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "concurrent"
4
+ require "i18n"
5
+ require "active_support/core_ext/module/delegation"
6
+ require "active_support/core_ext/string/inflections"
4
7
 
5
8
  require_relative "state_machina/event"
6
9
  require_relative "state_machina/events_collection"
@@ -18,4 +21,5 @@ module StateMachina
18
21
  class Error < StandardError; end
19
22
 
20
23
  class NoMachineFoundError < Error; end
24
+ class UnknownStateError < Error; end
21
25
  end
metadata CHANGED
@@ -1,15 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_machina
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan van der Pas
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-01-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activesupport
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '5.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '8'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '5.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '8'
13
32
  - !ruby/object:Gem::Dependency
14
33
  name: concurrent-ruby
15
34
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +43,26 @@ dependencies:
24
43
  - - "<"
25
44
  - !ruby/object:Gem::Version
26
45
  version: '2'
46
+ - !ruby/object:Gem::Dependency
47
+ name: i18n
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0.7'
53
+ - - "<"
54
+ - !ruby/object:Gem::Version
55
+ version: '2'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0.7'
63
+ - - "<"
64
+ - !ruby/object:Gem::Version
65
+ version: '2'
27
66
  - !ruby/object:Gem::Dependency
28
67
  name: pry
29
68
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +77,6 @@ dependencies:
38
77
  - - "<"
39
78
  - !ruby/object:Gem::Version
40
79
  version: '0.15'
41
- description:
42
80
  email:
43
81
  - jan.vanderpas@beequip.nl
44
82
  executables: []
@@ -68,12 +106,9 @@ files:
68
106
  - lib/state_machina/util.rb
69
107
  - lib/state_machina/version.rb
70
108
  - sig/state_machina.rbs
71
- - state_machina.gemspec
72
- homepage:
73
109
  licenses:
74
110
  - MIT
75
111
  metadata: {}
76
- post_install_message:
77
112
  rdoc_options: []
78
113
  require_paths:
79
114
  - lib
@@ -88,8 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
123
  - !ruby/object:Gem::Version
89
124
  version: '0'
90
125
  requirements: []
91
- rubygems_version: 3.4.21
92
- signing_key:
126
+ rubygems_version: 4.0.13
93
127
  specification_version: 4
94
128
  summary: State machine supporting multiple machines per object
95
129
  test_files: []
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/state_machina/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "state_machina"
7
- spec.version = StateMachina::VERSION
8
- spec.authors = ["Jan van der Pas"]
9
- spec.email = ["jan.vanderpas@beequip.nl"]
10
-
11
- spec.summary = "State machine supporting multiple machines per object"
12
- # spec.description = "TODO: Write a longer description or delete this line."
13
- # spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.6.0"
16
-
17
- # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
-
19
- # spec.metadata["homepage_uri"] = spec.homepage
20
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
21
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
-
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
- `git ls-files -z`.split("\x0").reject do |f|
27
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
- end
29
- end
30
- spec.bindir = "exe"
31
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
- spec.require_paths = ["lib"]
33
-
34
- spec.add_dependency "concurrent-ruby", "< 2"
35
- spec.add_development_dependency "pry", "< 0.15"
36
- end