statesman 13.1.0 → 13.2.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: f93bd968475f6cfd090311f9998a2350993df852aa3796fab5d3b52f962d6147
4
- data.tar.gz: 3789c10d55df44ee6e921f9d2297d7d0e0767f42521309ac14aed8e49a0986a8
3
+ metadata.gz: ffe7ee5f3aa4787fccd4c325c42bd892dc475edaaabc45a4a67155ebe41d41c1
4
+ data.tar.gz: 1794e00cf99c34e3d84a680f409a92d2430d0ed4964d3145f7f0539d7c54ec09
5
5
  SHA512:
6
- metadata.gz: 13b9e129ec5bb984066a05c408ee99c9965861775269bab232e6aac86ee75b5c5485a14ccc8476b3b96d0bc383cc68a1f67d32cf9d3eea575478e25ed0245d56
7
- data.tar.gz: d88507f263405847ea99f8a7cc88ec4e63c3a82addcef3a20e9c0e1c83372df38868278459702c0855e535d7ebca031e18ddaee32031b0beb162932963156325
6
+ metadata.gz: 7fc095f7cdfec543802c1e367af567d63e8abea8e57c01bc0b1fc1a6d661ea3b187e0d9ed91457c2eecf109286879ef7bd5bf45e3fa80a44777cb326486f9007
7
+ data.tar.gz: e3c342d10b68eccd5d4f145079c70537582f7923cf5cf7a9c0724fb58553476ca3d4e319c993929840e7ee2d2dbfedf1634e40160647429ea7cf194574275b79
@@ -25,12 +25,15 @@ jobs:
25
25
  strategy:
26
26
  fail-fast: false
27
27
  matrix:
28
- ruby-version: ["3.2", "3.3", "3.4", "3.5"]
28
+ ruby-version: ["3.3", "3.4", "4.0"]
29
29
  rails-version:
30
- - "7.1"
31
30
  - "7.2"
32
31
  - "8.0"
32
+ - "8.1"
33
33
  - "main"
34
+ exclude:
35
+ - ruby-version: "3.2"
36
+ rails-version: "main"
34
37
  runs-on: ubuntu-latest
35
38
  env:
36
39
  RAILS_VERSION: ${{ matrix.rails-version }}
@@ -49,13 +52,16 @@ jobs:
49
52
  strategy:
50
53
  fail-fast: false
51
54
  matrix:
52
- ruby-version: ["3.2", "3.3", "3.4", "3.5"]
55
+ ruby-version: ["3.3", "3.4", "4.0"]
53
56
  rails-version:
54
- - "7.1"
55
57
  - "7.2"
56
58
  - "8.0"
59
+ - "8.1"
57
60
  - "main"
58
61
  postgres-version: ["14", "15", "16", "17"]
62
+ exclude:
63
+ - ruby-version: "3.2"
64
+ rails-version: "main"
59
65
  runs-on: ubuntu-latest
60
66
  services:
61
67
  postgres:
@@ -90,13 +96,16 @@ jobs:
90
96
  strategy:
91
97
  fail-fast: false
92
98
  matrix:
93
- ruby-version: ["3.2", "3.3", "3.4", "3.5"]
99
+ ruby-version: ["3.3", "3.4", "4.0"]
94
100
  rails-version:
95
- - "7.1"
96
101
  - "7.2"
97
102
  - "8.0"
103
+ - "8.1"
98
104
  - "main"
99
105
  mysql-version: ["8.0", "8.4", "9.4"]
106
+ exclude:
107
+ - ruby-version: "3.2"
108
+ rails-version: "main"
100
109
 
101
110
  runs-on: ubuntu-latest
102
111
  services:
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ inherit_gem:
4
4
  gc_ruboconfig: rubocop.yml
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 3.2
7
+ TargetRubyVersion: 3.3
8
8
  NewCops: enable
9
9
 
10
10
  Metrics/AbcSize:
