rrx_dev 8.0.2 → 8.0.3

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: 41a698133f5c37c62dc20f8a9d9f85d83679d08014685c82e35726d87bf7fe7e
4
- data.tar.gz: 2476886a4f224620d9ed9e3da10a5fda9b54e691572a7a16c716e412a30c4b53
3
+ metadata.gz: 1f3a039f5ed32d3aa0775a52aea95494f21a7e6427a96363c2ee223f6012ed0c
4
+ data.tar.gz: a5bb1c050d86ea3219d4f3147d170a51a5924607f12df01ba5ce0ed079212320
5
5
  SHA512:
6
- metadata.gz: bf5e9605d06672c5be03c47ed79bf0d30356ee2b50d31af7d64a5250661d3fb14935df669f4f48e3ed07896e21facb76eb19230f1da39b48e37e8f021d8ef27b
7
- data.tar.gz: 66140f82fc51f825e394a015cbdd8483573c71fe6c17d42b696edd1e0d30ad8c561d09a7144090f2bb4eb64cc1f3780e41f21b24c2538d4be86ca8268a98e0f5
6
+ metadata.gz: 75901172924ee1489ee1d0706c430e93cd8de78ffb763991b2342945c3baf4835fde836fea11aaa1aa43af4d204921c114825c2bd8cefec97b83d20eec1f8ca4
7
+ data.tar.gz: 9101eb0180a20be2f40fd64d4c8414e89b98045461dc70feca2b7447161f12bfe067c9b8522f488487a428eaca1b746804477575affa92c682fde70624cd5866
data/Gemfile.lock CHANGED
@@ -112,7 +112,7 @@ GEM
112
112
  nokogiri (>= 1.12.0)
113
113
  minitest (5.25.5)
114
114
  msgpack (1.7.2)
115
- nokogiri (1.16.0-x86_64-linux)
115
+ nokogiri (1.19.1-x86_64-linux-gnu)
116
116
  racc (~> 1.4)
117
117
  parallel (1.24.0)
118
118
  parser (3.2.2.4)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Shared context: auth_helpers
4
+ # Provides test authentication helpers for request specs.
5
+ #
6
+ # Usage:
7
+ # RSpec.describe 'Posts', type: :request do
8
+ # include_context :auth_helpers
9
+ # authenticated!
10
+ #
11
+ # it 'returns posts' do
12
+ # get '/posts', headers: request_headers
13
+ # expect(response).to be_successful
14
+ # end
15
+ # end
16
+ #
17
+ # By default +authenticated!+ sets +X-Test-User-Id+ from the +user+ let.
18
+ # Pass a different let name if needed:
19
+ # authenticated! user_let: :admin_user
20
+ RSpec.shared_context :auth_helpers do
21
+ let(:auth_headers) { {} }
22
+ let(:request_headers) { {}.merge!(auth_headers) }
23
+
24
+ def self.authenticated!(user_let: :user)
25
+ before do
26
+ auth_headers['X-Test-User-Id'] = send(user_let).id
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,7 @@
1
1
  require 'active_support/testing/assertions'
2
2
  require 'rspec/parameterized'
3
+ require_relative 'matchers'
4
+ require_relative 'auth_helpers'
3
5
 
4
6
  module Global
