stateful_enum 0.6.0 → 0.8.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
  SHA256:
3
- metadata.gz: 6d0d82f2cf13496a059030aac0a34a998e47997bcbf6605637fa488c5363454d
4
- data.tar.gz: 69fc206ccfc3d4290ad0961cac0d011e92ed1fa5421c0064bd881213d52082d5
3
+ metadata.gz: 862f0fff7013f98f6f39aa069098e104f7d48bcdefabbb30ca8accf6f817dd49
4
+ data.tar.gz: 645171697753e52e14c87a42df936df727d2b984bfc0dba7f05a18c874667694
5
5
  SHA512:
6
- metadata.gz: e3f5cec3415b7401c36acf28d5dda810d75818cc88b38a768e721757aaf508714ee0613b7926bb0b5e05832df83e6d7deadc3cc0b816eb3e7ab9a6286f6b1399
7
- data.tar.gz: 6a8d8196552d59c696c42872ae3a9decb62ddef4e75b42566af8e45cd2d3887e3fe6688808ac230f3d35ba7501f4e06328a4fad93462d3e8aee4fca985da4720
6
+ metadata.gz: ade6a0c15d35d147bb60f17d7dca8e36c0aa43975d14ca88dc88cf402b3bebd6b4d443b050048a0fbe8d92a339ae2fd966c6aa6220623e385d9df1c401366d8f
7
+ data.tar.gz: b6fd92a9296efb47852956375d73b8c801b63bbf877e4a9612db5f3f74f96ee4930a6cefe12cd635ea667ff43f0875ffebce8307bada70d409ac78f8171095c7
@@ -0,0 +1,92 @@
1
+ name: build
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ strategy:
8
+ matrix:
9
+ ruby_version: [ruby-head, '3.4', '3.3', '3.2', '3.1']
10
+ rails_version: [edge, '8.1', '8.0', '7.2', '7.1', '7.0', '6.1']
11
+
12
+ include:
13
+ - ruby_version: '3.0'
14
+ rails_version: '7.1'
15
+ - ruby_version: '3.0'
16
+ rails_version: '7.0'
17
+ - ruby_version: '3.0'
18
+ rails_version: '6.1'
19
+ - ruby_version: '3.0'
20
+ rails_version: '6.0'
21
+
22
+ - ruby_version: '2.7'
23
+ rails_version: '7.1'
24
+ - ruby_version: '2.7'
25
+ rails_version: '7.0'
26
+ - ruby_version: '2.7'
27
+ rails_version: '6.1'
28
+ - ruby_version: '2.7'
29
+ rails_version: '6.0'
30
+
31
+ - ruby_version: '2.6'
32
+ rails_version: '6.1'
33
+ - ruby_version: '2.6'
34
+ rails_version: '6.0'
35
+ - ruby_version: '2.6'
36
+ rails_version: '5.2'
37
+ - ruby_version: '2.6'
38
+ rails_version: '5.1'
39
+ - ruby_version: '2.6'
40
+ rails_version: '5.0'
41
+ - ruby_version: '2.6'
42
+ rails_version: '4.2'
43
+ bundler_version: '1'
44
+
45
+ - ruby_version: '2.5'
46
+ rails_version: '5.2'
47
+ - ruby_version: '2.5'
48
+ rails_version: '4.2'
49
+ bundler_version: '1'
50
+
51
+ - ruby_version: '2.4'
52
+ rails_version: '5.2'
53
+ - ruby_version: '2.4'
54
+ rails_version: '4.2'
55
+ bundler_version: '1'
56
+
57
+ - ruby_version: '2.3'
58
+ rails_version: '4.1'
59
+ bundler_version: '1'
60
+
61
+ - ruby_version: '2.2'
62
+ rails_version: '5.2'
63
+ bundler_version: '1'
64
+
65
+ exclude:
66
+ - ruby_version: '3.1'
67
+ rails_version: 'edge'
68
+ - ruby_version: '3.1'
69
+ rails_version: '8.1'
70
+ - ruby_version: '3.1'
71
+ rails_version: '8.0'
72
+
73
+ env:
74
+ RAILS_VERSION: ${{ matrix.rails_version }}
75
+
76
+ runs-on: ubuntu-24.04
77
+
78
+ steps:
79
+ - uses: actions/checkout@v6
80
+
81
+ - uses: ruby/setup-ruby@v1
82
+ with:
83
+ ruby-version: "${{ matrix.ruby_version }}"
84
+ rubygems: ${{ matrix.ruby_version < '2.7' && 'default' || 'latest' }}
85
+ bundler: "${{ matrix.bundler_version }}"
86
+ bundler-cache: true
87
+ continue-on-error: ${{ (matrix.ruby_version == 'ruby-head') || (matrix.rails_version == 'edge') || (matrix.allow_failures == 'true') }}
88
+
89
+ - run: sudo apt-get install graphviz
90
+
91
+ - run: bundle exec rake
92
+ continue-on-error: ${{ (matrix.ruby_version == 'ruby-head') || (matrix.rails_version == 'edge') || (matrix.allow_failures == 'true') }}
data/.gitignore CHANGED
@@ -10,5 +10,7 @@ gemfiles/*.lock
10
10
  /tmp/
11
11
  /log/
12
12
  /test/dummy/log/
13
+ /test/dummy/tmp/
14
+ /test/dummy/**/*.png
13
15
 
