coercive 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3eee84a8970b92e6b5d1b0e01e51a40c66cc0c7298b0fe37a6ea44aecd7b9064
4
- data.tar.gz: 9504d35e8ce6376fd821110a15d079783f723af1ae78606fa7fd2e565c053487
3
+ metadata.gz: 7ffc4474a94a2f1e246925e54549fdbf360fdc272ebdb670a99152b7ec6418b9
4
+ data.tar.gz: 92bdc78e8286dce0ce88464b843777f3c7b60bbb864a4c3daca3e3b80a9d6c8c
5
5
  SHA512:
6
- metadata.gz: 41fef05cb7a8c6a1d2f9b7f0f3737d76c5756a36903d6e2c45d028fb539d4de50f9ac0720b07e4262b97df2ff187638e0cf6d5fef4692d470ddc9484e00a9b57
7
- data.tar.gz: 94c3e1e38e740c7089d8913977fbd1feea04d1df592d918c76b46be18c53787c95d36fed451a39191781db63718a941f31d53b4ac56d960384e1e854ed4d6066
6
+ metadata.gz: 7a41ea8301735ce0b45d4c6d2e96a9e8c0bb06399c8b4f47be1f115d8996c640714a36e7211d4abc73e5ca40944f9be387b31eed0e9c8b22f7e859f10bd59480
7
+ data.tar.gz: e9f73c7c476d50e49bfbc7433d3b9da14541999a92582462e5ca1042ef80743a748ce83af2eb418ffb54ec393d4196cba1a49f5f5008aa4c20907918af915e7d
data/README.md CHANGED
@@ -128,6 +128,30 @@ CoerceFoo.call("foo" => "DEADBEEF")
128
128
  # => {"foo"=>"DEADBEEF"}