5
7
  def self.included(other)
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Shared context: error_matcher
4
+ # Provides a +verify+ matcher for asserting ActiveModel validation errors.
5
+ #
6
+ # Usage:
7
+ # include_context :error_matcher
8
+ # it { is_expected.to verify(:name).present }
9
+ RSpec.shared_context :error_matcher do
10
+ matcher :verify do |attribute|
11
+ match do |actual|
12
+ @actual = actual
13
+ @attribute = attribute
14
+ actual.validate
15
+ if @message
16
+ errors.include?(@message)
17
+ else
18
+ errors.any?
19
+ end
20
+ end
21
+
22
+ def errors
23
+ @errors ||= @actual.errors.errors
24
+ .select { |err| err.attribute == @attribute }
25
+ .map(&:type)
26
+ end
27
+
28
+ description do
29
+ desc = if @message
30
+ "have error :#{@message} on :#{@attribute}"
31
+ else
32
+ "have any error on :#{@attribute}"
33
+ end
34
+
35
+ if errors.present?
36
+ desc << " (errors: #{errors.join(', ')})"
37
+ else
38
+ desc << '. No errors were found.'
39
+ end
40
+
41
+ desc
42
+ end
43
+
44
+ chain :positive do
45
+ @message = :greater_than_or_equal_to
46
+ end
47
+
48
+ chain :numeric do
49
+ @message = :not_a_number
50
+ end
51
+
52
+ chain :present do
53
+ @message = :blank
54
+ end
55
+
56
+ chain :absent do
57
+ @message = :absent
58
+ end
59
+
60
+ chain :with_message do |message|
61
+ @message = message
62
+ end
63
+ end
64
+ end
65
+
66
+ # Shared context: model_matchers
67
+ # Provides helpers for comparing ActiveRecord model instances against response hashes.
68
+ #
69
+ # Usage:
70
+ # include_context :model_matchers
71
+ # it { expect(json_response).to match_model_hash(user) }
72
+ RSpec.shared_context :model_matchers do
73
+ class ModelMatcherResult
74
+ DIFFER = RSpec::Support::Differ.new(color: true) unless defined?(DIFFER)
75
+
76
+ attr_reader :expected, :actual, :matches, :index
77
+
78
+ def initialize(expected, actual, matcher, index = nil)
79
+ @expected = expected
80
+ @actual = actual
81
+ @matches = matcher.call(**expected).matches?(actual)
82
+ @index = index
83
+ end
84
+
85
+ def match? = matches
86
+ def failed? = !matches
87
+
88
+ def diff
89
+ DIFFER.diff(actual, expected).strip
90
+ end
91
+
92
+ def to_s
93
+ if index.nil?
94
+ "Expected result to match: #{diff}"
95
+ else
96
+ "Expected result #{index} to match:#{diff}"
97
+ end
98
+ end
99
+ end
100
+
101
+ matcher :model_matcher do |matcher, model, attrs, extra, extra_block = nil|
102
+ match do |actual|
103
+ matcher_method = matcher.is_a?(Symbol) ? method(matcher) : matcher
104
+
105
+ if model.is_a?(Array)
106
+ @results = model.length.times.map do |i|
107
+ a = actual[i]
108
+ ModelMatcherResult.new(
109
+ expected_attributes(model[i], attrs, extra, extra_block, a),
110
+ a,
111
+ matcher_method,
112
+ i
113
+ )
114
+ end
115
+ @results.all?(&:match?)
116
+ else
117
+ @result = ModelMatcherResult.new(
118
+ expected_attributes(model, attrs, extra, extra_block, actual),
119
+ actual,
120
+ matcher_method
121
+ )
122
+ @result.match?
123
+ end
124
+ end
125
+
126
+ failure_message do |_actual|
127
+ if @results
128
+ @results.select(&:failed?).join("\n")
129
+ else
130
+ @result.to_s
131
+ end
132
+ end
133
+ end
134
+
135
+ # @param attrs [Array<Symbol>, nil] limit comparison to these attributes (all if nil)
136
+ def expected_attributes(model, attrs, extra, extra_block, actual)
137
+ include_type = attrs.blank? || attrs.delete(:type)
138
+
139
+ expected = (attrs.blank? ? model.attributes : model.slice(*attrs)).deep_symbolize_keys
140
+ expected.merge!(extra) if extra
141
+ expected.merge!(extra_block.call(model)) if extra_block
142
+ expected[:type] ||= model.class.name.underscore if include_type
143
+
144
+ if actual.is_a?(Hash)
145
+ expected.transform_values! do |v|
146
+ v.respond_to?(:iso8601) ? v.as_json : v
147
+ end
148
+ end
149
+
150
+ expected
151
+ end
152
+
153
+ def match_model(model, attrs = nil, **extra, &extra_block)
154
+ model_matcher(:have_attributes, model, attrs, extra, extra_block)
155
+ end
156
+
157
+ def match_model_hash(model, attrs = nil, **extra, &extra_block)
158
+ model_matcher(:match, model, attrs, extra, extra_block)
159
+ end
160
+
161
+ def include_model_hash(model, attrs = nil, **extra, &extra_block)
162
+ model_matcher(:include, model, attrs, extra, extra_block)
163
+ end
164
+
165
+ alias match_models match_model
166
+ alias match_models_hashes match_model_hash
167
+ alias include_model_hashes include_model_hash
168
+ end
@@ -27,7 +27,9 @@ def init_rrx_spec_rails!
27
27
  end
28
28
  end
29
29
 
30
- Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
30
+ # Use spec_dir (the caller's spec/ directory) instead of Rails.root,
31
+ # because Rails.root resolves to spec/dummy which is inside spec/.
32
+ Dir[spec_dir.join('support/**/*.rb')].sort.each { |f| require f }
31
33
  end
32
34
 
33
35
  init_rrx_spec_rails!
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RrxDev
4
- VERSION = '8.0.2'
4
+ VERSION = '8.0.3'
5
5
  RAILS_VERSION = "~> #{VERSION}"
6
6
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrx_dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.2
4
+ version: 8.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Drew
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-11-17 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: active_record_query_trace
@@ -30,14 +29,14 @@ dependencies:
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: 8.0.2
32
+ version: 8.0.3
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: 8.0.2
39
+ version: 8.0.3
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: bootsnap
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +113,14 @@ dependencies:
114
113
  requirements:
115
114
  - - "~>"
116
115
  - !ruby/object:Gem::Version
117
- version: 8.0.2
116
+ version: 8.0.3
118
117
  type: :runtime
119
118
  prerelease: false
120
119
  version_requirements: !ruby/object:Gem::Requirement
121
120
  requirements:
122
121
  - - "~>"
123
122
  - !ruby/object:Gem::Version
124
- version: 8.0.2
123
+ version: 8.0.3
125
124
  - !ruby/object:Gem::Dependency
126
125
  name: rake
127
126
  requirement: !ruby/object:Gem::Requirement
@@ -262,7 +261,6 @@ dependencies:
262
261
  - - ">="
263
262
  - !ruby/object:Gem::Version
264
263
  version: '0'
265
- description:
266
264
  email:
267
265
  - dan.drew@hotmail.com
268
266
  executables: []
@@ -299,8 +297,10 @@ files:
299
297
  - lib/rrx_dev.rb
300
298
  - lib/rrx_dev/rswag.rb
301
299
  - lib/rrx_dev/spec.rb
300
+ - lib/rrx_dev/spec/auth_helpers.rb
302
301
  - lib/rrx_dev/spec/factory_bot.rb
303
302
  - lib/rrx_dev/spec/global.rb
303
+ - lib/rrx_dev/spec/matchers.rb
304
304
  - lib/rrx_dev/spec/rails.rb
305
305
  - lib/rrx_dev/spec/rswag.rb
306
306
  - lib/rrx_dev/version.rb
@@ -331,8 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
331
331
  - !ruby/object:Gem::Version
332
332
  version: '0'
333
333
  requirements: []
334
- rubygems_version: 3.4.19
335
- signing_key:
334
+ rubygems_version: 3.6.7
336
335
  specification_version: 4
337
336
  summary: Ruby on Rails core development support
338
337
  test_files: []