14
16
  .byebug_history
data/Gemfile CHANGED
@@ -1,6 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in stateful_enum.gemspec
4
6
  gemspec
5
7
 
6
- gem 'byebug'
8
+ if ENV['RAILS_VERSION'] == 'edge'
9
+ gem 'rails', git: 'https://github.com/rails/rails.git'
10
+ elsif ENV['RAILS_VERSION']
11
+ gem 'rails', "~> #{ENV['RAILS_VERSION']}.0"
12
+ if ENV['RAILS_VERSION'] <= '5.0'
13
+ gem 'sqlite3', '< 1.4'
14
+ elsif ENV['RAILS_VERSION'] <= '7.1'
15
+ gem 'sqlite3', '~> 1.4'
16
+ end
17
+ else
18
+ gem 'rails'
19
+ end
20
+
21
+ gem 'selenium-webdriver'
22
+ gem 'nokogiri', RUBY_VERSION < '2.1' ? '~> 1.6.0' : '>= 1.7'
23
+ gem 'loofah', RUBY_VERSION < '2.5' ? '< 2.21.0' : '>= 0'
24
+
25
+ if RUBY_VERSION >= '3.3'
26
+ gem 'bigdecimal'
27
+ gem 'mutex_m'
28
+ end
29
+
30
+ gem 'benchmark' if RUBY_VERSION >= '3.5'
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # StatefulEnum [![Build Status](https://travis-ci.org/amatsuda/stateful_enum.svg?branch=master)](https://travis-ci.org/amatsuda/stateful_enum)
1
+ # StatefulEnum [![Build Status](https://github.com/amatsuda/stateful_enum/actions/workflows/main.yml/badge.svg)](https://github.com/amatsuda/stateful_enum/actions)
2
2
 
3
3
  stateful_enum is a state machine gem built on top of ActiveRecord's built-in ActiveRecord::Enum.
4
4
 
@@ -41,7 +41,7 @@ The stateful_enum gem extends AR::Enum definition to take a block with a similar
41
41
  Example:
