rasti-form 5.0.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +36 -0
- data/README.md +6 -61
- data/lib/rasti/form/validable.rb +5 -1
- data/lib/rasti/form.rb +28 -20
- data/rasti-form.gemspec +1 -1
- data/spec/validations_spec.rb +34 -2
- metadata +3 -3
- data/.travis.yml +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efb9cfdea85fcce07f977a6bf54a183aface5cce17bfa3f9720f0b60684f48c3
|
4
|
+
data.tar.gz: f1aa1973dad9c2f363bd8f9f030ca48fd158a9897821439ab9e0d93c334a79de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38d34d94241efe87628538d8f6e59baf91e4f46ecf4afe72aebaddf69136de15e2cde9713329cb20d3fb80d8bbb9cbcb52c9041972f949051b925b89b3ce42fb
|
7
|
+
data.tar.gz: cd250e2f305c5836e6b70b6d1e3d0a0d964311af5ac68d5b033461d74b9461d8a4b1cc1948cc6c7d3e7b1bd399a980d5c84765aeced72cadee7d51408dc35d45
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: CI
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
contents: read
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
test:
|
21
|
+
|
22
|
+
runs-on: ubuntu-latest
|
23
|
+
name: Tests
|
24
|
+
strategy:
|
25
|
+
matrix:
|
26
|
+
ruby-version: ['2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '3.0', 'jruby-9.2.9.0']
|
27
|
+
|
28
|
+
steps:
|
29
|
+
- uses: actions/checkout@v3
|
30
|
+
- name: Set up Ruby
|
31
|
+
uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: ${{ matrix.ruby-version }}
|
34
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
35
|
+
- name: Run tests
|
36
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Rasti::Form
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/rasti-form.svg)](https://rubygems.org/gems/rasti-form)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/gabynaiman/rasti-form/actions/workflows/ci.yml/badge.svg)](https://github.com/gabynaiman/rasti-form/actions/workflows/ci.yml)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/github/gabynaiman/rasti-form/badge.svg?branch=master)](https://coveralls.io/github/gabynaiman/rasti-form?branch=master)
|
6
6
|
[![Code Climate](https://codeclimate.com/github/gabynaiman/rasti-form.svg)](https://codeclimate.com/github/gabynaiman/rasti-form)
|
7
7
|
|
8
|
-
Forms validations
|
8
|
+
Forms validations
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -25,37 +25,18 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
```ruby
|
29
|
-
T = Rasti::Form::Types
|
30
|
-
```
|
31
|
-
|
32
|
-
### Type casting
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
T::Integer.cast '10' # => 10
|
36
|
-
T::Integer.cast '10.5' # => 10
|
37
|
-
T::Integer.cast 'text' # => Rasti::Types::CastError: Invalid cast: 'text' -> Rasti::Types::Integer
|
38
|
-
|
39
|
-
T::Boolean.cast 'true' # => true
|
40
|
-
T::Boolean.cast 'FALSE' # => false
|
41
|
-
T::Boolean.cast 'text' # => Rasti::Types::CastError: Invalid cast: 'text' -> Rasti::Types::Boolean
|
42
|
-
|
43
|
-
T::Time['%Y-%m-%d'].cast '2016-10-22' # => 2016-10-22 00:00:00 -0300
|
44
|
-
T::Time['%Y-%m-%d'].cast '2016-10' # => Rasti::Types::CastError: Invalid cast: '2016-10' -> Rasti::Types::Time['%Y-%m-%d']
|
45
|
-
|
46
|
-
T::Array[T::Symbol].cast [1, 'test', :sym] # => [:"1", :test, :sym]
|
47
|
-
```
|
48
|
-
|
49
28
|
### Form type coercion
|
50
29
|
|
51
30
|
```ruby
|
31
|
+
T = Rasti::Types
|
32
|
+
|
52
33
|
PointForm = Rasti::Form[x: T::Integer, y: T::Integer] # => PointForm[:x, :y]
|
53
34
|
form = PointForm.new x: '1', y: 2 # => #<PointForm[x: 1, y: 2]>
|
54
35
|
form.x # => 1
|
55
36
|
form.y # => 2
|
56
|
-
form.
|
37
|
+
form.to_h # => {x: 1, y: 2}
|
57
38
|
|
58
|
-
PointForm.new x: true # => Validation error: {"x":["Invalid cast: true -> Rasti::
|
39
|
+
PointForm.new x: true # => Validation error: {"x":["Invalid cast: true -> Rasti::Types::Integer"]}
|
59
40
|
```
|
60
41
|
|
61
42
|
### Form validations
|
@@ -84,42 +65,6 @@ form.from # => 2016-10-20 00:00:00 -0300
|
|
84
65
|
form.to # => 2016-10-28 00:00:00 -0300
|
85
66
|
```
|
86
67
|
|
87
|
-
### Built-in types
|
88
|
-
|
89
|
-
- Array
|
90
|
-
- Boolean
|
91
|
-
- Enum
|
92
|
-
- Float
|
93
|
-
- Form
|
94
|
-
- Hash
|
95
|
-
- Integer
|
96
|
-
- IO
|
97
|
-
- Regexp
|
98
|
-
- String
|
99
|
-
- Symbol
|
100
|
-
- Time
|
101
|
-
- UUID
|
102
|
-
|
103
|
-
### Plugable types
|
104
|
-
|
105
|
-
```ruby
|
106
|
-
class CustomType
|
107
|
-
class << self
|
108
|
-
extend Castable
|
109
|
-
|
110
|
-
private
|
111
|
-
|
112
|
-
def valid?(value)
|
113
|
-
valid.is_a?(String)
|
114
|
-
end
|
115
|
-
|
116
|
-
def transform(value)
|
117
|
-
value.upcase
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
```
|
122
|
-
|
123
68
|
## Contributing
|
124
69
|
|
125
70
|
Bug reports and pull requests are welcome on GitHub at https://github.com/gabynaiman/rasti-form.
|
data/lib/rasti/form/validable.rb
CHANGED
@@ -10,12 +10,16 @@ module Rasti
|
|
10
10
|
|
11
11
|
def validate!
|
12
12
|
validate
|
13
|
-
|
13
|
+
raise_if_errors!
|
14
14
|
end
|
15
15
|
|
16
16
|
def validate
|
17
17
|
end
|
18
18
|
|
19
|
+
def raise_if_errors!
|
20
|
+
raise ValidationError.new(self, errors) unless errors.empty?
|
21
|
+
end
|
22
|
+
|
19
23
|
def assert(key, condition, message)
|
20
24
|
errors[key] << message unless condition
|
21
25
|
condition
|
data/lib/rasti/form.rb
CHANGED
@@ -10,45 +10,53 @@ module Rasti
|
|
10
10
|
|
11
11
|
include Validable
|
12
12
|
|
13
|
+
alias_method :__initialize__, :initialize
|
14
|
+
private :__initialize__
|
15
|
+
|
13
16
|
def initialize(attributes={})
|
14
|
-
|
15
|
-
|
17
|
+
assign_attributes! attributes
|
18
|
+
validate_type_casting!
|
19
|
+
validate!
|
20
|
+
end
|
16
21
|
|
17
|
-
|
22
|
+
def assigned?(attr_name)
|
23
|
+
assigned_attribute? attr_name.to_sym
|
24
|
+
end
|
18
25
|
|
19
|
-
|
20
|
-
ex.attributes.each do |attr_name|
|
21
|
-
errors[attr_name] << 'unexpected attribute'
|
22
|
-
end
|
26
|
+
private
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
errors[key] += messages
|
27
|
-
end
|
28
|
+
def assign_attributes!(attributes)
|
29
|
+
__initialize__ attributes
|
28
30
|
|
31
|
+
rescue Rasti::Model::UnexpectedAttributesError => ex
|
32
|
+
ex.attributes.each do |attr_name|
|
33
|
+
errors[attr_name] << 'unexpected attribute'
|
29
34
|
end
|
30
35
|
|
31
|
-
|
36
|
+
ensure
|
37
|
+
raise_if_errors!
|
32
38
|
end
|
33
39
|
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
40
|
+
def validate_type_casting!
|
41
|
+
cast_attributes!
|
37
42
|
|
38
|
-
|
43
|
+
rescue Rasti::Types::CompoundError => ex
|
44
|
+
ex.errors.each do |key, messages|
|
45
|
+
errors[key] += messages
|
46
|
+
end
|
47
|
+
|
48
|
+
ensure
|
49
|
+
raise_if_errors!
|
50
|
+
end
|
39
51
|
|
40
52
|
def assert_present(attr_name)
|
41
53
|
if !errors.key?(attr_name)
|
42
54
|
assert attr_name, assigned?(attr_name) && !public_send(attr_name).nil?, 'not present'
|
43
55
|
end
|
44
|
-
rescue Types::Error
|
45
|
-
assert attr_name, false, 'not present'
|
46
56
|
end
|
47
57
|
|
48
58
|
def assert_not_present(attr_name)
|
49
59
|
assert attr_name, !assigned?(attr_name) || public_send(attr_name).nil?, 'is present'
|
50
|
-
rescue Types::Error
|
51
|
-
assert attr_name, false, 'is present'
|
52
60
|
end
|
53
61
|
|
54
62
|
def assert_not_empty(attr_name)
|
data/rasti-form.gemspec
CHANGED
data/spec/validations_spec.rb
CHANGED
@@ -103,7 +103,7 @@ describe Rasti::Form, 'Validations' do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
assert_validation_error('range.max' => ['not present']
|
106
|
+
assert_validation_error('range.max' => ['not present']) do
|
107
107
|
form.new range: {min: 1}
|
108
108
|
end
|
109
109
|
end
|
@@ -162,7 +162,7 @@ describe Rasti::Form, 'Validations' do
|
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'Invalid nested cast' do
|
165
|
-
assert_validation_error('range.max' => ['not present']
|
165
|
+
assert_validation_error('range.max' => ['not present']) do
|
166
166
|
form.new range: {min: 1}
|
167
167
|
end
|
168
168
|
end
|
@@ -298,4 +298,36 @@ describe Rasti::Form, 'Validations' do
|
|
298
298
|
end
|
299
299
|
end
|
300
300
|
|
301
|
+
describe 'Validations Precedence' do
|
302
|
+
|
303
|
+
let(:form) do
|
304
|
+
build_form do
|
305
|
+
attribute :limit, T::Integer
|
306
|
+
|
307
|
+
def validate
|
308
|
+
assert :limit, limit < 10, 'invalid limit'
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
it '1) Validate unexpected attributes' do
|
314
|
+
assert_validation_error(id: ["unexpected attribute"]) do
|
315
|
+
form.new id: '123'
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
it '2) Validate attributes casting' do
|
320
|
+
assert_validation_error(limit: ["Invalid cast: 'pepe' -> Rasti::Types::Integer"]) do
|
321
|
+
form.new limit: 'pepe'
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
it '3) Run custom validations' do
|
326
|
+
assert_validation_error(limit: ["invalid limit"]) do
|
327
|
+
form.new limit: 500
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
301
333
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rasti-form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_require
|
@@ -150,10 +150,10 @@ extensions: []
|
|
150
150
|
extra_rdoc_files: []
|
151
151
|
files:
|
152
152
|
- ".coveralls.yml"
|
153
|
+
- ".github/workflows/ci.yml"
|
153
154
|
- ".gitignore"
|
154
155
|
- ".ruby-gemset"
|
155
156
|
- ".ruby-version"
|
156
|
-
- ".travis.yml"
|
157
157
|
- Gemfile
|
158
158
|
- LICENSE.txt
|
159
159
|
- README.md
|
data/.travis.yml
DELETED