decorator_dryer 0.1.1 → 0.1.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: fc5615f9000e21335ada498331dd1fe229958e961492c4cd2221190fafa7ffa6
4
- data.tar.gz: 288f3aace43467fad8b93afc54334101fbe669ab98992fdb00c86a7f978d05da
3
+ metadata.gz: b2b5ffec7f0a9d0ed8372f6a8ab3433a2daab3ea6fc1068ad79b1ba36061e990
4
+ data.tar.gz: 2cebca175fc5e36be748707c2bae014d20678df21d1d6add37762e58acfef3f8
5
5
  SHA512:
6
- metadata.gz: 55e39f52c71bf22f394ba9c2c8581c99b8cd741c1329340999e58f0d175d584e14881d306b2def6981d144f8ac1cb650d3e5c1a5ba9b4ca4c092a685adc711e8
7
- data.tar.gz: 1498d7d0e999640d81bee64c36920ee1727d4f297e8a5cfa31c25e02edc02c7a383d21bceba9d63d4657ed391a5e3bdca3f8d7b2b9df64ffdceda21afa442d80
6
+ metadata.gz: 769b19aedb2d3d7b617bbbd7b1bd473c5b371a8fb0afb520134c20b5af9b926d1130441e008697e4072ad5fb535bfca2392503215959c2ac194792f02f896c96
7
+ data.tar.gz: fc53714bc8a1c60a28adc349e5f2afe6d9989aeb9750b29271cb8da83980e3fb91e18c7741557f7ab4da5699fdeaff47380c22a93e19255061a72d42f4ccb4a3
data/README.md CHANGED
@@ -223,12 +223,79 @@ class PersonDecorator < Draper::Decorator
223
223
  end
