formalism-r18n_errors 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dcf5355aaae24c4d6f11fab3b1e12db6bfaf22787e796e86c04b1d55aba23a81
4
+ data.tar.gz: 6c1d095c383a63a90199be313376fec2aa181fe22ea3a740d37d69d23e20807d
5
+ SHA512:
6
+ metadata.gz: 53838438aef5b7d043e828d45b6bd80ef9635aab86d9428afbccb13fb1d2e1d7f8bce096cf50fe818147d741c05f2f9574b25cb68ffe845283ac2c494a8a3e79
7
+ data.tar.gz: 12bd780ec37f522802138712980c2e2b93da72ed5ae604dd0d98803832105c56a273dd09744e5378b4b94c3d4f4c4d25cfc45f498abcd0882e4726ccf63dfa18
data/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ ## master (unreleased)
4
+
5
+ ## 0.2.0 (2020-09-24)
6
+
7
+ ## 0.1.3 (2020-09-23)
8
+
9
+ * Add specs for anything, especially for `ValidationHelpers`.
10
+ Make code coverage 100%.
11
+ * Add documentation about `ValidationHelpers`.
12
+
13
+ ## 0.1.2 (2020-09-22)
14
+
15
+ * Require `gorilla_patch/blank` before its usage.
16
+
17
+ ## 0.1.1 (2020-09-22)
18
+
19
+ * Fix the issue with unknown `Forwardable` constant.
20
+
21
+ ## 0.1.0 (2020-07-10)
22
+
23
+ * Initial release.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Alexander Popov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # Formalism R18n Errors
2
+
3
+ [![Cirrus CI - Base Branch Build Status](https://img.shields.io/cirrus/github/AlexWayfer/formalism-r18n_errors?style=flat-square)](https://cirrus-ci.com/github/AlexWayfer/formalism-r18n_errors)
4
+ [![Codecov branch](https://img.shields.io/codecov/c/github/AlexWayfer/formalism-r18n_errors/master.svg?style=flat-square)](https://codecov.io/gh/AlexWayfer/formalism-r18n_errors)
5
+ [![Code Climate](https://img.shields.io/codeclimate/maintainability/AlexWayfer/formalism-r18n_errors.svg?style=flat-square)](https://codeclimate.com/github/AlexWayfer/formalism-r18n_errors)
6
+ [![Depfu](https://img.shields.io/depfu/AlexWayfer/benchmark_toys?style=flat-square)](https://depfu.com/repos/github/AlexWayfer/formalism-r18n_errors)
7
+ [![Inline docs](https://inch-ci.org/github/AlexWayfer/formalism-r18n_errors.svg?branch=master)](https://inch-ci.org/github/AlexWayfer/formalism-r18n_errors)
8
+ [![license](https://img.shields.io/github/license/AlexWayfer/formalism-r18n_errors.svg?style=flat-square)](LICENSE.txt)
9
+ [![Gem](https://img.shields.io/gem/v/formalism-r18n_errors.svg?style=flat-square)](https://rubygems.org/gems/formalism-r18n_errors)
10
+
11
+ Errors for [Formalism](https://github.com/AlexWayfer/formalism)
12
+ via [R18n](https://github.com/r18n/r18n).
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'formalism-r18n_errors'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ ```shell
25
+ bundle install
26
+ ```
27
+
28
+ Or install it yourself as:
29
+
30
+ ```shell
31
+ gem install formalism-r18n_errors
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```ruby
37
+ require 'formalism/r18n_errors'
38
+
39
+ module MyProject
40
+ module Forms
41
+ class Base < Formalism::Form
42
+ include Formalism::R18nErrors
43
+
44
+ def initialize(*)
45
+ ## This is an example, but some value is required
46
+ @errors_key = self.class.name.split('::')[2].underscore.to_sym
47
+
48
+ super
49
+ end
50
+ end
51
+
52
+ class GeoLocation < Base
53
+ field :address
54
+ end
55
+
56
+ class User < Base
57
+ field :name, String
58
+
59
+ ## `:errors_key` can be changed for nested forms
60
+ nested :location, GeoLocation, errors_key: :geolocation
61
+
62
+ private
63
+
64
+ def validate
65
+ ## `add_error` is the alias for `errors.add errors_key, *` (`:user` in this case)
66
+ add_error :name, :is_empty if name.to_s.empty?
67
+ end
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ ### Validation Helpers
74
+
75
+ ```ruby
76
+ require 'formalism/r18n_errors/validation_helpers'
77
+
78
+ module MyProject
79
+ module Forms
80
+ class Base < Formalism::Form
81
+ include Formalism::R18nErrors
82
+ include Formalism::R18nErrors::ValidationHelpers
83
+
84
+ # ...
85
+ end
86
+
87
+ class User < Base
88
+ field :name, String
89
+ field :country
90
+ field :city
91
+ field :score, Float
92
+ field :email, String
93
+
94
+ nested :location, GeoLocation
95
+
96
+ private
97
+
98
+ def validate
99
+ ## `errors.user.name.not_entered`
100
+ validate_entry :name
101
+
102
+ ## `errors.user.country.not_chosen`
103
+ ## `errors.user.city.not_chosen`
104
+ validate_choice %i[country city]
105
+
106
+ ## `errors.user.location.not_provided`
107
+ validate_provision :location
108
+
109
+ ## `errors.user.name.greater_than(20)`
110
+ validate_max_length :name, 20
111
+
112
+ ## `errors.user.name.less_than(3)`
113
+ validate_min_length :name, 3
114
+
115
+ ## `errors.user.score.greater_than(5)`
116
+ ## or
117
+ ## `errors.user.score.less_than(1)`
118
+ validate_range_entry :score, 1..5
119
+
120
+ ## Requires `email_address` gem
121
+ ## `errors.user.email.not_valid_email`
122
+ validate_email :email
123
+
124
+ ## Requires `formalism-model_form` gem
125
+ ## `errors.user.email.already_taken`
126
+ validate_uniqueness :email
127
+ ## `errors.user.itself.already_exists.country_and_city`
128
+ validate_uniqueness %i[country city]
129
+ end
130
+ end
131
+ end
132
+ end
133
+ ```
134
+
135
+ ## Development
136
+
137
+ After checking out the repo, run `bundle install` to install dependencies.
138
+
139
+ Then, run `toys rspec` to run the tests.
140
+
141
+ To install this gem onto your local machine, run `toys gem install`.
142
+
143
+ To release a new version, run `toys gem release %version%`.
144
+ See how it works [here](https://github.com/AlexWayfer/gem_toys#release).
145
+
146
+ ## Contributing
147
+
148
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/AlexWayfer/formalism-r18n_errors).
149
+
150
+ ## License
151
+
152
+ The gem is available as open source under the terms of the
153
+ [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'formalism'
4
+
5
+ require_relative 'r18n_errors/version'
6
+ require_relative 'r18n_errors/errors'
7
+
8
+ module Formalism
9
+ ## Main module which should be included into base form
10
+ module R18nErrors
11
+ def initialize(*)
12
+ ## `@errors_key` should be set in using form
13
+ @errors = Errors.new
14
+
15
+ super
16
+ end
17
+
18
+ protected
19
+
20
+ attr_accessor :errors_key
21
+ attr_reader :errors
22
+
23
+ private
24
+
25
+ def initialize_nested_form(name, options)
26
+ return unless (form = super)
27
+
28
+ form.errors_key = options.fetch(:errors_key, name)
29
+ form
30
+ end
31
+
32
+ def add_error(*args, **kwargs)
33
+ raise '`@errors_key` is required' unless errors_key
34
+
35
+ errors.add errors_key, *args, **kwargs
36
+ end
37
+
38
+ def merge_errors_of_nested_form(name, nested_form)
39
+ add_error name, nested_errors: nested_form.errors
40
+ end
41
+
42
+ def nested_form_to_params(_name_of_nested_form, nested_form)
43
+ return super if nested_form.errors_key
44
+
45
+ nested_form.to_params
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'r18n-core'
5
+
6
+ module Formalism
7
+ module R18nErrors
8
+ ## Class for errors collection
9
+ class Errors
10
+ extend Forwardable
11
+
12
+ def_delegators :@hash, :any?, :empty?, :clear, :to_json
13
+
14
+ include R18n::Helpers
15
+
16
+ ## class for translation hash creation
17
+ class ErrorTranslator
18
+ def initialize(translations, form_errors)
19
+ @translations = translations
20
+ @form_errors = form_errors
21
+ @result = Hash.new { |hsh, key| hsh[key] = Hash.new(&hsh.default_proc) }
22
+ end
23
+
24
+ def translate(prefixes)
25
+ @form_errors.each do |model_key, errors|
26
+ errors.each do |error|
27
+ if error[:rest_keys]
28
+ insert_translation_in_result(error, model_key, prefixes)
29
+ else
30
+ merge_nested_translations_with_result(error, prefixes)
31
+ end
32
+ end
33
+ end
34
+ @result
35
+ end
36
+
37
+ private
38
+
39
+ def insert_translation_in_result(error, model_key, prefixes)
40
+ translation_keys = error[:rest_keys][0..-2].unshift(model_key)
41
+ edge_key = error[:rest_keys].last
42
+ args = error[:translation_args]
43
+
44
+ @result.dig(*translation_keys)[edge_key] =
45
+ @translations.dig(*prefixes + translation_keys)[edge_key, args]
46
+ end
47
+
48
+ def merge_nested_translations_with_result(error, prefixes)
49
+ nested_hash = error[:nested_errors].translations_hash(*prefixes)
50
+ nested_hash = nested_hash[nil] while nested_hash.key?(nil)
51
+ @result.merge! nested_hash
52
+ end
53
+ end
54
+
55
+ private_constant :ErrorTranslator
56
+
57
+ def initialize
58
+ @hash = Hash.new do |hash, model|
59
+ hash[model] = Hash.new do |model_hash, field|
60
+ model_hash[field] = []
61
+ end
62
+ end
63
+ end
64
+
65
+ def add(model_key, field_key, *rest_keys, args: nil, nested_errors: nil)
66
+ @hash[model_key][field_key].push(
67
+ if nested_errors
68
+ { nested_errors: nested_errors }
69
+ else
70
+ { rest_keys: rest_keys, translation_args: args }
71
+ end
72
+ )
73
+ end
74
+
75
+ def translations(*prefixes)
76
+ @hash.flat_map do |model_key, field_hash|
77
+ field_hash.flat_map do |field_key, errors_array|
78
+ errors_array.flat_map do |error|
79
+ translate prefixes, model_key, field_key, error
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ def translations_hash(*prefixes)
86
+ prefixes.push(@hash.keys.first) if @hash.keys.first
87
+ @hash.transform_values do |errors|
88
+ ErrorTranslator.new(t.error, errors).translate(prefixes)
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def translate(prefixes, model_key, field_key, error)
95
+ if (nested_errors = error[:nested_errors])
96
+ return nested_errors.translations(*prefixes, model_key)
97
+ end
98
+
99
+ rest_keys = error.fetch(:rest_keys)
100
+ t.error
101
+ .dig(*[*prefixes, model_key, field_key].compact, *rest_keys[0..-2])
102
+ .public_send(rest_keys.last, error[:translation_args])
103
+ end
104
+ end
105
+
106
+ private_constant :Errors
107
+ end
108
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gorilla_patch/blank'
4
+
5
+ module Formalism
6
+ module R18nErrors
7
+ ## Helper methods for validations
8
+ module ValidationHelpers
9
+ private
10
+
11
+ using GorillaPatch::Blank
12
+
13
+ def validate_provision(*validation_fields, error_key: :not_provided)
14
+ valid = true
15
+ validation_fields.flatten.each do |validation_field|
16
+ next unless field_changed?(validation_field)
17
+ next if field_valid?(validation_field)
18
+
19
+ valid = false
20
+ add_error validation_field, error_key
21
+ end
22
+ valid
23
+ end
24
+
25
+ def validate_entry(*validation_fields)
26
+ validate_provision(*validation_fields, error_key: :not_entered)
27
+ end
28
+
29
+ def validate_choice(*validation_fields)
30
+ validate_provision(*validation_fields, error_key: :not_chosen)
31
+ end
32
+
33
+ def validate_max_length(validation_field, max_length)
34
+ return unless field_changed?(validation_field)
35
+
36
+ value = public_send(validation_field)
37
+ return true if value && value.length <= max_length
38
+
39
+ add_error validation_field, :greater_than, args: max_length
40
+ false
41
+ end
42
+
43
+ def validate_min_length(validation_field, min_length)
44
+ return unless field_changed?(validation_field)
45
+
46
+ value = public_send(validation_field)
47
+ return true if value && value.length >= min_length
48
+
49
+ add_error validation_field, :less_than, args: min_length
50
+ false
51
+ end
52
+
53
+ def validate_range_entry(validation_field, range)
54
+ return unless field_changed?(validation_field)
55
+
56
+ value = public_send(validation_field).to_f
57
+
58
+ add_error validation_field, :less_than, args: range.begin if value < range.begin
59
+
60
+ return if value.public_send (range.exclude_end? ? :< : :<=), range.end
61
+
62
+ add_error validation_field, :greater_than, args: range.end
63
+ end
64
+
65
+ ## Requires `email_address` gem
66
+ def validate_email(*validation_fields)
67
+ valid = true
68
+ validation_fields.flatten.each do |validation_field|
69
+ next unless field_changed?(validation_field)
70
+ next if EmailAddress.valid? public_send(validation_field)
71
+
72
+ valid = false
73
+ add_error validation_field, :not_valid_email
74
+ end
75
+ valid
76
+ end
77
+
78
+ ## Requires `formalism-model_form` gem
79
+ def validate_uniqueness(*fields_combinations)
80
+ valid = true
81
+ fields_combinations.each do |*fields_combination|
82
+ fields_combination.flatten!
83
+
84
+ next if fields_combination.none? { |field| field_changed?(field) }
85
+
86
+ next if unique_by_fields_combination? fields_combination
87
+
88
+ valid = false
89
+ add_error_for_uniqueness_validation fields_combination
90
+ end
91
+ valid
92
+ end
93
+
94
+ ## Private methods for this module
95
+
96
+ def field_valid?(field)
97
+ result = true
98
+ if (nested_form = nested_forms[field])
99
+ result = nested_form.valid?
100
+ return result unless result
101
+
102
+ nested_form.run
103
+ end
104
+ result && !public_send(field).blank?
105
+ end
106
+
107
+ def unique_by_fields_combination?(fields_combination)
108
+ dataset = model.where(
109
+ fields_combination
110
+ .map { |field| field_condition(field, send(field)) }
111
+ .reduce(:&)
112
+ )
113
+ dataset = dataset.exclude(instance.pk_hash) if instance&.pk_hash
114
+ dataset.empty?
115
+ end
116
+
117
+ def add_error_for_uniqueness_validation(fields)
118
+ if fields.count == 1
119
+ add_error fields.first, :already_taken
120
+ else
121
+ add_error :itself, :already_exists, fields.join('_and_')
122
+ end
123
+ end
124
+
125
+ def field_changed?(_field)
126
+ true ## can be redefined, for example, in update forms
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Formalism
4
+ module R18nErrors
5
+ VERSION = '0.2.0'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,237 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: formalism-r18n_errors
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Popov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-09-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: formalism
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: gorilla_patch
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: r18n-core
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: gem_toys
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.4.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.4.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: toys
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.11.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.11.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: codecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.2.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.9'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.19.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.19.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.91.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.91.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-performance
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.0'
195
+ description: 'Errors for Formalism via R18n.
196
+
197
+ '
198
+ email:
199
+ - alex.wayfer@gmail.com
200
+ executables: []
201
+ extensions: []
202
+ extra_rdoc_files: []
203
+ files:
204
+ - CHANGELOG.md
205
+ - LICENSE.txt
206
+ - README.md
207
+ - lib/formalism/r18n_errors.rb
208
+ - lib/formalism/r18n_errors/errors.rb
209
+ - lib/formalism/r18n_errors/validation_helpers.rb
210
+ - lib/formalism/r18n_errors/version.rb
211
+ homepage: https://github.com/AlexWayfer/formalism-r18n_errors
212
+ licenses:
213
+ - MIT
214
+ metadata:
215
+ source_code_uri: https://github.com/AlexWayfer/formalism-r18n_errors
216
+ homepage_uri: https://github.com/AlexWayfer/formalism-r18n_errors
217
+ changelog_uri: https://github.com/AlexWayfer/formalism-r18n_errors/blob/master/CHANGELOG.md
218
+ post_install_message:
219
+ rdoc_options: []
220
+ require_paths:
221
+ - lib
222
+ required_ruby_version: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - ">="
225
+ - !ruby/object:Gem::Version
226
+ version: '2.5'
227
+ required_rubygems_version: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ requirements: []
233
+ rubygems_version: 3.1.2
234
+ signing_key:
235
+ specification_version: 4
236
+ summary: Errors for Formalism via R18n
237
+ test_files: []