129
129
  ```
130
130
 
131
+ ### `date` and `datetime`
132
+
133
+ The `date` and `datetime` coercion functions will receive a `String` and give you `Date` and `DateTime` objects, respectively.
134
+
135
+ By default they expect an ISO 8601 string, but they provide a `format` option in case you need to parse something different, following the `strftime` format.
136
+
137
+ ```ruby
138
+ module CoerceFoo
139
+ extend Coercive
140
+
141
+ attribute :date_foo, date, optional
142
+ attribute :american_date, date(format: "%m-%d-%Y"), optional
143
+ attribute :datetime_foo, datetime, optional
144
+ end
145
+
146
+ CoerceFoo.call("date_foo" => "1988-05-18", "datetime_foo" => "1988-05-18T21:00:00Z", "american_date" => "05-18-1988")
147
+ # => {"date_foo"=>#<Date: 1988-05-18 ((2447300j,0s,0n),+0s,2299161j)>,
148
+ # "american_date"=>#<Date: 1988-05-18 ((2447300j,0s,0n),+0s,2299161j)>,
149
+ # "datetime_foo"=>#<DateTime: 1988-05-18T21:00:00+00:00 ((2447300j,75600s,0n),+0s,2299161j)>}
150
+
151
+ CoerceFoo.call("date_foo" => "18th May 1988")
152
+ # => Coercive::Error: {"date_foo"=>"not_valid"}
153
+ ```
154
+
131
155
  ### `any`
132
156
 
133
157
  The `any` coercion function lets anything pass through. It's commonly used with the `optional` fetch function when an attribute may or many not be a part of the input.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "coercive"
3
- s.version = "1.1.0"
3
+ s.version = "1.2.0"
4
4
  s.summary = "Coercive is a library to validate and coerce user input"
5
5
  s.description = s.summary
6
6
  s.authors = ["Joe McIlvain", "Lucas Tolchinsky"]
@@ -1,3 +1,4 @@
1
+ require "date"
1
2
  require_relative "coercive/uri"
2
3
 
3
4
  # Public: The Coercive module implements a succinct DSL for declaring callable
@@ -192,6 +193,48 @@ module Coercive
192
193
  end
193
194
  end
194
195
 
196
+ # Public DSL: Return a coercion function to coerce input into a Date.
197
+ # Used when declaring an attribute. See documentation for attr_coerce_fns.
198
+ #
199
+ # format - String following Ruby's `strftime` format to change the parsing behavior. When empty
200
+ # it will expect the String to be ISO 8601 compatible.
201
+ def date(format: nil)
202
+ ->(input) do
203
+ input = begin
204
+ if format
205
+ Date.strptime(input, format)
206
+ else
207
+ Date.iso8601(input)
208
+ end
209
+ rescue ArgumentError
210
+ fail Coercive::Error.new("not_valid")
211
+ end
212
+
213
+ input
214
+ end
215
+ end
216
+
217
+ # Public DSL: Return a coercion function to coerce input into a DateTime.
218
+ # Used when declaring an attribute. See documentation for attr_coerce_fns.
219
+ #
220
+ # format - String following Ruby's `strftime` format to change the parsing behavior. When empty
221
+ # it will expect the String to be ISO 8601 compatible.
222
+ def datetime(format: nil)
223
+ ->(input) do
224
+ input = begin
225
+ if format
226
+ DateTime.strptime(input, format)
227
+ else
228
+ DateTime.iso8601(input)
229
+ end
230
+ rescue ArgumentError
231
+ fail Coercive::Error.new("not_valid")
232
+ end
233
+
234
+ input
235
+ end
236
+ end
237
+
195
238
  # Public DSL: Return a coercion function to coerce input to an Array.
196
239
  # Used when declaring an attribute. See documentation for attr_coerce_fns.
197
240
  #
@@ -199,6 +199,84 @@ describe "Coercive" do
199
199
  end
200
200
  end
201
201
 
202
+ describe "date" do
203
+ before do
204
+ @coercion = Module.new do
205
+ extend Coercive
206
+
207
+ attribute :date, date, optional
208
+ attribute :american_date, date(format: "%m-%d-%Y"), optional
209
+ end
210
+ end
211
+
212
+ it "coerces a string into a Date object with ISO 8601 format by default" do
213
+ attributes = { "date" => "1988-05-18" }
214
+
215
+ expected = { "date" => Date.new(1988, 5, 18) }
216
+
217
+ assert_equal expected, @coercion.call(attributes)
218
+ end
219
+
220
+ it "supports a custom date format" do
221
+ attributes = { "american_date" => "05-18-1988" }
222
+
223
+ expected = { "american_date" => Date.new(1988, 5, 18) }
224
+
225
+ assert_equal expected, @coercion.call(attributes)
226
+ end
227
+
228
+ it "errors if the input doesn't parse" do
229
+ attributes = { "date" => "12-31-1990" }
230
+
231
+ expected_errors = { "date" => "not_valid" }
232
+
233
+ assert_coercion_error(expected_errors) { @coercion.call(attributes) }
234
+ end
235
+ end
236
+
237
+ describe "datetime" do
238
+ before do
239
+ @coercion = Module.new do
240
+ extend Coercive
241
+
242
+ attribute :datetime, datetime, optional
243
+ attribute :american_date, datetime(format: "%m-%d-%Y %I:%M:%S %p"), optional
244
+ end
245
+ end
246
+
247
+ it "coerces a string into a DateTime object with ISO 8601 format by default" do
248
+ attributes = { "datetime" => "1988-05-18T21:00:00Z" }
249
+
250
+ expected = { "datetime" => DateTime.new(1988, 5, 18, 21, 00, 00) }
251
+
252
+ assert_equal expected, @coercion.call(attributes)
253
+ end
254
+
255
+ it "honors the timezone" do
256
+ attributes = { "datetime" => "1988-05-18T21:00:00-0300" }
257
+
258
+ expected = { "datetime" => DateTime.new(1988, 5, 18, 21, 00, 00, "-03:00") }
259
+
260
+ assert_equal expected, @coercion.call(attributes)
261
+ end
262
+
263
+ it "supports a custom date format" do
264
+ attributes = { "american_date" => "05-18-1988 09:00:00 PM" }
265
+
266
+ expected = { "american_date" => DateTime.new(1988, 5, 18, 21, 00, 00) }
267
+
268
+ assert_equal expected, @coercion.call(attributes)
269
+ end
270
+
271
+ it "errors if the input doesn't parse" do
272
+ attributes = { "datetime" => "12-31-1990T21:00:00Z" }
273
+
274
+ expected_errors = { "datetime" => "not_valid" }
275
+
276
+ assert_coercion_error(expected_errors) { @coercion.call(attributes) }
277
+ end
278
+ end
279
+
202
280
  describe "array" do
203
281
  before do
204
282
  @coercion = Module.new do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coercive
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe McIlvain
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-08-13 00:00:00.000000000 Z
12
+ date: 2020-08-31 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Coercive is a library to validate and coerce user input
15
15
  email: