Skip to content
Merged
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
3 changes: 1 addition & 2 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby-version: ['3.2', '3.3', '3.4']
ruby-version: ['3.2', '3.4']
gemfiles:
- gemfiles/active_model_7.1.gemfile
- gemfiles/active_model_7.2.gemfile
- gemfiles/active_model_8.0.gemfile
- gemfiles/active_model_edge.gemfile
Expand Down
34 changes: 34 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
AllCops:
NewCops: enable
TargetRubyVersion: 3.0
SuggestExtensions: false

# Allow nested method definitions in tests - they're used for test setup
Lint/NestedMethodDefinition:
Exclude:
- 'test/**/*_test.rb'

# Test setup methods can be longer
Metrics/MethodLength:
Exclude:
- 'test/**/*_test.rb'
- 'test/test_helper.rb'
Max: 10

# Use bracket style for percent literals
Style/PercentLiteralDelimiters:
PreferredDelimiters:
'%w': '[]'
'%W': '[]'
'%i': '[]'
'%I': '[]'

# The save method in tests returns a boolean, it's not a predicate method
Naming/PredicateMethod:
Exclude:
- 'test/**/*_test.rb'

# In tests, we sometimes need empty initialize methods for stubbing
Style/RedundantInitialize:
Exclude:
- 'test/**/*_test.rb'
2 changes: 1 addition & 1 deletion state_machines-activemodel.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
spec.test_files = Dir.glob('test/**/{*_test,test_*}.rb')
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 3.2.0'
spec.add_dependency 'state_machines', '>= 0.100.0'
spec.add_dependency 'state_machines', '>= 0.100.1'
spec.add_dependency 'activemodel', '>= 7.2'

spec.add_development_dependency 'bundler', '>= 1.6'
Expand Down
2 changes: 1 addition & 1 deletion test/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_should_match_if_class_includes_validations_feature
end

def test_should_not_match_if_class_does_not_include_active_model_features
refute StateMachines::Integrations::ActiveModel.matches?(new_model)
refute StateMachines::Integrations::ActiveModel.matches?(new_plain_model)
end

def test_should_have_no_defaults
Expand Down
5 changes: 1 addition & 4 deletions test/machine_initialization_compatibility_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class MachineInitializationCompatibilityTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Validations
attr_accessor :state
end

@machine = StateMachines::Machine.new(@model, initial: :parked)
Expand All @@ -31,9 +30,7 @@ def test_should_accept_empty_initialization

def test_should_handle_attribute_aliases
@model.class_eval do
def self.attribute_aliases
{ 'status' => 'state' }
end
alias_attribute :status, :state
end

record = @model.new(status: 'idling')
Expand Down
2 changes: 1 addition & 1 deletion test/machine_multiple_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class MachineMultipleTest < BaseTestCase
def setup
@model = new_model do
model_attribute :status
attribute :status, :string
end

@state_machine = StateMachines::Machine.new(@model, initial: :parked, integration: :active_model)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Dirty
model_attribute :status
define_attribute_methods [:status]
attribute :status, :string

def save
super.tap do
if valid?
changes_applied
true
else
false
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions test/machine_with_dirty_attribute_and_state_events_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
class MachineWithDirtyAttributeAndStateEventsTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Dirty
define_attribute_methods [:state]

def save
super.tap do
if valid?
changes_applied
true
else
false
end
end
end
Expand Down
15 changes: 8 additions & 7 deletions test/machine_with_dirty_attributes_and_custom_attribute_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
class MachineWithDirtyAttributesAndCustomAttributeTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Dirty
model_attribute :status
define_attribute_methods [:status]
attribute :status, :string

def save
super.tap do
if valid?
changes_applied
true
else
false
end
end
end
Expand All @@ -26,17 +27,17 @@ def save
end

def test_should_include_state_in_changed_attributes
assert_equal %w(status), @record.changed
assert_equal %w[status], @record.changed
end

def test_should_track_attribute_change
assert_equal %w(parked idling), @record.changes['status']
assert_equal %w[parked idling], @record.changes['status']
end