42
42
  ```ruby
43
43
  class Bug < ApplicationRecord
44
- enum status: {unassigned: 0, assigned: 1, resolved: 2, closed: 3} do
44
+ enum :status, {unassigned: 0, assigned: 1, resolved: 2, closed: 3} do
45
45
  event :assign do
46
46
  transition :unassigned => :assigned
47
47
  end
@@ -122,6 +122,29 @@ end
122
122
 
123
123
  You can define `before` and `after` event hooks inside of an `event` block.
124
124
 
125
+ Event methods accept arguments (both positional and keyword arguments) that are passed through to the callbacks:
126
+
127
+ ```ruby
128
+ class Bug < ApplicationRecord
129
+ enum :status, {unassigned: 0, assigned: 1, resolved: 2, closed: 3} do
130
+ event :close do
131
+ before do |closed_by:, reason: nil|
132
+ self.closed_by = closed_by
133
+ self.close_reason = reason
134
+ end
135
+
136
+ after do |closed_by:, **|
137
+ Notifier.notify "Bug##{id} was closed by #{closed_by.name}"
138
+ end
139
+
140
+ transition all - [:closed] => :closed
141
+ end
142
+ end
143
+ end
144
+
145
+ @bug.close(closed_by: current_user, reason: 'Duplicate')
146
+ ```
147
+
125
148
  ### Inspecting All Defined Events And Current Possible Events
126
149
 
127
150
  You can get the list of defined events from the model class:
@@ -175,9 +198,9 @@ You can specify relative or absolute output path via environment variable `DEST_
175
198
  * Better Error handling
176
199
 
177
200
 
178
- ## Support Rails Versions
201
+ ## Supported Rails Versions
179
202
 
180
- * Rails 4.1.x, 4.2.x, 5.0, 5.1, 5.2, and 6.0 (edge)
203
+ * Rails 4.1.x, 4.2.x, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, 8.1, and 8.2 (edge)
181
204
 
182
205
 
183
206
  ## Contributing
data/Rakefile CHANGED
@@ -13,11 +13,3 @@ Rake::TestTask.new(:test) do |t|
13
13
  end
14
14
 
15
15
  task default: :test
16
-
17
- namespace :test do
18
- task :all do
19
- YAML.load(File.read(File.expand_path('.travis.yml')))['gemfile'].each do |gemfile|
20
- sh "BUNDLE_GEMFILE='#{gemfile}' bundle exec rake test"
21
- end
22
- end
23
- end
@@ -39,7 +39,7 @@ module StatefulEnum
39
39
  @g.get_node(final) {|n| n['shape'] = 'doublecircle' }
40
40
  end
41
41
 
42
- @g.output png: File.join((ENV['DEST_DIR'] || Dir.pwd), "#{model.name}.png")
42
+ @g.output png: File.join((ENV['DEST_DIR'] || Dir.pwd), "#{model.name}_#{column}.png")
43
43
  end
44
44
 
45
45
  def event(name, &block)
@@ -9,13 +9,31 @@ module StatefulEnum
9
9
  # transition :unassigned => :assigned
10
10
  # end
11
11
  # end
12
- def enum(definitions, &block)
13
- prefix, suffix = definitions[:_prefix], definitions[:_suffix] if Rails::VERSION::MAJOR >= 5
14
- enum = super definitions
12
+ if Rails::VERSION::MAJOR >= 7
13
+ def enum(name = nil, values = nil, **options, &block)
14
+ return super unless block
15
15
 
16
- if block
17
- definitions.each_key do |column|
18
- states = enum[column]
16
+ definitions = super name, values, **options
17
+
18
+ if name
19
+ (@_defined_stateful_enums ||= []) << StatefulEnum::Machine.new(self, name, (definitions.is_a?(Hash) ? definitions.keys : definitions), options[:prefix], options[:suffix], &block)
20
+ else
21
+ definitions.each do |column, states|
22
+ (@_defined_stateful_enums ||= []) << StatefulEnum::Machine.new(self, column, (states.is_a?(Hash) ? states.keys : states), options[:_prefix], options[:_suffix], &block)
23
+ end
24
+ end
25
+
26
+ definitions
27
+ end
28
+ else
29
+ def enum(definitions, &block)
30
+ return super unless block
31
+
32
+ # Preserving prefix and suffix values before calling super because the super destroys the given Hash
33
+ prefix, suffix = definitions[:_prefix], definitions[:_suffix] if Rails::VERSION::MAJOR >= 5
34
+ enum_values = super definitions
35
+
36
+ enum_values.each_pair do |column, states|
19
37
  (@_defined_stateful_enums ||= []) << StatefulEnum::Machine.new(self, column, (states.is_a?(Hash) ? states.keys : states), prefix, suffix, &block)
20
38
  end
21
39
  end
@@ -5,7 +5,7 @@ module StatefulEnum
5
5
  attr_reader :events
6
6
 
7
7
  def initialize(model, column, states, prefix, suffix, &block)
8
- @model, @column, @states, @events = model, column, states, []
8
+ @model, @column, @states, @events = model, column, states.map(&:to_sym), []
9
9
  @prefix = if prefix
10
10
  prefix == true ? "#{column}_" : "#{prefix}_"
11
11
  end
@@ -27,7 +27,7 @@ module StatefulEnum
27
27
  end
28
28
 
29
29
  class Event
30
- attr_reader :name, :value_method_name
30
+ attr_reader :name, :value_method_name, :transitions
31
31
 
32
32
  def initialize(model, column, states, prefix, suffix, name, &block)
33
33
  @states, @name, @transitions, @before, @after = states, name, {}, [], []
@@ -42,24 +42,23 @@ module StatefulEnum
42
42
  # def assign()
43
43
  detect_enum_conflict! column, value_method_name
44
44
 
45
- # defining callbacks
46
- define_callbacks value_method_name
47
- before.each do |before_callback|
48
- model.set_callback value_method_name, :before, before_callback
49
- end
50
- after.each do |after_callback|
51
- model.set_callback value_method_name, :after, after_callback
52
- end
53
-
54
- define_method value_method_name do
45
+ define_method value_method_name do |*args, **kwargs|
55
46
  to, condition = transitions[send(column).to_sym]
56
47
  #TODO better error
57
- if to && (!condition || instance_exec(&condition))
48
+ if to && (condition.nil? || instance_exec(&condition))
58
49
  #TODO transaction?
59
- run_callbacks value_method_name do
60
- original_method = self.class.send(:_enum_methods_module).instance_method "#{prefix}#{to}#{suffix}!"
61
- original_method.bind(self).call
50
+ before.each do |before_callback|
51
+ instance_exec(*args, **kwargs, &before_callback)
62
52
  end
53
+
54
+ original_method = self.class.send(:_enum_methods_module).instance_method "#{prefix}#{to}#{suffix}!"
55
+ ret = original_method.bind(self).call
56
+
57
+ after.each do |after_callback|
58
+ instance_exec(*args, **kwargs, &after_callback)
59
+ end
60
+
61
+ ret
63
62
  else
64
63
  false
65
64
  end
@@ -67,8 +66,8 @@ module StatefulEnum
67
66
 
68
67
  # def assign!()
69
68
  detect_enum_conflict! column, "#{value_method_name}!"
70
- define_method "#{value_method_name}!" do
71
- send(value_method_name) || raise('Invalid transition')
69
+ define_method "#{value_method_name}!" do |*args, **kwargs|
70
+ send(value_method_name, *args, **kwargs) || raise('Invalid transition')
72
71
  end
73
72
 
74
73
  # def can_assign?()
@@ -77,7 +76,7 @@ module StatefulEnum
77
76
  state = send(column).to_sym
78
77
  return false unless transitions.key? state
79
78
  _to, condition = transitions[state]
80
- !condition || instance_exec(&condition)
79
+ condition.nil? || instance_exec(&condition)
81
80
  end
82
81
 
83
82
  # def assign_transition()
@@ -37,7 +37,7 @@ module StatefulEnum
37
37
  @defined_stateful_enums.flat_map do |stateful_enum|
38
38
  col = stateful_enum.instance_variable_get :@column
39
39
  pe = stateful_enum.events.select {|e| @model_instance.send("can_#{e.value_method_name}?") }
40
- pe.flat_map {|e| e.instance_variable_get(:@transitions)[@model_instance.send(col).to_sym].first }
40
+ pe.flat_map {|e| e.transitions[@model_instance.send(col).to_sym].first }
41
41
  end
42
42
  end
43
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StatefulEnum
4
- VERSION = '0.6.0'
4
+ VERSION = '0.8.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stateful_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Matsuda
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2019-06-06 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -101,21 +100,14 @@ executables: []
101
100
  extensions: []
102
101
  extra_rdoc_files: []
103
102
  files:
103
+ - ".github/workflows/main.yml"
104
104
  - ".gitignore"