224
224
  ```
225
225
 
226
+ ## Testing
227
+
228
+ ### RSpec Matchers
229
+
230
+ Decorator Dryer provides RSpec matchers to help you test your decorators. To use them, require the matchers in your `spec_helper.rb` or `rails_helper.rb`:
231
+
232
+ ```ruby
233
+ require 'decorator_dryer/rspec'
234
+ ```
235
+
236
+ The following matchers are available:
237
+
238
+ #### format_field_to_name
239
+
240
+ Verifies that a decorator defines a method to retrieve the name value from an association:
241
+
242
+ ```ruby
243
+ it { should format_field_to_name(:person) }
244
+ ```
245
+
246
+ #### format_field_to_datetime
247
+
248
+ Verifies that a decorator defines a datetime format method for a given attribute:
249
+
250
+ ```ruby
251
+ it { should format_field_to_datetime(:moment_of_birth) }
252
+ ```
253
+
254
+ #### format_field_to_time
255
+
256
+ Verifies that a decorator defines a time format method for a given attribute:
257
+
258
+ ```ruby
259
+ it { should format_field_to_time(:lunch_time) }
260
+ ```
261
+
262
+ #### format_field_to_date
263
+
264
+ Verifies that a decorator defines a date format method for a given attribute:
265
+
266
+ ```ruby
267
+ it { should format_field_to_date(:moment_of_birth) }
268
+ ```
269
+
270
+ #### format_field_to_precision_number
271
+
272
+ Verifies that a decorator defines a precision number format method for a given attribute:
273
+
274
+ ```ruby
275
+ it { should format_field_to_precision_number(:salary, 2) }
276
+ ```
277
+
278
+ #### delegate_field
279
+
280
+ Verifies that a decorator defines a method to delegate a given attribute to a given association:
281
+
282
+ ```ruby
283
+ it { should delegate_field(:job_title, :employee) }
284
+ ```
285
+
286
+ #### delegate_field_with_prefix
287
+
288
+ Verifies that a decorator defines a method to delegate a given attribute to a given association, using the association as the method prefix:
289
+
290
+ ```ruby
291
+ it { should delegate_field_with_prefix(:job_title, :employee) }
292
+ ```
293
+
226
294
  ## To Do
227
295
 
228
296
  * Enable formats to be overridden when calling shortcuts.
229
297
  * Add support for additional attachment libraries.
230
298
  * Add a more flexible replacement for the `to_name` shortcut.
231
- * Add test helpers.
232
299
  * Add a generator for the initialiser.
233
300
 
234
301
  ## Development
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DecoratorDryer
4
+ module RSpec
5
+ module Matchers
6
+ # Matcher to verify that a decorator defines a method to return the name attribute
7
+ # of a field.
8
+ #
9
+ # @example
10
+ # expect(user).to format_field_to_name(:role)
11
+ ::RSpec::Matchers.define :format_field_to_name do |field|
12
+ match do |subject|
13
+ subject.decorate.send("#{field}_name") == subject.send(field).try(:name)
14
+ end
15
+ description do
16
+ "format #{field} to display its name attribute"
17
+ end
18
+ failure_message do |subject|
19
+ "expected #{subject.class.name} decorator to format #{field} with a _name suffix method"
20
+ end
21
+ end
22
+
23
+ # Matcher to verify that a decorator formats a datetime field with format '%Y-%m-%d %H:%M'.
24
+ #
25
+ # @example
26
+ # expect(post).to format_field_to_datetime(:published_at)
27
+ ::RSpec::Matchers.define :format_field_to_datetime do |field|
28
+ match do |subject|
29
+ subject.decorate.send(field) == subject.send(field).try(:strftime, '%Y-%m-%d %H:%M')
30
+ end
31
+ description do
32
+ "format #{field} as a datetime with format '%Y-%m-%d %H:%M'"
33
+ end
34
+ failure_message do |subject|
35
+ "expected #{subject.class.name} decorator to format #{field} as '%Y-%m-%d %H:%M'"
36
+ end
37
+ end
38
+
39
+ # Matcher to verify that a decorator formats a date field with format '%Y-%m-%d'.
40
+ #
41
+ # @example
42
+ # expect(event).to format_field_to_date(:start_date)
43
+ ::RSpec::Matchers.define :format_field_to_date do |field|
44
+ match do |subject|
45
+ subject.decorate.send(field) == subject.send(field).try(:strftime, '%Y-%m-%d')
46
+ end
47
+ description do
48
+ "format #{field} as a date with format '%Y-%m-%d'"
49
+ end
50
+ failure_message do |subject|
51
+ "expected #{subject.class.name} decorator to format #{field} as '%Y-%m-%d'"
52
+ end
53
+ end
54
+
55
+ # Matcher to verify that a decorator formats a time field with format '%H:%M'.
56
+ #
57
+ # @example
58
+ # expect(schedule).to format_field_to_time(:start_time)
59
+ ::RSpec::Matchers.define :format_field_to_time do |field|
60
+ match do |subject|
61
+ subject.decorate.send(field) == subject.send(field).try(:strftime, '%H:%M')
62
+ end
63
+ description do
64
+ "format #{field} as a time with format '%H:%M'"
65
+ end
66
+ failure_message do |subject|
67
+ "expected #{subject.class.name} decorator to format #{field} as '%H:%M'"
68
+ end
69
+ end
70
+
71
+ # Matcher to verify that a decorator formats a number field with a specific precision.
72
+ #
73
+ # @example
74
+ # expect(product).to format_field_to_precision_number(:price, 2)
75
+ ::RSpec::Matchers.define :format_field_to_precision_number do |field, precision|
76
+ match do |subject|
77
+ subject.decorate.send(field) == number_with_precision(subject.send(field), precision: precision)
78
+ end
79
+ description do
80
+ "format #{field} as a number with precision #{precision}"
81
+ end
82
+ failure_message do |subject|
83
+ "expected #{subject.class.name} decorator to format #{field} with precision #{precision}"
84
+ end
85
+ end
86
+
87
+ # Matcher to verify that a decorator delegates a field to an associated object.
88
+ #
89
+ # @example
90
+ # expect(order).to delegate_field(:email, :customer)
91
+ ::RSpec::Matchers.define :delegate_field do |field, association|
92
+ match do |subject|
93
+ subject.decorate.send(field) == subject.send(association).decorate.send(field)
94
+ end
95
+ description do
96
+ "delegate #{field} to #{association}"
97
+ end
98
+ failure_message do |subject|
99
+ "expected #{subject.class.name} to delegate #{field} to #{association}"
100
+ end
101
+ end
102
+
103
+ # Matcher to verify that a decorator delegates a field to an associated object with
104
+ # a prefix based on the association name.
105
+ #
106
+ # @example
107
+ # expect(order).to delegate_field_with_prefix(:email, :customer)
108
+ ::RSpec::Matchers.define :delegate_field_with_prefix do |field, association|
109
+ match do |subject|
110
+ subject.decorate.send("#{association}_#{field}") ==
111
+ subject.send(association).decorate.send(field)
112
+ end
113
+ description do
114
+ "delegate #{field} to #{association} with prefix"
115
+ end
116
+ failure_message do |subject|
117
+ "expected #{subject.class.name} to delegate #{field} to #{association}"
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ # Auto-include matchers when RSpec is loaded
125
+ ::RSpec.configure { |config| config.include DecoratorDryer::RSpec::Matchers }
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/core"
4
+ require_relative "rspec/matchers"
5
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DecoratorDryer
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decorator_dryer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Harbison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-25 00:00:00.000000000 Z
11
+ date: 2026-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -76,6 +76,8 @@ files:
76
76
  - lib/decorator_dryer/active_storage_shortcuts.rb
77
77
  - lib/decorator_dryer/configuration.rb
78
78
  - lib/decorator_dryer/formatters.rb
79
+ - lib/decorator_dryer/rspec.rb
80
+ - lib/decorator_dryer/rspec/matchers.rb
79
81
  - lib/decorator_dryer/shortcuts.rb
80
82
  - lib/decorator_dryer/version.rb
81
83
  - sig/decorator_dryer.rbs