def test_should_not_reset_changes_on_multiple_transitions
transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
transition.perform

assert_equal %w(parked idling), @record.changes['status']
assert_equal %w[parked idling], @record.changes['status']
end
end
8 changes: 4 additions & 4 deletions test/machine_with_dirty_attributes_during_loopback_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
class MachineWithDirtyAttributesDuringLoopbackTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Dirty
define_attribute_methods [:state]

def save
super.tap do
if valid?
changes_applied
true
else
false
end
end
end
Expand Down
14 changes: 7 additions & 7 deletions test/machine_with_dirty_attributes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
class MachineWithDirtyAttributesTest < BaseTestCase
def setup
@model = new_model do
include ActiveModel::Dirty
define_attribute_methods [:state]

def save
super.tap do
if valid?
changes_applied
true
else
false
end
end
end
Expand All @@ -25,17 +25,17 @@ def save
end

def test_should_include_state_in_changed_attributes
assert_equal %w(state), @record.changed
assert_equal %w[state], @record.changed
end

def test_should_track_attribute_change
assert_equal %w(parked idling), @record.changes['state']
assert_equal %w[parked idling], @record.changes['state']
end

def test_should_not_reset_changes_on_multiple_transitions
transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
transition.perform

assert_equal %w(parked idling), @record.changes['state']
assert_equal %w[parked idling], @record.changes['state']
end
end
13 changes: 11 additions & 2 deletions test/machine_with_initialized_aliased_attribute_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class MachineWithInitializedAliasedAttributeTest < BaseTestCase
def test_should_match_original_attribute_value_with_attribute_methods
model = new_model do
include ActiveModel::AttributeMethods

alias_attribute :custom_status, :state
end

Expand All @@ -19,7 +20,16 @@ def test_should_match_original_attribute_value_with_attribute_methods
end

def test_should_not_match_original_attribute_value_without_attribute_methods
model = new_model do
model = new_plain_model do
include ActiveModel::Model

attr_accessor :state

def self.alias_attribute(new_name, old_name)
alias_method new_name, old_name
alias_method "#{new_name}=", "#{old_name}="
end

alias_attribute :custom_status, :state
end

Expand All @@ -32,4 +42,3 @@ def test_should_not_match_original_attribute_value_without_attribute_methods
refute record.state?(:started)
end
end

5 changes: 2 additions & 3 deletions test/machine_with_non_model_state_attribute_undefined_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

class MachineWithNonModelStateAttributeUndefinedTest < BaseTestCase
def setup
@model = new_model do
def initialize
end
@model = new_plain_model do
def initialize; end
end

@machine = StateMachines::Machine.new(@model, :status, initial: :parked, integration: :active_model)
Expand Down
49 changes: 22 additions & 27 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,40 @@

class BaseTestCase < ActiveSupport::TestCase
protected
# Creates a new ActiveModel model (and the associated table)
def new_model(&block)
# Simple ActiveModel superclass
parent = Class.new do
def self.model_attribute(name)
define_method(name) { instance_variable_defined?(:"@#{name}") ? instance_variable_get(:"@#{name}") : nil }
define_method("#{name}=") do |value|
send(:"#{name}_will_change!") if self.class <= ActiveModel::Dirty && value != send(name)
instance_variable_set("@#{name}", value)
end
end

def self.create
object = new
object.save
object
# Creates a plain model without ActiveModel features
def new_plain_model(&block)
model = Class.new do
def self.name
'Foo'
end
end

def initialize(attrs = {})
attrs.each { |attr, value| send("#{attr}=", value) }
end
model.class_eval(&block) if block_given?

def attributes
@attributes ||= {}
end
model
end

def save
true
end
end
# Creates a new ActiveModel model (and the associated table)
def new_model(&block)
model = Class.new do
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Dirty

attribute :state, :string

model = Class.new(parent) do
def self.name
'Foo'
end

model_attribute :state
def self.create
new.tap { |instance| instance.save if instance.respond_to?(:save) }
end
end

model.class_eval(&block) if block_given?

model
end
end