shaped 0.6.4 → 0.8.0
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 +4 -4
- data/.github/workflows/ruby.yml +21 -0
- data/.rubocop.yml +5 -142
- data/.ruby-version +1 -1
- data/CHANGELOG.md +32 -1
- data/Gemfile +9 -4
- data/Gemfile.lock +64 -52
- data/README.md +56 -6
- data/bin/_guard-core +1 -1
- data/bin/guard +1 -1
- data/bin/rspec +1 -1
- data/bin/rubocop +1 -1
- data/lib/shaped.rb +3 -2
- data/lib/shaped/shapes/all.rb +25 -0
- data/lib/shaped/shapes/{or.rb → any.rb} +1 -1
- data/lib/shaped/shapes/callable.rb +1 -0
- data/lib/shaped/shapes/class.rb +0 -7
- data/lib/shaped/shapes/method.rb +15 -0
- data/lib/shaped/version.rb +1 -1
- data/shaped.gemspec +1 -1
- metadata +11 -9
- data/.travis.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a84f7dd70b2d40e32d1dde68014ec240d1681ef75f9c111d7ef52943a99cbab
|
4
|
+
data.tar.gz: bf55523db329247de28c8140a8b4e06392879b6893649bf5de3e4c5da206bbde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72652921092823a183d70edad881be6e3ad881c5c443ce9b2513b54975e6acda118716ed35e597c3414cfdd40ed0cf93ee884d4429c5f4dce445a254dcfa30de
|
7
|
+
data.tar.gz: 0d6e6d2951c4885cf22389da5805211f1410c48b442183067fa862218a967b380e112971f63c08c5e4842723ca77517ebaf4ff3fe7b8b348e0dcc23a8d265fe8
|
@@ -0,0 +1,21 @@
|
|
1
|
+
name: Run Tests, Linters, Etc.
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
build:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v2
|
13
|
+
- uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
bundler-cache: true
|
16
|
+
- name: Run Rubocop
|
17
|
+
run: bin/rubocop --format clang
|
18
|
+
- name: Run RSpec tests
|
19
|
+
run: bin/rspec --format progress
|
20
|
+
- name: Ensure no git diff
|
21
|
+
run: git diff --exit-code && git diff-index --quiet --cached HEAD
|
data/.rubocop.yml
CHANGED
@@ -1,142 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
-
|
5
|
-
|
6
|
-
- bin/{annotate,brakeman,bundle,database_consistency,pallets,rubocop,sidekiq}
|
7
|
-
- db/schema.rb
|
8
|
-
- lib/tasks/auto_annotate_models.rake
|
9
|
-
- node_modules/**/*
|
10
|
-
TargetRubyVersion: 2.7
|
11
|
-
Bundler/GemComment:
|
12
|
-
Enabled: false
|
13
|
-
Layout/ArgumentAlignment:
|
14
|
-
EnforcedStyle: with_fixed_indentation
|
15
|
-
Layout/ClassStructure:
|
16
|
-
ExpectedOrder:
|
17
|
-
- module_inclusion
|
18
|
-
- constants
|
19
|
-
- public_class_methods
|
20
|
-
- initializer
|
21
|
-
- public_methods
|
22
|
-
- protected_methods
|
23
|
-
- private_methods
|
24
|
-
Layout/DotPosition:
|
25
|
-
EnforcedStyle: trailing
|
26
|
-
Layout/FirstArgumentIndentation:
|
27
|
-
Enabled: false # this rule doesn't play nicely with the way that I like to use `memoize`
|
28
|
-
Layout/FirstArrayElementIndentation:
|
29
|
-
EnforcedStyle: consistent
|
30
|
-
Layout/LineLength:
|
31
|
-
IgnoredPatterns:
|
32
|
-
# ignore line length if the line is a comment without any spaces; it's probably not something we
|
33
|
-
# can fix (e.g. a long file path)
|
34
|
-
- !ruby/regexp /^ *#? [\S]+$/
|
35
|
-
Max: 100
|
36
|
-
Layout/MultilineMethodCallIndentation:
|
37
|
-
EnforcedStyle: indented
|
38
|
-
Layout/SpaceBeforeBlockBraces:
|
39
|
-
Enabled: false
|
40
|
-
Layout/SpaceBeforeSemicolon:
|
41
|
-
Enabled: false
|
42
|
-
Layout/SpaceInsideHashLiteralBraces:
|
43
|
-
EnforcedStyle: space
|
44
|
-
Lint/RedundantSplatExpansion:
|
45
|
-
Enabled: false
|
46
|
-
Metrics/AbcSize:
|
47
|
-
Enabled: false
|
48
|
-
Metrics/BlockLength:
|
49
|
-
Enabled: false
|
50
|
-
Metrics/ClassLength:
|
51
|
-
Enabled: false
|
52
|
-
Metrics/MethodLength:
|
53
|
-
Max: 30
|
54
|
-
Naming/RescuedExceptionsVariableName:
|
55
|
-
Enabled: false
|
56
|
-
Style/BlockDelimiters:
|
57
|
-
Enabled: false
|
58
|
-
Style/ClassAndModuleChildren:
|
59
|
-
EnforcedStyle: compact
|
60
|
-
Style/CollectionMethods:
|
61
|
-
Enabled: false
|
62
|
-
Style/ConstantVisibility:
|
63
|
-
Enabled: false
|
64
|
-
Style/Copyright:
|
65
|
-
Enabled: false
|
66
|
-
Style/DisableCopsWithinSourceCodeDirective:
|
67
|
-
Enabled: false
|
68
|
-
Style/Documentation:
|
69
|
-
Enabled: false
|
70
|
-
Style/DocumentationMethod:
|
71
|
-
Enabled: false
|
72
|
-
Style/EmptyCaseCondition:
|
73
|
-
Enabled: false
|
74
|
-
Style/FrozenStringLiteralComment:
|
75
|
-
Enabled: true
|
76
|
-
Style/GlobalVars:
|
77
|
-
Enabled: false
|
78
|
-
Style/GuardClause:
|
79
|
-
Enabled: false
|
80
|
-
Style/IfUnlessModifier:
|
81
|
-
Enabled: false
|
82
|
-
Style/InlineComment:
|
83
|
-
Enabled: false
|
84
|
-
Style/Lambda:
|
85
|
-
Enabled: false
|
86
|
-
Style/MethodCallWithArgsParentheses:
|
87
|
-
IgnoredMethods:
|
88
|
-
- add_runtime_dependency
|
89
|
-
- desc
|
90
|
-
- fail
|
91
|
-
- file
|
92
|
-
- gem
|
93
|
-
- head
|
94
|
-
- include
|
95
|
-
- integer
|
96
|
-
- load
|
97
|
-
- p
|
98
|
-
- print
|
99
|
-
- puts
|
100
|
-
- render
|
101
|
-
- require
|
102
|
-
- require_relative
|
103
|
-
- ruby
|
104
|
-
- run
|
105
|
-
- string
|
106
|
-
- source
|
107
|
-
Style/MissingElse:
|
108
|
-
Enabled: false
|
109
|
-
Style/NegatedIf:
|
110
|
-
Enabled: false
|
111
|
-
Style/ImplicitRuntimeError:
|
112
|
-
Enabled: false
|
113
|
-
Style/MethodCalledOnDoEndBlock:
|
114
|
-
Enabled: false
|
115
|
-
Style/NumericPredicate:
|
116
|
-
Enabled: false
|
117
|
-
Style/ParenthesesAroundCondition:
|
118
|
-
Enabled: false
|
119
|
-
Style/RescueModifier:
|
120
|
-
Enabled: false
|
121
|
-
Style/RescueStandardError:
|
122
|
-
Enabled: false
|
123
|
-
Style/ReturnNil:
|
124
|
-
Enabled: false
|
125
|
-
Style/RegexpLiteral:
|
126
|
-
Enabled: false
|
127
|
-
Style/Semicolon:
|
128
|
-
Enabled: false
|
129
|
-
Style/SignalException:
|
130
|
-
Enabled: false
|
131
|
-
Style/StderrPuts:
|
132
|
-
Enabled: false
|
133
|
-
Style/StringHashKeys:
|
134
|
-
Enabled: false
|
135
|
-
Style/TernaryParentheses:
|
136
|
-
Enabled: false
|
137
|
-
Style/TrailingCommaInArguments:
|
138
|
-
EnforcedStyleForMultiline: comma
|
139
|
-
Style/TrailingCommaInArrayLiteral:
|
140
|
-
EnforcedStyleForMultiline: comma
|
141
|
-
Style/TrailingCommaInHashLiteral:
|
142
|
-
EnforcedStyleForMultiline: comma
|
1
|
+
inherit_gem:
|
2
|
+
runger_style:
|
3
|
+
- rulesets/default.yml # gem 'rubocop'
|
4
|
+
- rulesets/performance.yml # gem 'rubocop-performance'
|
5
|
+
- rulesets/rspec.yml # gem 'rubocop-rspec'
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.7.
|
1
|
+
2.7.2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
## v0.8.0 (2021-01-31)
|
2
|
+
### Added
|
3
|
+
- Accept `Method` as a `Callable` shape definition
|
4
|
+
|
5
|
+
### Internal
|
6
|
+
- Bump Ruby version from 2.7.0 to 2.7.2
|
7
|
+
- Move from Travis to GitHub Actions
|
8
|
+
|
9
|
+
## v0.7.3 (2021-01-07)
|
10
|
+
### Removed
|
11
|
+
- Removed `::name` method for anonymous validator class in `Shaped::Shapes::Class`
|
12
|
+
|
13
|
+
## v0.7.2 (2020-07-13)
|
14
|
+
### Dependencies
|
15
|
+
- Bump `rubocop` to 0.88.0 and `runger_style` to 0.2.3
|
16
|
+
|
17
|
+
## v0.7.1 (2020-07-02)
|
18
|
+
### Internal
|
19
|
+
- Source Rubocop rules/config from `runger_style` gem
|
20
|
+
|
21
|
+
## v0.7.0 (2020-06-24)
|
22
|
+
### BREAKING CHANGES
|
23
|
+
- Rename the `Or` shape to `Any`
|
24
|
+
- Add a `Method` shape (where the shape description is the name of a method which, when called on a
|
25
|
+
test object, must return a truthy value). This is a breaking change because the `Shaped::Shape`
|
26
|
+
constructor will now return an instance of `Shaped::Shapes::Method` rather than
|
27
|
+
`Shaped::Shapes::Equality` when called with a Symbol argument.
|
28
|
+
|
29
|
+
### Added
|
30
|
+
- Add an `All` shape (w/ multiple sub-shapes, all of which must be matched)
|
31
|
+
|
1
32
|
## v0.6.4 (2020-06-22)
|
2
33
|
### Fixed
|
3
34
|
- Make it possible to specify optional keys in a Hash shape (using an `Or` shape as the value)
|
@@ -92,7 +123,7 @@
|
|
92
123
|
`Shaped::Shapes::Hash`):
|
93
124
|
1. `Shaped::Shapes::Class`
|
94
125
|
2. `Shaped::Shapes::Equality`
|
95
|
-
3. `Shaped::Shapes::
|
126
|
+
3. `Shaped::Shapes::Any`
|
96
127
|
- All hashes and arrays in shape definitions are parsed "recursively" as shape definitions. For
|
97
128
|
example, instead of:
|
98
129
|
|
data/Gemfile
CHANGED
@@ -5,10 +5,15 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in shaped.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
|
9
|
-
gem '
|
10
|
-
gem '
|
11
|
-
gem '
|
8
|
+
group :development, :test do
|
9
|
+
gem 'amazing_print'
|
10
|
+
gem 'pry-byebug'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rubocop', require: false
|
13
|
+
gem 'rubocop-performance', require: false
|
14
|
+
gem 'rubocop-rspec', require: false
|
15
|
+
gem 'runger_style', github: 'davidrunger/runger_style', require: false
|
16
|
+
end
|
12
17
|
|
13
18
|
group :test do
|
14
19
|
gem 'codecov', require: false
|
data/Gemfile.lock
CHANGED
@@ -7,35 +7,39 @@ GIT
|
|
7
7
|
guard-compat (~> 1.1)
|
8
8
|
rspec (>= 2.99.0, < 4.0)
|
9
9
|
|
10
|
+
GIT
|
11
|
+
remote: https://github.com/davidrunger/runger_style.git
|
12
|
+
revision: ba2f3c3600bd393a3141a4883489ac15e19dbfd0
|
13
|
+
specs:
|
14
|
+
runger_style (0.2.15)
|
15
|
+
|
10
16
|
PATH
|
11
17
|
remote: .
|
12
18
|
specs:
|
13
|
-
shaped (0.
|
19
|
+
shaped (0.8.0)
|
14
20
|
activemodel (~> 6.0)
|
15
21
|
activesupport (~> 6.0)
|
16
22
|
|
17
23
|
GEM
|
18
24
|
remote: https://rubygems.org/
|
19
25
|
specs:
|
20
|
-
activemodel (6.
|
21
|
-
activesupport (= 6.
|
22
|
-
activesupport (6.
|
26
|
+
activemodel (6.1.1)
|
27
|
+
activesupport (= 6.1.1)
|
28
|
+
activesupport (6.1.1)
|
23
29
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
24
|
-
i18n (>=
|
25
|
-
minitest (
|
26
|
-
tzinfo (~>
|
27
|
-
zeitwerk (~> 2.
|
28
|
-
amazing_print (1.2.
|
30
|
+
i18n (>= 1.6, < 2)
|
31
|
+
minitest (>= 5.1)
|
32
|
+
tzinfo (~> 2.0)
|
33
|
+
zeitwerk (~> 2.3)
|
34
|
+
amazing_print (1.2.2)
|
29
35
|
ast (2.4.1)
|
30
36
|
byebug (11.1.3)
|
31
|
-
codecov (0.
|
32
|
-
|
33
|
-
simplecov
|
34
|
-
url
|
37
|
+
codecov (0.4.0)
|
38
|
+
simplecov (>= 0.15, < 0.22)
|
35
39
|
coderay (1.1.3)
|
36
|
-
concurrent-ruby (1.1.
|
37
|
-
diff-lcs (1.
|
38
|
-
docile (1.3.
|
40
|
+
concurrent-ruby (1.1.8)
|
41
|
+
diff-lcs (1.4.4)
|
42
|
+
docile (1.3.5)
|
39
43
|
ffi (1.13.1)
|
40
44
|
formatador (0.2.5)
|
41
45
|
guard (2.16.2)
|
@@ -48,22 +52,21 @@ GEM
|
|
48
52
|
shellany (~> 0.0)
|
49
53
|
thor (>= 0.18.1)
|
50
54
|
guard-compat (1.2.1)
|
51
|
-
i18n (1.8.
|
55
|
+
i18n (1.8.7)
|
52
56
|
concurrent-ruby (~> 1.0)
|
53
|
-
json (2.3.0)
|
54
57
|
listen (3.2.1)
|
55
58
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
56
59
|
rb-inotify (~> 0.9, >= 0.9.10)
|
57
60
|
lumberjack (1.2.5)
|
58
61
|
method_source (1.0.0)
|
59
|
-
minitest (5.14.
|
62
|
+
minitest (5.14.3)
|
60
63
|
nenv (0.3.0)
|
61
64
|
notiffany (0.1.3)
|
62
65
|
nenv (~> 0.1)
|
63
66
|
shellany (~> 0.0)
|
64
|
-
parallel (1.
|
65
|
-
parser (
|
66
|
-
ast (~> 2.4.
|
67
|
+
parallel (1.20.1)
|
68
|
+
parser (3.0.0.0)
|
69
|
+
ast (~> 2.4.1)
|
67
70
|
pry (0.13.1)
|
68
71
|
coderay (~> 1.1)
|
69
72
|
method_source (~> 1.0)
|
@@ -71,49 +74,55 @@ GEM
|
|
71
74
|
byebug (~> 11.0)
|
72
75
|
pry (~> 0.13.0)
|
73
76
|
rainbow (3.0.0)
|
74
|
-
rake (13.0.
|
77
|
+
rake (13.0.3)
|
75
78
|
rb-fsevent (0.10.4)
|
76
79
|
rb-inotify (0.10.1)
|
77
80
|
ffi (~> 1.0)
|
78
|
-
regexp_parser (
|
81
|
+
regexp_parser (2.0.3)
|
79
82
|
rexml (3.2.4)
|
80
|
-
rspec (3.
|
81
|
-
rspec-core (~> 3.
|
82
|
-
rspec-expectations (~> 3.
|
83
|
-
rspec-mocks (~> 3.
|
84
|
-
rspec-core (3.
|
85
|
-
rspec-support (~> 3.
|
86
|
-
rspec-expectations (3.
|
83
|
+
rspec (3.10.0)
|
84
|
+
rspec-core (~> 3.10.0)
|
85
|
+
rspec-expectations (~> 3.10.0)
|
86
|
+
rspec-mocks (~> 3.10.0)
|
87
|
+
rspec-core (3.10.1)
|
88
|
+
rspec-support (~> 3.10.0)
|
89
|
+
rspec-expectations (3.10.1)
|
87
90
|
diff-lcs (>= 1.2.0, < 2.0)
|
88
|
-
rspec-support (~> 3.
|
89
|
-
rspec-mocks (3.
|
91
|
+
rspec-support (~> 3.10.0)
|
92
|
+
rspec-mocks (3.10.1)
|
90
93
|
diff-lcs (>= 1.2.0, < 2.0)
|
91
|
-
rspec-support (~> 3.
|
92
|
-
rspec-support (3.
|
93
|
-
rubocop (
|
94
|
+
rspec-support (~> 3.10.0)
|
95
|
+
rspec-support (3.10.1)
|
96
|
+
rubocop (1.8.1)
|
94
97
|
parallel (~> 1.10)
|
95
|
-
parser (>=
|
98
|
+
parser (>= 3.0.0.0)
|
96
99
|
rainbow (>= 2.2.2, < 4.0)
|
97
|
-
regexp_parser (>= 1.
|
100
|
+
regexp_parser (>= 1.8, < 3.0)
|
98
101
|
rexml
|
99
|
-
rubocop-ast (>= 0.0
|
102
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
100
103
|
ruby-progressbar (~> 1.7)
|
101
|
-
unicode-display_width (>= 1.4.0, <
|
102
|
-
rubocop-ast (
|
103
|
-
parser (>= 2.7.
|
104
|
-
|
104
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
105
|
+
rubocop-ast (1.4.0)
|
106
|
+
parser (>= 2.7.1.5)
|
107
|
+
rubocop-performance (1.9.2)
|
108
|
+
rubocop (>= 0.90.0, < 2.0)
|
109
|
+
rubocop-ast (>= 0.4.0)
|
110
|
+
rubocop-rspec (2.1.0)
|
111
|
+
rubocop (~> 1.0)
|
112
|
+
rubocop-ast (>= 1.1.0)
|
113
|
+
ruby-progressbar (1.11.0)
|
105
114
|
shellany (0.0.1)
|
106
|
-
simplecov (0.
|
115
|
+
simplecov (0.21.2)
|
107
116
|
docile (~> 1.1)
|
108
117
|
simplecov-html (~> 0.11)
|
109
|
-
|
118
|
+
simplecov_json_formatter (~> 0.1)
|
119
|
+
simplecov-html (0.12.3)
|
120
|
+
simplecov_json_formatter (0.1.2)
|
110
121
|
thor (1.0.1)
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
url (0.3.2)
|
116
|
-
zeitwerk (2.3.0)
|
122
|
+
tzinfo (2.0.4)
|
123
|
+
concurrent-ruby (~> 1.0)
|
124
|
+
unicode-display_width (2.0.0)
|
125
|
+
zeitwerk (2.4.2)
|
117
126
|
|
118
127
|
PLATFORMS
|
119
128
|
ruby
|
@@ -126,7 +135,10 @@ DEPENDENCIES
|
|
126
135
|
rake
|
127
136
|
rspec
|
128
137
|
rubocop
|
138
|
+
rubocop-performance
|
139
|
+
rubocop-rspec
|
140
|
+
runger_style!
|
129
141
|
shaped!
|
130
142
|
|
131
143
|
BUNDLED WITH
|
132
|
-
2.1.
|
144
|
+
2.1.4
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
[](https://codecov.io/gh/davidrunger/shaped)
|
2
|
-
[](https://travis-ci.com/davidrunger/shaped)
|
3
2
|
[](https://dependabot.com)
|
4
3
|
[](https://badge.fury.io/rb/shaped)
|
5
4
|
|
@@ -21,15 +20,17 @@ Validate the "shape" of Ruby objects!
|
|
21
20
|
* [Shaped::Shapes::Array](#shapedshapesarray)
|
22
21
|
* [Shaped::Shapes::Class](#shapedshapesclass)
|
23
22
|
* [ActiveModel validations](#activemodel-validations)
|
23
|
+
* [Shaped::Shapes::Method](#shapedshapesmethod)
|
24
24
|
* [Shaped::Shapes::Callable](#shapedshapescallable)
|
25
25
|
* [Shaped::Shapes::Equality](#shapedshapesequality)
|
26
|
-
* [Shaped::Shapes::
|
26
|
+
* [Shaped::Shapes::Any](#shapedshapesany)
|
27
|
+
* [Shaped::Shapes::All](#shapedshapesall)
|
27
28
|
* [#to_s](#to_s)
|
28
29
|
* [Development](#development)
|
29
30
|
* [For maintainers](#for-maintainers)
|
30
31
|
* [License](#license)
|
31
32
|
|
32
|
-
<!-- Added by: david, at:
|
33
|
+
<!-- Added by: david, at: Wed Jun 24 13:56:49 PDT 2020 -->
|
33
34
|
|
34
35
|
<!--te-->
|
35
36
|
|
@@ -91,7 +92,7 @@ types (all of which inherit from `Shaped::Shape`):
|
|
91
92
|
1. `Shaped::Shapes::Class`
|
92
93
|
1. `Shaped::Shapes::Callable`
|
93
94
|
1. `Shaped::Shapes::Equality`
|
94
|
-
1. `Shaped::Shapes::
|
95
|
+
1. `Shaped::Shapes::Any`
|
95
96
|
|
96
97
|
Examples illustrating the use of each shape type are below.
|
97
98
|
|
@@ -204,6 +205,21 @@ shape.matched_by?('a@b.c') # too short
|
|
204
205
|
# => false
|
205
206
|
```
|
206
207
|
|
208
|
+
## Shaped::Shapes::Method
|
209
|
+
|
210
|
+
This shape allows specifying a method name that, when called upon a test object, must return a
|
211
|
+
truthy value in order for `matched_by?` to be true.
|
212
|
+
|
213
|
+
```rb
|
214
|
+
shape = Shaped::Shape(:odd?)
|
215
|
+
|
216
|
+
shape.matched_by?(55)
|
217
|
+
# => true
|
218
|
+
|
219
|
+
shape.matched_by?(60)
|
220
|
+
# => false
|
221
|
+
```
|
222
|
+
|
207
223
|
## Shaped::Shapes::Callable
|
208
224
|
|
209
225
|
This shape is very powerful if you need a very customized shape definition; you can define any
|
@@ -223,6 +239,23 @@ shape.matched_by?(5) # fails the `#even?` check
|
|
223
239
|
shape.matched_by?(10) # fails the `#cover?` check (10 is too high)
|
224
240
|
# => false
|
225
241
|
```
|
242
|
+
|
243
|
+
If you'd like to provide a named method rather than an anonymous proc/lambda, you can do that, too:
|
244
|
+
|
245
|
+
```rb
|
246
|
+
def number_is_greater_than_thirty?(number)
|
247
|
+
number > 30
|
248
|
+
end
|
249
|
+
|
250
|
+
shape = Shaped::Shape(method(:number_is_greater_than_thirty?))
|
251
|
+
|
252
|
+
shape.matched_by?(31)
|
253
|
+
# => true
|
254
|
+
|
255
|
+
shape.matched_by?(29)
|
256
|
+
# => false
|
257
|
+
```
|
258
|
+
|
226
259
|
You can also provide an instance of a custom class that implements a `#call` instance method:
|
227
260
|
|
228
261
|
```rb
|
@@ -282,7 +315,7 @@ shape.matched_by?(verification_code: '321cba', new_role: 'SuperAdmin')
|
|
282
315
|
# => false
|
283
316
|
```
|
284
317
|
|
285
|
-
## Shaped::Shapes::
|
318
|
+
## Shaped::Shapes::Any
|
286
319
|
|
287
320
|
This shape is used behind the scenes to build "compound matchers", such as an Array shape that
|
288
321
|
allows multiple different classes:
|
@@ -299,7 +332,7 @@ shape.matched_by?([0.333, 55])
|
|
299
332
|
# => false
|
300
333
|
```
|
301
334
|
|
302
|
-
You can build an `
|
335
|
+
You can build an `Any` shape by invoking the `Shaped::Shape` constructor with more than one argument.
|
303
336
|
Below is a (rather artificial) example illustrating this. To match this `shape`, an object must be
|
304
337
|
either greater than zero OR an Integer (or both).
|
305
338
|
|
@@ -316,6 +349,23 @@ shape.matched_by?(-11.5) # it's neither greater than 0 nor an Integer
|
|
316
349
|
# => false
|
317
350
|
```
|
318
351
|
|
352
|
+
## Shaped::Shapes::All
|
353
|
+
|
354
|
+
This shape can be used to combine multiple checks, all of which must be true for a test object in
|
355
|
+
order for `#matched_by?` to be true:
|
356
|
+
|
357
|
+
```rb
|
358
|
+
shape = Shaped::Shapes::All.new(Numeric, ->(number) { number.even? })
|
359
|
+
shape.to_s
|
360
|
+
# => "Numeric AND Proc test defined at (eval):10"
|
361
|
+
|
362
|
+
shape.matched_by?(22) # 22 is both a Numeric and `#even?`
|
363
|
+
# => true
|
364
|
+
|
365
|
+
shape.matched_by?(33) # 33 is a Numeric but it's not `#even?`
|
366
|
+
# => false
|
367
|
+
```
|
368
|
+
|
319
369
|
## `#to_s`
|
320
370
|
|
321
371
|
Each Shape type implements a `#to_s` instance method that aims to provide a relatively clear
|
data/bin/_guard-core
CHANGED
@@ -17,7 +17,7 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path(
|
|
17
17
|
bundle_binstub = File.expand_path('bundle', __dir__)
|
18
18
|
|
19
19
|
if File.file?(bundle_binstub)
|
20
|
-
if
|
20
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
21
21
|
load(bundle_binstub)
|
22
22
|
else
|
23
23
|
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
data/bin/guard
CHANGED
@@ -17,7 +17,7 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path(
|
|
17
17
|
bundle_binstub = File.expand_path('bundle', __dir__)
|
18
18
|
|
19
19
|
if File.file?(bundle_binstub)
|
20
|
-
if
|
20
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
21
21
|
load(bundle_binstub)
|
22
22
|
else
|
23
23
|
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
data/bin/rspec
CHANGED
@@ -18,7 +18,7 @@ ENV['BUNDLE_GEMFILE'] ||=
|
|
18
18
|
bundle_binstub = File.expand_path('bundle', __dir__)
|
19
19
|
|
20
20
|
if File.file?(bundle_binstub)
|
21
|
-
if
|
21
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
22
22
|
load(bundle_binstub)
|
23
23
|
else
|
24
24
|
abort(<<~ERROR)
|
data/bin/rubocop
CHANGED
@@ -14,7 +14,7 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE_
|
|
14
14
|
bundle_binstub = File.expand_path('bundle', __dir__)
|
15
15
|
|
16
16
|
if File.file?(bundle_binstub)
|
17
|
-
if
|
17
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
18
18
|
load(bundle_binstub)
|
19
19
|
else
|
20
20
|
abort(<<~ERROR)
|
data/lib/shaped.rb
CHANGED
@@ -6,14 +6,14 @@ module Shaped::Shapes ; end
|
|
6
6
|
require 'active_support/all'
|
7
7
|
require 'active_model'
|
8
8
|
require_relative './shaped/shape.rb'
|
9
|
-
Dir[File.dirname(__FILE__)
|
9
|
+
Dir["#{File.dirname(__FILE__)}/**/*.rb"].sort.each { |file| require file }
|
10
10
|
|
11
11
|
module Shaped
|
12
12
|
# rubocop:disable Naming/MethodName, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
13
13
|
def self.Shape(*shape_descriptions)
|
14
14
|
validation_options = shape_descriptions.extract_options!
|
15
15
|
if shape_descriptions.size >= 2
|
16
|
-
Shaped::Shapes::
|
16
|
+
Shaped::Shapes::Any.new(*shape_descriptions, validation_options)
|
17
17
|
else
|
18
18
|
# If the shape_descriptions argument list was just one hash, then `extract_options!` would
|
19
19
|
# have removed it, making `shape_descriptions` an empty array, so we need to "restore" the
|
@@ -30,6 +30,7 @@ module Shaped
|
|
30
30
|
when Shaped::Shape then shape_description
|
31
31
|
when Hash then Shaped::Shapes::Hash.new(shape_description)
|
32
32
|
when Array then Shaped::Shapes::Array.new(shape_description)
|
33
|
+
when Symbol then Shaped::Shapes::Method.new(shape_description)
|
33
34
|
when Class then Shaped::Shapes::Class.new(shape_description, validation_options)
|
34
35
|
else
|
35
36
|
if shape_description.respond_to?(:call)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Shaped::Shapes::All < Shaped::Shape
|
4
|
+
def initialize(*shape_descriptions)
|
5
|
+
validation_options = shape_descriptions.extract_options!
|
6
|
+
if shape_descriptions.size <= 1
|
7
|
+
raise(Shaped::InvalidShapeDescription, <<~ERROR.squish)
|
8
|
+
A #{self.class} description must be a list of two or more shape descriptions.
|
9
|
+
ERROR
|
10
|
+
end
|
11
|
+
|
12
|
+
@shapes =
|
13
|
+
shape_descriptions.map do |description|
|
14
|
+
Shaped::Shape(description, validation_options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def matched_by?(object)
|
19
|
+
@shapes.all? { |shape| shape.matched_by?(object) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
@shapes.map(&:to_s).join(' AND ')
|
24
|
+
end
|
25
|
+
end
|
@@ -11,6 +11,7 @@ class Shaped::Shapes::Callable < Shaped::Shape
|
|
11
11
|
|
12
12
|
def to_s
|
13
13
|
case @callable
|
14
|
+
when Method then "Method defined at #{@callable.source_location.map(&:to_s).join(':')}"
|
14
15
|
when Proc then "Proc test defined at #{@callable.source_location.map(&:to_s).join(':')}"
|
15
16
|
else "#call test defined at #{@callable.method(:call).source_location.map(&:to_s).join(':')}"
|
16
17
|
end
|
data/lib/shaped/shapes/class.rb
CHANGED
@@ -34,13 +34,6 @@ class Shaped::Shapes::Class < Shaped::Shape
|
|
34
34
|
attr_accessor :value
|
35
35
|
|
36
36
|
validates :value, validations
|
37
|
-
|
38
|
-
class << self
|
39
|
-
# ActiveModel requires the class to have a `name`
|
40
|
-
def name
|
41
|
-
'Shaped::Shapes::Class::AnonymousValidator'
|
42
|
-
end
|
43
|
-
end
|
44
37
|
end
|
45
38
|
end
|
46
39
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Shaped::Shapes::Method < Shaped::Shape
|
4
|
+
def initialize(method_name)
|
5
|
+
@method_name = method_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def matched_by?(object)
|
9
|
+
!!object.public_send(@method_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"object returning truthy for ##{@method_name}"
|
14
|
+
end
|
15
|
+
end
|
data/lib/shaped/version.rb
CHANGED
data/shaped.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Validate the "shape" of Ruby objects.'
|
13
13
|
spec.homepage = 'https://github.com/davidrunger/shaped'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
16
16
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
18
18
|
spec.metadata['source_code_uri'] = 'https://github.com/davidrunger/shaped'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shaped
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Runger
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -45,11 +45,11 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- ".github/workflows/ruby.yml"
|
48
49
|
- ".gitignore"
|
49
50
|
- ".rspec"
|
50
51
|
- ".rubocop.yml"
|
51
52
|
- ".ruby-version"
|
52
|
-
- ".travis.yml"
|
53
53
|
- CHANGELOG.md
|
54
54
|
- Gemfile
|
55
55
|
- Gemfile.lock
|
@@ -65,12 +65,14 @@ files:
|
|
65
65
|
- bin/setup
|
66
66
|
- lib/shaped.rb
|
67
67
|
- lib/shaped/shape.rb
|
68
|
+
- lib/shaped/shapes/all.rb
|
69
|
+
- lib/shaped/shapes/any.rb
|
68
70
|
- lib/shaped/shapes/array.rb
|
69
71
|
- lib/shaped/shapes/callable.rb
|
70
72
|
- lib/shaped/shapes/class.rb
|
71
73
|
- lib/shaped/shapes/equality.rb
|
72
74
|
- lib/shaped/shapes/hash.rb
|
73
|
-
- lib/shaped/shapes/
|
75
|
+
- lib/shaped/shapes/method.rb
|
74
76
|
- lib/shaped/version.rb
|
75
77
|
- shaped.gemspec
|
76
78
|
homepage: https://github.com/davidrunger/shaped
|
@@ -80,7 +82,7 @@ metadata:
|
|
80
82
|
homepage_uri: https://github.com/davidrunger/shaped
|
81
83
|
source_code_uri: https://github.com/davidrunger/shaped
|
82
84
|
changelog_uri: https://github.com/davidrunger/shaped/blob/master/CHANGELOG.md
|
83
|
-
post_install_message:
|
85
|
+
post_install_message:
|
84
86
|
rdoc_options: []
|
85
87
|
require_paths:
|
86
88
|
- lib
|
@@ -88,15 +90,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
90
|
requirements:
|
89
91
|
- - ">="
|
90
92
|
- !ruby/object:Gem::Version
|
91
|
-
version: 2.
|
93
|
+
version: 2.7.0
|
92
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
95
|
requirements:
|
94
96
|
- - ">="
|
95
97
|
- !ruby/object:Gem::Version
|
96
98
|
version: '0'
|
97
99
|
requirements: []
|
98
|
-
rubygems_version: 3.1.
|
99
|
-
signing_key:
|
100
|
+
rubygems_version: 3.1.4
|
101
|
+
signing_key:
|
100
102
|
specification_version: 4
|
101
103
|
summary: Validate the "shape" of Ruby objects.
|
102
104
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: ruby
|
3
|
-
os: linux
|
4
|
-
dist: bionic
|
5
|
-
cache: bundler
|
6
|
-
rvm:
|
7
|
-
- 2.7.0
|
8
|
-
notifications:
|
9
|
-
email:
|
10
|
-
on_success: never
|
11
|
-
on_failure: always
|
12
|
-
script:
|
13
|
-
- bin/rubocop $(git ls-tree -r HEAD --name-only) --force-exclusion --format clang
|
14
|
-
- bin/rspec
|