Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby 3.2 support #367

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ coverage/
/doc/
test/*.log
/Gemfile.lock

.idea/
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* Fix target state being indeterminate for transitions that use blacklists
* Allow super to be called within state-driven behaviors

## 2.0.0 - 2025-03-04

* Added Ruby 3.2 support for legacy projects, a very few changes such as `File.exists` and `Object#taint` fixes

## 1.2.0 / 2013-03-30

* Allow multiple whitelisted / blacklisted :to states when definining transitions
Expand Down
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This file is used to compare changes with "original" version of this gem.
FROM ruby:1.9.3

RUN mkdir /app
COPY . /app
WORKDIR /app

RUN bundle install
RUN gem install appraisal -v 0.5.2
RUN bundle exec rake test
#RUN bundle exec rake appraisal:install
#CMD bundle exec rake appraisal test

1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
source "http://www.rubygems.org"

gem 'test-unit'
gemspec
32 changes: 16 additions & 16 deletions lib/state_machine/integrations/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Base
module ClassMethods
# The default options to use for state machines using this integration
attr_reader :defaults

# The name of the integration
def integration_name
@integration_name ||= begin
Expand All @@ -16,71 +16,71 @@ def integration_name
name.to_sym
end
end

# Whether this integration is available for the current library. This
# is only true if the ORM that the integration is for is currently
# defined.
def available?
matching_ancestors.any? && Object.const_defined?(matching_ancestors[0].split('::')[0])
end

# The list of ancestor names that cause this integration to matched.
def matching_ancestors
[]
end

# Whether the integration should be used for the given class.
def matches?(klass)
matches_ancestors?(klass.ancestors.map {|ancestor| ancestor.name})
end

# Whether the integration should be used for the given list of ancestors.
def matches_ancestors?(ancestors)
(ancestors & matching_ancestors).any?
end

# Tracks the various version overrides for an integration
def versions
@versions ||= []
end

# Creates a new version override for an integration. When this
# integration is activated, each version that is marked as active will
# also extend the integration.
#
#
# == Example
#
#
# module StateMachine
# module Integrations
# module ORMLibrary
# version '0.2.x - 0.3.x' do
# def self.active?
# ::ORMLibrary::VERSION >= '0.2.0' && ::ORMLibrary::VERSION < '0.4.0'
# end
#
#
# def invalidate(object, attribute, message, values = [])
# # Override here...
# end
# end
# end
# end
# end
#
#
# In the above example, a version override is defined for the ORMLibrary
# integration when the version is between 0.2.x and 0.3.x.
def version(name, &block)
versions << mod = Module.new(&block)
mod
end

# The path to the locale file containing translations for this
# integration. This file will only exist for integrations that actually
# support i18n.
def locale_path
path = "#{File.dirname(__FILE__)}/#{integration_name}/locale.rb"
path if File.exists?(path)
path if File.exist?(path)
end

# Extends the given object with any version overrides that are currently
# active
def extended(base)
Expand All @@ -89,9 +89,9 @@ def extended(base)
end
end
end

extend ClassMethods

def self.included(base) #:nodoc:
base.class_eval { extend ClassMethods }
end
Expand Down
2 changes: 1 addition & 1 deletion lib/state_machine/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module StateMachine
VERSION = '1.2.0'
VERSION = '2.0.0'
end
7 changes: 4 additions & 3 deletions state_machine.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ Gem::Specification.new do |s|
s.test_files = s.files.grep(/^test\//)
s.rdoc_options = %w(--line-numbers --inline-source --title state_machine --main README.md)
s.extra_rdoc_files = %w(README.md CHANGELOG.md LICENSE)
s.add_development_dependency("rake")

s.add_development_dependency("rake", "~> 13.1.0")
s.add_development_dependency("simplecov")
s.add_development_dependency("appraisal", "~> 0.5.0")
s.add_development_dependency("docile", "~> 1.4.0")
s.add_development_dependency("appraisal", "~> 2.5.0")
end
52 changes: 27 additions & 25 deletions test/unit/eval_helpers_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class EvalHelpersBaseTest < Test::Unit::TestCase
include StateMachine::EvalHelpers

def default_test
end
end
Expand All @@ -11,7 +11,7 @@ class EvalHelpersTest < EvalHelpersBaseTest
def setup
@object = Object.new
end

def test_should_raise_exception_if_method_is_not_symbol_string_or_proc
exception = assert_raise(ArgumentError) { evaluate_method(@object, 1) }
assert_match(/Methods must/, exception.message)
Expand All @@ -26,7 +26,7 @@ def callback
end
end
end

def test_should_call_method_on_object_with_no_arguments
assert_equal true, evaluate_method(@object, :callback, 1, 2, 3)
end
Expand All @@ -41,7 +41,7 @@ def callback
end
end
end

def test_should_call_method_on_object_with_no_arguments
assert_equal true, evaluate_method(@object, :callback, 1, 2, 3)
end
Expand All @@ -56,7 +56,7 @@ def callback
end
end
end

def test_should_call_method_on_object_with_no_arguments
assert_equal true, evaluate_method(@object, :callback, 1, 2, 3)
end
Expand All @@ -70,7 +70,7 @@ def callback(*args)
end
end
end

def test_should_call_method_with_all_arguments
assert_equal [1, 2, 3], evaluate_method(@object, :callback, 1, 2, 3)
end
Expand All @@ -84,7 +84,7 @@ def callback
end
end
end

def test_should_call_method_on_object_with_block
assert_equal true, evaluate_method(@object, :callback) { true }
end
Expand All @@ -98,7 +98,7 @@ def callback(*args)
end
end
end

def test_should_call_method_on_object_with_all_arguments_and_block
assert_equal [1, 2, 3, true], evaluate_method(@object, :callback, 1, 2, 3) { true }
end
Expand All @@ -110,11 +110,13 @@ class << (@object = Object.new)
def callback
true
end

taint

# taint
# https://blog.saeloun.com/2020/02/18/ruby-2-7-access-and-setting-of-safe-warned-will-become-global-variable/#ruby-27
self
end
end

def test_should_not_raise_security_error
assert_nothing_raised { evaluate_method(@object, :callback, 1, 2, 3) }
end
Expand All @@ -126,13 +128,13 @@ class << (@object = Object.new)
def method_missing(symbol, *args)
send("method_missing_#{symbol}", *args)
end

def method_missing_callback(*args)
args
end
end
end

def test_should_call_dynamic_method_with_all_arguments
assert_equal [1, 2, 3], evaluate_method(@object, :callback, 1, 2, 3)
end
Expand All @@ -142,16 +144,16 @@ class EvalHelpersStringTest < EvalHelpersBaseTest
def setup
@object = Object.new
end

def test_should_evaluate_string
assert_equal 1, evaluate_method(@object, '1')
end

def test_should_evaluate_string_within_object_context
@object.instance_variable_set('@value', 1)
assert_equal 1, evaluate_method(@object, '@value')
end

def test_should_ignore_additional_arguments
assert_equal 1, evaluate_method(@object, '1', 2, 3, 4)
end
Expand All @@ -161,7 +163,7 @@ class EvalHelpersStringWithBlockTest < EvalHelpersBaseTest
def setup
@object = Object.new
end

def test_should_call_method_on_object_with_block
assert_equal 1, evaluate_method(@object, 'yield') { 1 }
end
Expand All @@ -172,7 +174,7 @@ def setup
@object = Object.new
@proc = lambda {|obj| obj}
end

def test_should_call_proc_with_object_as_argument
assert_equal @object, evaluate_method(@object, @proc, 1, 2, 3)
end
Expand All @@ -188,7 +190,7 @@ def arity
end
end
end

def test_should_call_proc_with_no_arguments
assert_equal [], evaluate_method(@object, @proc, 1, 2, 3)
end
Expand All @@ -199,7 +201,7 @@ def setup
@object = Object.new
@proc = lambda {|*args| args}
end

def test_should_call_method_with_all_arguments
assert_equal [@object, 1, 2, 3], evaluate_method(@object, @proc, 1, 2, 3)
end
Expand All @@ -210,7 +212,7 @@ def setup
@object = Object.new
@proc = lambda {|obj, block| block.call}
end

def test_should_call_method_on_object_with_block
assert_equal true, evaluate_method(@object, @proc, 1, 2, 3) { true }
end
Expand All @@ -226,7 +228,7 @@ def arity
end
end
end

def test_should_call_proc_without_arguments
block = lambda { true }
assert_equal [], evaluate_method(@object, @proc, 1, 2, 3, &block)
Expand All @@ -238,7 +240,7 @@ def setup
@object = Object.new
@proc = lambda {|block| [block]}
end

def test_should_call_proc_with_block_only
block = lambda { true }
assert_equal [block], evaluate_method(@object, @proc, 1, 2, 3, &block)
Expand All @@ -250,7 +252,7 @@ def setup
@object = Object.new
@proc = lambda {|*args| args}
end

def test_should_call_method_on_object_with_all_arguments_and_block
block = lambda { true }
assert_equal [@object, 1, 2, 3, block], evaluate_method(@object, @proc, 1, 2, 3, &block)
Expand All @@ -262,7 +264,7 @@ def setup
@object = Object.new
@proc = lambda {|object, arg1, arg2, arg3, block| [object, arg1, arg2, arg3, block]}
end

def test_should_call_method_on_object_with_all_arguments_and_block
block = lambda { true }
assert_equal [@object, 1, 2, 3, block], evaluate_method(@object, @proc, 1, 2, 3, &block)
Expand Down
Loading