diff --git a/CHANGELOG.md b/CHANGELOG.md index f8cec42..e6e31b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change log +## 3.0.27 (2023-12-13) + +* Add format `mailbox` to `str` node for Schemacop3 schemas + ## 3.0.26 (2023-11-16) * Lock dependency `ruby2_keywords` to the more open `>= 0.0.4` diff --git a/README_V3.md b/README_V3.md index f80a33d..449a7fd 100644 --- a/README_V3.md +++ b/README_V3.md @@ -243,6 +243,11 @@ transformed into various types. Validates for a valid email address. There is no casting involved since email addresses do not have their own ruby type. +* `mailbox` + Validates for a valid mailbox, which is defined as a valid email enclosed in + brackets (`< >`), with an optional name before the email address. There is no + casting involved. + * `boolean` The string must be either `true`, `false`, `0` or `1`. This value will be casted to Ruby's `TrueClass` or `FalseClass`. Please note that the strings diff --git a/lib/schemacop.rb b/lib/schemacop.rb index deba600..28d8b2d 100644 --- a/lib/schemacop.rb +++ b/lib/schemacop.rb @@ -55,6 +55,12 @@ def self.register_string_formatter(name, pattern:, handler:) handler: ->(value) { value } ) + register_string_formatter( + :mailbox, + pattern: %r{^.*\s?<[a-zA-Z0-9.!\#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*>$}, + handler: ->(value) { value } + ) + register_string_formatter( :boolean, pattern: /^(true|false|0|1)$/i, diff --git a/test/unit/schemacop/v3/string_node_test.rb b/test/unit/schemacop/v3/string_node_test.rb index 3edff10..43bac85 100644 --- a/test/unit/schemacop/v3/string_node_test.rb +++ b/test/unit/schemacop/v3/string_node_test.rb @@ -191,6 +191,50 @@ def test_format_email assert_cast('john.doe@example.com', 'john.doe@example.com') end + def test_format_mailbox + schema :string, format: :mailbox + + assert_json(type: :string, format: :mailbox) + + assert_validation 'john.doe@example.com' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation 'john.doe+foo-bar_baz@example.com' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation 'JOHN.DOE+FOO-BAR_BAZ@EXAMPLE.COM' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation 'someemail' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation 'john doe@example.com' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation '@john@example.com' do + error '/', 'String does not match format "mailbox".' + end + + assert_validation 'John Doe ' + assert_validation 'John Doe ' + assert_validation 'John Doe ' + + assert_validation 'John ' + assert_validation 'John Doe 123 ' + assert_validation 'John_Doe ' + assert_validation 'John-Doe ÖÄ ' + assert_validation '"John Doe" ' + assert_validation '' + + assert_cast(nil, nil) + assert_cast('John Doe ', 'John Doe ') + end + def test_format_boolean schema :string, format: :boolean