105
- - ".travis.yml"
106
105
  - Gemfile
107
106
  - MIT-LICENSE
108
107
  - README.md
109
108
  - Rakefile
110
109
  - bin/console
111
110
  - bin/setup
112
- - gemfiles/Gemfile-rails.4.1.x
113
- - gemfiles/Gemfile-rails.4.2.x
114
- - gemfiles/Gemfile-rails.5.0.x
115
- - gemfiles/Gemfile-rails.5.1.x
116
- - gemfiles/Gemfile-rails.5.2.x
117
- - gemfiles/Gemfile-rails.6.0.x
118
- - gemfiles/Gemfile-rails.edge
119
111
  - lib/generators/stateful_enum/graph_generator.rb
120
112
  - lib/generators/stateful_enum/plantuml_generator.rb
121
113
  - lib/stateful_enum.rb
@@ -129,7 +121,6 @@ homepage: https://github.com/amatsuda/stateful_enum
129
121
  licenses:
130
122
  - MIT
131
123
  metadata: {}
132
- post_install_message:
133
124
  rdoc_options: []
134
125
  require_paths:
135
126
  - lib
@@ -144,8 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
135
  - !ruby/object:Gem::Version
145
136
  version: '0'
146
137
  requirements: []
147
- rubygems_version: 3.0.3
148
- signing_key:
138
+ rubygems_version: 4.0.3
149
139
  specification_version: 4
150
140
  summary: A state machine plugin on top of ActiveRecord::Enum
151
141
  test_files: []
data/.travis.yml DELETED
@@ -1,47 +0,0 @@
1
- language: ruby
2
-
3
- sudo: false
4
-
5
- cache:
6
- - apt
7
- - bundler
8
- before_install:
9
- - gem i bundler -v '<2'
10
-
11
- addons:
12
- apt:
13
- packages:
14
- - graphviz
15
-
16
- matrix:
17
- include:
18
- - rvm: 2.6.0
19
- gemfile: gemfiles/Gemfile-rails.6.0.x
20
-
21
- - rvm: 2.6.0
22
- gemfile: gemfiles/Gemfile-rails.5.2.x
23
- - rvm: 2.6.0
24
- gemfile: gemfiles/Gemfile-rails.5.1.x
25
- - rvm: 2.6.0
26
- gemfile: gemfiles/Gemfile-rails.5.0.x
27
-
28
- - rvm: 2.5.3
29
- gemfile: gemfiles/Gemfile-rails.4.2.x
30
-
31
- - rvm: 2.3.8
32
- gemfile: gemfiles/Gemfile-rails.4.1.x
33
-
34
- - rvm: 2.4.5
35
- gemfile: gemfiles/Gemfile-rails.5.2.x
36
- - rvm: 2.2.10
37
- gemfile: gemfiles/Gemfile-rails.5.2.x
38
-
39
- - rvm: ruby-head
40
- gemfile: gemfiles/Gemfile-rails.5.2.x
41
-
42
- - rvm: 2.6.0
43
- gemfile: gemfiles/Gemfile-rails.edge
44
-
45
- allow_failures:
46
- - rvm: ruby-head
47
- - gemfile: gemfiles/Gemfile-rails.edge
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 4.1.0'
6
- gem 'sqlite3', '~> 1.3.6'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 4.2.0'
6
- gem 'sqlite3', '~> 1.3.6'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 5.0.0'
6
- gem 'sqlite3', '~> 1.3.6'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 5.1.0'
6
- gem 'sqlite3', '~> 1.3.6'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 5.2.0'
6
- gem 'sqlite3', '~> 1.3.6'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '..'
4
-
5
- gem 'rails', '~> 6.0.0.rc1'
6
- gem 'selenium-webdriver'
@@ -1,14 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- git_source(:github) do |repo_name|
4
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
5
- "https://github.com/#{repo_name}.git"
6
- end
7
-
8
- gemspec path: '..'
9
-
10
- github 'rails/rails' do
11
- gem 'rails'
12
- end
13
- gem 'sqlite3'
14
- gem 'selenium-webdriver'