enum_transitions 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1163e05c0547bba40946136e8ed6e5816c044b1
4
+ data.tar.gz: da88b22cc6a7283c466a4d591596399f1f6f2dd0
5
+ SHA512:
6
+ metadata.gz: ce52ae8544c71df04827ab5edb1b675844613cbc19bccd9673fa69b4420e4c23ea21aea7e9a5938a9064272d09cabb3728e6ab673ad855ed2e9d26ac9069fbab
7
+ data.tar.gz: a8162fec399773363224fe90f1762c867e8ef23e2f1ffce10cf4aadb99b1cbad16d3b0834d1c4f33d9458ce7f25918bf27dff0048fca76bfc6e6930a88f8d024
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /spec/dummy/db/*.sqlite3
11
+ /spec/dummy/log/*.log
12
+ /spec/dummy/tmp/
13
+ /spec/dummy/.sass-cache
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --require byebug
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ cache: bundler
3
+ before_install: gem install bundler
4
+ rvm:
5
+ - 2.2.6
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby "2.2.6"
4
+ #ruby-gemset=enum_transitions
5
+
6
+ # Specify your gem's dependencies in enum_transitions.gemspec
7
+ gemspec
@@ -0,0 +1,58 @@
1
+ # EnumTransitions
2
+
3
+ Rails provides [ActiveRecord::Enum](http://api.rubyonrails.org/classes/ActiveRecord/Enum.html) which is great for state machines. The only problem is that it doesn't provide built-in validations for transitions.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'enum_transitions'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install enum_transitions
20
+
21
+ ## Usage
22
+
23
+ For example, let's say you have a `Car` model:
24
+
25
+ ```ruby
26
+ class Car < ApplicationRecord
27
+ enum state: [ :parked, :drive, :reverse ]
28
+
29
+ enum_transitions state: {
30
+ parked: [ :drive, :reverse ],
31
+ drive: :parked,
32
+ reverse: :parked
33
+ }
34
+ end
35
+ ```
36
+
37
+ Then when you call the transition methods (provided by `ActiveRecord::Enum`), an error will raise if the transition is invalid:
38
+
39
+ ```ruby
40
+ car = Car.create!
41
+ car.drive! #=> car.state == :drive
42
+ car.reverse! #=> raises EnumTransitions::InvalidTransition
43
+
44
+ car.transitions_to_reverse? #=> false
45
+ car.transitions_to_parked? #=> true
46
+ ```
47
+
48
+
49
+ ## Development
50
+
51
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
52
+
53
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
54
+
55
+ ## Contributing
56
+
57
+ Bug reports and pull requests are welcome on GitHub at https://github.com/listia/enum_transitions.
58
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "enum_transitions"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'enum_transitions/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "enum_transitions"
8
+ spec.version = EnumTransitions::VERSION
9
+ spec.authors = ["Ngan Pham", "Xenor Chang"]
10
+ spec.email = ["ngan@listia.com", "xenor@listia.com"]
11
+
12
+ spec.summary = %q{Add state maps to Rails Enums for validation on transitions.}
13
+ spec.description = %q{Add state maps to Rails Enums for validation on transitions.}
14
+ spec.homepage = "https://github.com/listia/enum_transitions"
15
+
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "rails", ">= 4.1", "< 4.3"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec-rails", "~> 3.5"
25
+ spec.add_development_dependency "byebug", "~> 9.0.6"
26
+ spec.add_development_dependency "sqlite3"
27
+ end
@@ -0,0 +1,68 @@
1
+ require "enum_transitions/version"
2
+
3
+ module EnumTransitions
4
+ InvalidTransition = Class.new(StandardError)
5
+
6
+ def self.extended(base)
7
+ base.class_attribute(:defined_enum_transitions, instance_writer: false)
8
+ base.defined_enum_transitions = {}
9
+ end
10
+
11
+ def inherited(base)
12
+ base.defined_enum_transitions = defined_enum_transitions.deep_dup
13
+ super
14
+ end
15
+
16
+ def enum_transitions(definitions)
17
+ definitions.each do |name, values|
18
+ unless enum_definition = defined_enums[name.to_s]
19
+ raise "#{name} enum is not defined"
20
+ end
21
+
22
+ transition_values = ActiveSupport::HashWithIndifferentAccess.new
23
+
24
+ values.each do |origin, destinations|
25
+ origin = origin.to_s
26
+ destinations = Array.wrap(destinations).map(&:to_s)
27
+ states_diff = (destinations + [origin]) - enum_definition.keys
28
+
29
+ unless states_diff.empty?
30
+ raise "#{name} enum does not define: #{states_diff.to_sentence}"
31
+ end
32
+
33
+ transition_values[origin] = destinations
34
+ end
35
+
36
+ enum_definition.keys.each do |state|
37
+ _enum_transitions_methods_module.module_eval do
38
+ define_method("transitions_to_#{state}?") {
39
+ defined_enum_transitions[name.to_s].map do |origin, destination|
40
+ origin if destination.include?(state)
41
+ end.compact.include?(public_send(name))
42
+ }
43
+
44
+ define_method("#{state}!") { |*args|
45
+ unless public_send("transitions_to_#{state}?")
46
+ raise InvalidTransition, "Cannot transition #{name} from `#{public_send(name)}` to `#{state}`"
47
+ end
48
+ super(*args)
49
+ }
50
+ end
51
+ end
52
+
53
+ defined_enum_transitions[name.to_s] = transition_values
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def _enum_transitions_methods_module
60
+ @_enum_transitions_methods_module ||= begin
61
+ mod = Module.new
62
+ include mod
63
+ mod
64
+ end
65
+ end
66
+ end
67
+
68
+ require "enum_transitions/railtie"
@@ -0,0 +1,9 @@
1
+ require "rails/railtie"
2
+
3
+ module EnumTransitions
4
+ class Railtie < ::Rails::Railtie
5
+ ActiveSupport.on_load :active_record do
6
+ ::ActiveRecord::Base.extend EnumTransitions
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module EnumTransitions
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: enum_transitions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ngan Pham
8
+ - Xenor Chang
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-12-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '4.1'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '4.3'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '4.1'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.3'
34
+ - !ruby/object:Gem::Dependency
35
+ name: bundler
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.11'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.11'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec-rails
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.5'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.5'
76
+ - !ruby/object:Gem::Dependency
77
+ name: byebug
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 9.0.6
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 9.0.6
90
+ - !ruby/object:Gem::Dependency
91
+ name: sqlite3
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ description: Add state maps to Rails Enums for validation on transitions.
105
+ email:
106
+ - ngan@listia.com
107
+ - xenor@listia.com
108
+ executables: []
109
+ extensions: []
110
+ extra_rdoc_files: []
111
+ files:
112
+ - ".gitignore"
113
+ - ".rspec"
114
+ - ".travis.yml"
115
+ - Gemfile
116
+ - README.md
117
+ - Rakefile
118
+ - bin/console
119
+ - bin/setup
120
+ - enum_transitions.gemspec
121
+ - lib/enum_transitions.rb
122
+ - lib/enum_transitions/railtie.rb
123
+ - lib/enum_transitions/version.rb
124
+ homepage: https://github.com/listia/enum_transitions
125
+ licenses: []
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.4.8
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Add state maps to Rails Enums for validation on transitions.
147
+ test_files: []