data/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## v13.2.0 29th July 2026
9
+
10
+ ### Added
11
+
12
+ - Expose the transitioning object on `GuardFailedError` via `#object` [#566](https://github.com/gocardless/statesman/pull/566)
13
+
8
14
  ## v13.1.0 9th October 2025
9
15
 
10
16
  ### Added
data/Gemfile CHANGED
@@ -14,17 +14,16 @@ end
14
14
 
15
15
  group :development, :test do
16
16
  gem "ammeter", "~> 1.1"
17
- gem "bundler", "~> 2"
18
- gem "gc_ruboconfig", "~> 5.0.0"
17
+ gem "gc_ruboconfig", "~> 6.0.0"
19
18
  gem "mysql2", ">= 0.4", "< 0.6"
20
19
  gem "pg", ">= 0.18", "<= 1.7"
21
20
  gem "pry"
22
- gem "rake", "~> 13.3.0"
21
+ gem "rake", "~> 13.4.1"
23
22
  gem "rspec", "~> 3.1"
24
23
  gem "rspec-github", "~> 3.0.0"
25
24
  gem "rspec-its", "~> 2.0"
26
25
  gem "rspec-rails", "~> 8.0"
27
- gem "sqlite3", "~> 2.7.3"
26
+ gem "sqlite3", "~> 2.9.0"
28
27
  gem "test-unit", "~> 3.3"
29
28
  gem "timecop", "~> 0.9.1"
30
29
  end
data/README.md CHANGED
@@ -539,6 +539,16 @@ Raised if:
539
539
 
540
540
  - A guard callback between `from` and `to` state returned a falsey value.
541
541
 
542
+ The model object that failed to transition is available via `object`:
543
+
544
+ ```ruby
545
+ begin
546
+ my_model.transition_to!(:some_state)
547
+ rescue Statesman::GuardFailedError => e
548
+ logger.error("Guard failed for #{e.object.class}##{e.object.id}: #{e.message}")
549
+ end
550
+ ```
551
+
542
552
  #### TransitionFailedError
543
553
 
544
554
  Raised if:
@@ -30,15 +30,16 @@ module Statesman
30
30
  end
31
31
 
32
32
  class GuardFailedError < StandardError
33
- def initialize(from, to, callback)
33
+ def initialize(from, to, callback, object = nil)
34
34
  @from = from
35
35
  @to = to
36
36
  @callback = callback
37
+ @object = object
37
38
  super(_message)
38
39
  set_backtrace(callback.source_location.join(":")) if callback&.source_location
39
40
  end
40
41
 
41
- attr_reader :from, :to, :callback
42
+ attr_reader :from, :to, :callback, :object
42
43
 
43
44
  private
44
45
 
@@ -5,8 +5,8 @@ require_relative "exceptions"
5
5
 
6
6
  module Statesman
7
7
  class Guard < Callback
8
- def call(*args)
9
- raise GuardFailedError.new(from, to, callback) unless super
8
+ def call(object = nil, last_transition = nil, metadata = nil)
9
+ raise GuardFailedError.new(from, to, callback, object) unless super
10
10
  end
11
11
  end
12
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Statesman
4
- VERSION = "13.1.0"
4
+ VERSION = "13.2.0"
5
5
  end
data/spec/spec_helper.rb CHANGED
@@ -28,7 +28,7 @@ RSpec.configure do |config|
28
28
  end
29
29
 
30
30
  if config.exclusion_filter[:active_record]
31
- puts "Skipping ActiveRecord tests"
31
+ warn "Skipping ActiveRecord tests"
32
32
  else
33
33
  current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
34
34
 
@@ -57,7 +57,7 @@ RSpec.configure do |config|
57
57
  ActiveRecord::Base.establish_connection(:primary)
58
58
 
59
59
  db_adapter = ActiveRecord::Base.connection.adapter_name
60
- puts "Running with database adapter '#{db_adapter}'"
60
+ warn "Running with database adapter '#{db_adapter}'"
61
61
 
62
62
  # Silence migration output
63
63
  ActiveRecord::Migration.verbose = false
@@ -84,15 +84,25 @@ describe "Exceptions" do
84
84
  is_expected.to eq([callback.source_location.join(":")])
85
85
  end
86
86
 
87
+ its(:object) { is_expected.to be_nil }
88
+
87
89
  its "string matches its message" do
88
90
  expect(error.to_s).to eq(error.message)
89
91
  end
92
+
93
+ context "when an object is passed" do
94
+ subject(:error) { Statesman::GuardFailedError.new("from", "to", callback, object) }
95
+
96
+ let(:object) { Object.new }
97
+
98
+ its(:object) { is_expected.to eq(object) }
99
+ end
90
100
  end
91
101
 
92
102
  describe "UnserializedMetadataError" do
93
103
  subject(:error) { Statesman::UnserializedMetadataError.new("foo") }
94
104
 
95
- its(:message) { is_expected.to match(/foo#metadata is not serialized/) }
105
+ its(:message) { is_expected.to include("foo#metadata is not serialized") }
96
106
 
97
107
  its "string matches its message" do
98
108
  expect(error.to_s).to eq(error.message)
@@ -102,7 +112,7 @@ describe "Exceptions" do
102
112
  describe "IncompatibleSerializationError" do
103
113
  subject(:error) { Statesman::IncompatibleSerializationError.new("foo") }
104
114
 
105
- its(:message) { is_expected.to match(/foo#metadata column type cannot be json/) }
115
+ its(:message) { is_expected.to include("foo#metadata column type cannot be json") }
106
116
 
107
117
  its "string matches its message" do
108
118
  expect(error.to_s).to eq(error.message)
@@ -10,15 +10,27 @@ describe Statesman::Guard do
10
10
  subject(:call) { guard.call }
11
11
 
12
12
  context "success" do
13
- let(:callback) { -> { true } }
13
+ let(:callback) { ->(*) { true } }
14
14
 
15
15
  specify { expect { call }.to_not raise_error }
16
16
  end
17
17
 
18
18
  context "error" do
19
- let(:callback) { -> { false } }
19
+ let(:callback) { ->(*) { false } }
20
20
 
21
21
  specify { expect { call }.to raise_error(Statesman::GuardFailedError) }
22
+
23
+ context "when called with an object" do
24
+ subject(:call) { guard.call(object) }
25
+
26
+ let(:object) { Object.new }
27
+
28
+ specify do
29
+ expect { call }.to raise_error(
30
+ an_instance_of(Statesman::GuardFailedError).and(having_attributes(object: object)),
31
+ )
32
+ end
33
+ end
22
34
  end
23
35
  end
24
36
  end
@@ -966,7 +966,7 @@ describe Statesman::Machine do
966
966
  expect { instance.transition_to!(:y) }.
967
967
  to raise_error(
968
968
  an_instance_of(Statesman::GuardFailedError).
969
- and(having_attributes(from: "x", to: ["y"])),
969
+ and(having_attributes(from: "x", to: ["y"], object: my_model)),
970
970
  )
971
971
  end
972
972
  end
data/statesman.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.required_ruby_version = ">= 3.2"
23
+ spec.required_ruby_version = ">= 3.3"
24
24
 
25
25
  spec.metadata = {
26
26
  "bug_tracker_uri" => "#{GITHUB_URL}/issues",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statesman
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.1.0
4
+ version: 13.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GoCardless
@@ -95,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
95
  requirements:
96
96
  - - ">="
97
97
  - !ruby/object:Gem::Version
98
- version: '3.2'
98
+ version: '3.3'
99
99
  required_rubygems_version: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="