media_types 2.2.0 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/debian.yml +1 -1
- data/.github/workflows/publish-bookworm.yml +34 -0
- data/.github/workflows/publish-sid.yml +34 -0
- data/.gitignore +10 -0
- data/CHANGELOG.md +30 -11
- data/Gemfile.lock +43 -43
- data/README.md +6 -4
- data/lib/media_types/constructable.rb +1 -0
- data/lib/media_types/errors.rb +6 -0
- data/lib/media_types/scheme/output_empty_guard.rb +4 -4
- data/lib/media_types/scheme/rules.rb +17 -4
- data/lib/media_types/scheme/rules_exhausted_guard.rb +8 -6
- data/lib/media_types/scheme/validation_options.rb +6 -5
- data/lib/media_types/scheme.rb +33 -11
- data/lib/media_types/validations.rb +14 -1
- data/lib/media_types/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1142ee3380c374e5f49563e0bc5dd52d379b1d5f0971f32573d1c4e508da8a53
|
4
|
+
data.tar.gz: 1110579b304aeaaa2cdf1c78c9083df5dae0c42a903daf448c5f8c3abea77c41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c91d590c74715eaf9d5cc705f9fc8cc1c8777fd32aaabd0a155548dc04c1c22426a5cd387803116956d8665465ec9ff5bee8c3f81140acb649e3a74821c449f
|
7
|
+
data.tar.gz: 520d8fa98570b498aaeae73168ea6e2c286fa918936874030eb16d42901e81a4431c10c2af168594f33c01e677f00ce46f2d7b9bd993051aaa634231ab70bf61
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish debian bookworm packages
|
2
|
+
|
3
|
+
on:
|
4
|
+
- workflow_dispatch
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish-bookworm:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
container:
|
10
|
+
image: debian:bookworm
|
11
|
+
steps:
|
12
|
+
- name: Install repo
|
13
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install wget && wget -O key.deb https://deb1.ws.maxmaton.nl/key.deb && DEBIAN_FRONTEND=noninteractive apt-get --yes install ./key.deb && echo "deb [signed-by=/usr/share/keyrings/maxmaton.gpg] http://deb.maxmaton.nl/debian bookworm main non-free" > /etc/apt/sources.list.d/maxmaton.list
|
14
|
+
- name: Install dependencies
|
15
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install git build-essential gem scrypt sshpass gem2deb ruby-actionpack ruby-activesupport
|
16
|
+
- uses: actions/checkout@v3
|
17
|
+
name: Check out repository
|
18
|
+
- name: Build gem
|
19
|
+
run: |
|
20
|
+
git config --global --add safe.directory "$(pwd)"
|
21
|
+
sed -i -re "s/VERSION\s+=\s+'([0-9]+.[0-9]+.[0-9]+)'/VERSION = '\1.bookworm'/g" lib/media_types/version.rb
|
22
|
+
gem build media_types.gemspec
|
23
|
+
- name: Build deb
|
24
|
+
run: DEBEMAIL=info@delftsolutions.nl gem2deb media_types-*.gem && ls -hal
|
25
|
+
- name: Publish
|
26
|
+
env:
|
27
|
+
PUBLISH_SIGNING_KEY: ${{ secrets.PUBLISH_SIGNING_KEY }}
|
28
|
+
SSHPASS: ${{ secrets.SSHPASS }}
|
29
|
+
run: |
|
30
|
+
echo "deb1.ws.maxmaton.nl ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgN3TiyKvRTj4xBSyQtYz0OuHZYv2i+x3NL+svh2k0SgPr0Xms4Vu+g3AXntXUQGRM0W9zbcZSHiBIWbliv3Y+20f7lKlj9uXUEMHDuiB7Fu7dXObfHswIvTX3XWiPdDeG1jYQbGM3tENX/wtEoixyL++33O69t2SFR5MkPk+/j+zlGLCFf0ypTAMb7bT5NjRNM3+v0LT2WVSZuawA7Fl8WBVTq7MSSuCZIxHIv1kEq6AWpOjWZHNVZrijs+uRTIPcrZ47wSt6tanjAnWT9sAzu8KqcvQsPw9IQwqV1nfQWz0wMit7ijn9B3MrkNHXP5PaNiZQCezsbrh9glhShz0z" > known_hosts
|
31
|
+
echo "deb1.ws.maxmaton.nl ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMr5uAraiRj0pQ9Q9dQO0xMosTzFUAe+VjtMclIUbdJ7r7XMUa3etxh3BfBlW4nq3ZdIFCsV2zwzTaYSmfh95Xs=" >> known_hosts
|
32
|
+
echo "deb1.ws.maxmaton.nl ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhQl7Ik6h7hSQbdo9ZfF78WYFCzch8SAOXFBxxAZH06" >> known_hosts
|
33
|
+
echo "Uploading :" ruby-media-types_*.deb
|
34
|
+
scrypt enc --passphrase "env:PUBLISH_SIGNING_KEY" ruby-media-types_*.deb | sshpass -e ssh -o "UserKnownHostsFile=known_hosts" publish@deb1.ws.maxmaton.nl "echo 'uploading bookworm' && sudo /opt/max/publish-deb ruby-media-types bookworm main && echo 'bookworm done'"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish debian sid packages
|
2
|
+
|
3
|
+
on:
|
4
|
+
- workflow_dispatch
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish-sid:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
container:
|
10
|
+
image: debian:sid
|
11
|
+
steps:
|
12
|
+
- name: Install repo
|
13
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install wget && wget -O key.deb https://deb1.ws.maxmaton.nl/key.deb && DEBIAN_FRONTEND=noninteractive apt-get --yes install ./key.deb && echo "deb [signed-by=/usr/share/keyrings/maxmaton.gpg] http://deb.maxmaton.nl/debian sid main non-free" > /etc/apt/sources.list.d/maxmaton.list
|
14
|
+
- name: Install dependencies
|
15
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install git build-essential gem scrypt sshpass gem2deb ruby-actionpack ruby-activesupport
|
16
|
+
- uses: actions/checkout@v3
|
17
|
+
name: Check out repository
|
18
|
+
- name: Build gem
|
19
|
+
run: |
|
20
|
+
git config --global --add safe.directory "$(pwd)"
|
21
|
+
sed -i -re "s/VERSION\s+=\s+'([0-9]+.[0-9]+.[0-9]+)'/VERSION = '\1.sid'/g" lib/media_types/version.rb
|
22
|
+
gem build media_types.gemspec
|
23
|
+
- name: Build deb
|
24
|
+
run: DEBEMAIL=info@delftsolutions.nl gem2deb media_types-*.gem && ls -hal
|
25
|
+
- name: Publish
|
26
|
+
env:
|
27
|
+
PUBLISH_SIGNING_KEY: ${{ secrets.PUBLISH_SIGNING_KEY }}
|
28
|
+
SSHPASS: ${{ secrets.SSHPASS }}
|
29
|
+
run: |
|
30
|
+
echo "deb1.ws.maxmaton.nl ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgN3TiyKvRTj4xBSyQtYz0OuHZYv2i+x3NL+svh2k0SgPr0Xms4Vu+g3AXntXUQGRM0W9zbcZSHiBIWbliv3Y+20f7lKlj9uXUEMHDuiB7Fu7dXObfHswIvTX3XWiPdDeG1jYQbGM3tENX/wtEoixyL++33O69t2SFR5MkPk+/j+zlGLCFf0ypTAMb7bT5NjRNM3+v0LT2WVSZuawA7Fl8WBVTq7MSSuCZIxHIv1kEq6AWpOjWZHNVZrijs+uRTIPcrZ47wSt6tanjAnWT9sAzu8KqcvQsPw9IQwqV1nfQWz0wMit7ijn9B3MrkNHXP5PaNiZQCezsbrh9glhShz0z" > known_hosts
|
31
|
+
echo "deb1.ws.maxmaton.nl ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMr5uAraiRj0pQ9Q9dQO0xMosTzFUAe+VjtMclIUbdJ7r7XMUa3etxh3BfBlW4nq3ZdIFCsV2zwzTaYSmfh95Xs=" >> known_hosts
|
32
|
+
echo "deb1.ws.maxmaton.nl ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhQl7Ik6h7hSQbdo9ZfF78WYFCzch8SAOXFBxxAZH06" >> known_hosts
|
33
|
+
echo "Uploading :" ruby-media-types_*.deb
|
34
|
+
scrypt enc --passphrase "env:PUBLISH_SIGNING_KEY" ruby-media-types_*.deb | sshpass -e ssh -o "UserKnownHostsFile=known_hosts" publish@deb1.ws.maxmaton.nl "echo 'uploading sid' && sudo /opt/max/publish-deb ruby-media-types sid main && echo 'sid done'"
|
data/.gitignore
CHANGED
@@ -8,3 +8,13 @@
|
|
8
8
|
/tmp/
|
9
9
|
|
10
10
|
.idea/
|
11
|
+
|
12
|
+
/media_types-*.gem
|
13
|
+
/media-types-*.tar.gz
|
14
|
+
/ruby-media-types-*
|
15
|
+
/ruby-media-types_*.deb
|
16
|
+
/ruby-media-types_*.buildinfo
|
17
|
+
/ruby-media-types_*.changes
|
18
|
+
/ruby-media-types_*.debian.tar.xz
|
19
|
+
/ruby-media-types_*.dsc
|
20
|
+
/ruby-media-types_*.orig.tar.gz
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.3.2
|
4
|
+
|
5
|
+
- Fix that causes bailout in nested rule to stop validation altogether
|
6
|
+
|
7
|
+
## 2.3.1
|
8
|
+
|
9
|
+
- Fix build issue that caused debian package to be empty
|
10
|
+
|
11
|
+
## 2.3.0
|
12
|
+
|
13
|
+
- Add ability to define multiple versions using one block.
|
14
|
+
- Add `index` attribute type that automatically generates a link list compatible with media_types-serialization.
|
15
|
+
- Add support for `collection` to automatically look up a previously defined schema when passing a view.
|
16
|
+
- Add ability to mark certain attributes as optional when validating with `loose: true` and required otherwise.
|
17
|
+
|
18
|
+
## 2.2.0
|
19
|
+
|
20
|
+
- Change dependencies and build output to be debian compatible
|
21
|
+
|
3
22
|
## 2.1.1
|
4
23
|
|
5
24
|
- Fix Ruby 2.6 to 2.7 incompatible change
|
@@ -17,25 +36,25 @@
|
|
17
36
|
|
18
37
|
## 2.0.0
|
19
38
|
|
20
|
-
-
|
39
|
+
- Remove ability to set default suffix. All suffixes now default to `+json`.
|
21
40
|
- Suffixes are now set for a given view and version instead of as a block.
|
22
|
-
-
|
23
|
-
-
|
24
|
-
-
|
41
|
+
- Add `suffix :yoursuffix` command to override the default `:json` suffix.
|
42
|
+
- Remove defaults block.
|
43
|
+
- Remove registrations block.
|
25
44
|
|
26
45
|
## 1.0.0
|
27
46
|
|
28
|
-
-
|
47
|
+
- Add the ability to do inline tests when defining validations using `assert_pass '<json>'` and `assert_fail '<json>'`.
|
29
48
|
- `media_type` has been replaced with `use_name`.
|
30
49
|
- It is no longer possible to set a default version. Please use `version <x> do` instead.
|
31
50
|
- You no longer need to specify a custom format string. If you set an organisation with `def self.organisation` or set a module wide organisation with `MediaTypes::set_organisation <module>, '<organisation>'` the library will generate identifiers for you.
|
32
51
|
- `self.base_format` has been replaced by `identifier_format do |type:, view:, version:, suffix:|`.
|
33
|
-
-
|
34
|
-
-
|
35
|
-
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
-
|
52
|
+
- Add the `empty` validation to mark an empty object as valid.
|
53
|
+
- Add the `identifier` function to get the [Media Type Identifier](https://en.wikipedia.org/wiki/Media_type) for the validator.
|
54
|
+
- Add `version(x)` and `view(x)` functions.
|
55
|
+
- Add an `available_validations` functions that returns all defined validations.
|
56
|
+
- Fix an issue where validations could accidentally merge if defined with a bad `base_format`.
|
57
|
+
- Fix an issue where undefined validations would accept an empty object.
|
39
58
|
|
40
59
|
## 0.6.2
|
41
60
|
|
data/Gemfile.lock
CHANGED
@@ -1,43 +1,43 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
media_types (2.
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
ansi (1.5.0)
|
10
|
-
awesome_print (1.9.2)
|
11
|
-
builder (3.2.4)
|
12
|
-
docile (1.4.0)
|
13
|
-
minitest (5.18.0)
|
14
|
-
minitest-reporters (1.6.0)
|
15
|
-
ansi
|
16
|
-
builder
|
17
|
-
minitest (>= 5.0)
|
18
|
-
ruby-progressbar
|
19
|
-
oj (3.14.2)
|
20
|
-
rake (13.0.6)
|
21
|
-
ruby-progressbar (1.13.0)
|
22
|
-
simplecov (0.22.0)
|
23
|
-
docile (~> 1.1)
|
24
|
-
simplecov-html (~> 0.11)
|
25
|
-
simplecov_json_formatter (~> 0.1)
|
26
|
-
simplecov-html (0.12.3)
|
27
|
-
simplecov_json_formatter (0.1.4)
|
28
|
-
|
29
|
-
PLATFORMS
|
30
|
-
x64-mingw32
|
31
|
-
|
32
|
-
DEPENDENCIES
|
33
|
-
awesome_print
|
34
|
-
bundler (>= 2)
|
35
|
-
media_types!
|
36
|
-
minitest
|
37
|
-
minitest-reporters
|
38
|
-
oj
|
39
|
-
rake
|
40
|
-
simplecov
|
41
|
-
|
42
|
-
BUNDLED WITH
|
43
|
-
2.1.4
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
media_types (2.3.2)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ansi (1.5.0)
|
10
|
+
awesome_print (1.9.2)
|
11
|
+
builder (3.2.4)
|
12
|
+
docile (1.4.0)
|
13
|
+
minitest (5.18.0)
|
14
|
+
minitest-reporters (1.6.0)
|
15
|
+
ansi
|
16
|
+
builder
|
17
|
+
minitest (>= 5.0)
|
18
|
+
ruby-progressbar
|
19
|
+
oj (3.14.2)
|
20
|
+
rake (13.0.6)
|
21
|
+
ruby-progressbar (1.13.0)
|
22
|
+
simplecov (0.22.0)
|
23
|
+
docile (~> 1.1)
|
24
|
+
simplecov-html (~> 0.11)
|
25
|
+
simplecov_json_formatter (~> 0.1)
|
26
|
+
simplecov-html (0.12.3)
|
27
|
+
simplecov_json_formatter (0.1.4)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
x64-mingw32
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
awesome_print
|
34
|
+
bundler (>= 2)
|
35
|
+
media_types!
|
36
|
+
minitest
|
37
|
+
minitest-reporters
|
38
|
+
oj
|
39
|
+
rake
|
40
|
+
simplecov
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
2.1.4
|
data/README.md
CHANGED
@@ -81,7 +81,7 @@ class Venue
|
|
81
81
|
|
82
82
|
version 1 do
|
83
83
|
attribute :name, String
|
84
|
-
attribute :coords, String
|
84
|
+
attribute :coords, String, optional: :loose
|
85
85
|
attribute :updated_at, String
|
86
86
|
|
87
87
|
link :self
|
@@ -94,8 +94,10 @@ class Venue
|
|
94
94
|
attribute :altitude, AllowNil(Numeric)
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
versions [1, 2] do |v|
|
98
98
|
collection :location do
|
99
|
+
link :extra if v > 1
|
100
|
+
|
99
101
|
attribute :latitude, Numeric
|
100
102
|
attribute :longitude, Numeric
|
101
103
|
attribute :altitude, AllowNil(Numeric)
|
@@ -465,8 +467,8 @@ class MyMedia
|
|
465
467
|
{ "foo": { "bar": "string" } }
|
466
468
|
FIXTURE
|
467
469
|
assert_fail '{"foo": {}}'
|
468
|
-
assert_fail '{"foo": null}'
|
469
|
-
assert_fail '{"foo": [42]}'
|
470
|
+
assert_fail '{"foo": null}', loose: true
|
471
|
+
assert_fail '{"foo": [42]}', loose: false
|
470
472
|
end
|
471
473
|
end
|
472
474
|
|
data/lib/media_types/errors.rb
CHANGED
@@ -15,5 +15,11 @@ module MediaTypes
|
|
15
15
|
super(format('Unable to change key type expectation for %<mod>s since its current expectation is already used', mod: mod.name))
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
class CollectionDefinitionNotFound < StandardError
|
20
|
+
def initialize(current, target)
|
21
|
+
super(format('Unable to use %<target>s as a collection inside %<current>s, no such schema has been defined.', current: current, target: target))
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
19
25
|
end
|
@@ -29,15 +29,15 @@ module MediaTypes
|
|
29
29
|
attr_accessor :output, :options, :rules
|
30
30
|
|
31
31
|
def allow_empty?
|
32
|
-
rules.allow_empty? || rules.required.empty?
|
32
|
+
rules.allow_empty? || rules.required(loose: options.loose).empty?
|
33
33
|
end
|
34
34
|
|
35
35
|
def raise_empty!(backtrace:, found:)
|
36
36
|
raise EmptyOutputError, format(
|
37
|
-
'
|
37
|
+
'The object at %<backtrace>s was empty but I expected contents. Required keys are: %<required>s.',
|
38
38
|
backtrace: backtrace.join('->'),
|
39
|
-
required: rules.required.keys,
|
40
|
-
found: (found.
|
39
|
+
required: rules.required(loose: options.loose).keys,
|
40
|
+
found: (found.respond_to? :keys) ? found.keys : found.class.name,
|
41
41
|
)
|
42
42
|
end
|
43
43
|
end
|
@@ -14,6 +14,7 @@ module MediaTypes
|
|
14
14
|
self.allow_empty = allow_empty
|
15
15
|
self.expected_type = expected_type
|
16
16
|
self.optional_keys = []
|
17
|
+
self.strict_keys = []
|
17
18
|
self.original_key_type = {}
|
18
19
|
|
19
20
|
self.default = MissingValidation.new
|
@@ -32,7 +33,11 @@ module MediaTypes
|
|
32
33
|
|
33
34
|
normalized_key = normalize_key(key)
|
34
35
|
__getobj__[normalized_key] = val
|
35
|
-
|
36
|
+
if optional == :loose
|
37
|
+
strict_keys << normalized_key
|
38
|
+
else
|
39
|
+
optional_keys << normalized_key if optional
|
40
|
+
end
|
36
41
|
original_key_type[normalized_key] = key.class
|
37
42
|
|
38
43
|
self
|
@@ -87,11 +92,16 @@ module MediaTypes
|
|
87
92
|
#
|
88
93
|
# @return [Array<Symbol>] required keys
|
89
94
|
#
|
90
|
-
def required
|
95
|
+
def required(loose:)
|
91
96
|
clone.tap do |cloned|
|
92
97
|
optional_keys.each do |key|
|
93
98
|
cloned.delete(key)
|
94
99
|
end
|
100
|
+
if loose
|
101
|
+
strict_keys.each do |key|
|
102
|
+
cloned.delete(key)
|
103
|
+
end
|
104
|
+
end
|
95
105
|
end
|
96
106
|
end
|
97
107
|
|
@@ -113,6 +123,9 @@ module MediaTypes
|
|
113
123
|
if rules.respond_to?(:optional_keys, true)
|
114
124
|
optional_keys.push(*rules.send(:optional_keys))
|
115
125
|
end
|
126
|
+
if rules.respond_to?(:strict_keys, true)
|
127
|
+
strict_keys.push(*rules.send(:strict_keys))
|
128
|
+
end
|
116
129
|
|
117
130
|
self
|
118
131
|
end
|
@@ -123,7 +136,7 @@ module MediaTypes
|
|
123
136
|
return "#{prefix}[Error]Depth limit reached[/Error]" if indent > 5_000
|
124
137
|
|
125
138
|
[
|
126
|
-
"#{prefix}[Rules n=#{keys.length} optional=#{optional_keys.length} allow_empty=#{allow_empty?}]",
|
139
|
+
"#{prefix}[Rules n=#{keys.length} optional=#{optional_keys.length} strict=#{strict_keys.length} allow_empty=#{allow_empty?}]",
|
127
140
|
"#{prefix} #{inspect_format_attribute(indent, '*', default)}",
|
128
141
|
*keys.map { |key| "#{prefix} #{inspect_format_attribute(indent, key)}" },
|
129
142
|
"#{prefix}[/Rules]"
|
@@ -162,7 +175,7 @@ module MediaTypes
|
|
162
175
|
|
163
176
|
private
|
164
177
|
|
165
|
-
attr_accessor :allow_empty, :optional_keys, :original_key_type
|
178
|
+
attr_accessor :allow_empty, :strict_keys, :optional_keys, :original_key_type
|
166
179
|
attr_writer :expected_type
|
167
180
|
|
168
181
|
def normalize_key(key)
|
@@ -26,7 +26,7 @@ module MediaTypes
|
|
26
26
|
return iterate(EMPTY_MARK)
|
27
27
|
end
|
28
28
|
|
29
|
-
required_rules = rules.required
|
29
|
+
required_rules = rules.required(loose: options.loose)
|
30
30
|
# noinspection RubyScope
|
31
31
|
result = iterate(->(key) { required_rules.remove(key) })
|
32
32
|
return result if required_rules.empty?
|
@@ -48,11 +48,13 @@ module MediaTypes
|
|
48
48
|
|
49
49
|
mark.call(key)
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
catch(:end) do
|
52
|
+
rules.get(key).validate!(
|
53
|
+
value,
|
54
|
+
options.trace(key),
|
55
|
+
context: context
|
56
|
+
)
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
@@ -3,18 +3,19 @@
|
|
3
3
|
module MediaTypes
|
4
4
|
class Scheme
|
5
5
|
class ValidationOptions
|
6
|
-
attr_accessor :exhaustive, :strict, :backtrace, :context, :expected_key_type
|
6
|
+
attr_accessor :exhaustive, :strict, :backtrace, :context, :expected_key_type, :loose
|
7
7
|
|
8
|
-
def initialize(context = {}, exhaustive: true, strict: true, backtrace: [], expected_key_type:)
|
8
|
+
def initialize(context = {}, exhaustive: true, strict: true, backtrace: [], loose: false, expected_key_type:)
|
9
9
|
self.exhaustive = exhaustive
|
10
10
|
self.strict = strict
|
11
11
|
self.backtrace = backtrace
|
12
12
|
self.context = context
|
13
13
|
self.expected_key_type = expected_key_type
|
14
|
+
self.loose = loose
|
14
15
|
end
|
15
16
|
|
16
17
|
def inspect
|
17
|
-
"backtrack: #{backtrace.inspect}, strict: #{strict.inspect}, exhaustive: #{exhaustive}, current_obj: #{scoped_output.to_json}"
|
18
|
+
"backtrack: #{backtrace.inspect}, strict: #{strict.inspect}, loose: #{loose}, exhaustive: #{exhaustive}, current_obj: #{scoped_output.to_json}"
|
18
19
|
end
|
19
20
|
|
20
21
|
def scoped_output
|
@@ -28,7 +29,7 @@ module MediaTypes
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def with_backtrace(backtrace)
|
31
|
-
ValidationOptions.new(context, exhaustive: exhaustive, strict: strict, backtrace: backtrace, expected_key_type: expected_key_type)
|
32
|
+
ValidationOptions.new(context, exhaustive: exhaustive, strict: strict, backtrace: backtrace, expected_key_type: expected_key_type, loose: loose)
|
32
33
|
end
|
33
34
|
|
34
35
|
def trace(*traces)
|
@@ -36,7 +37,7 @@ module MediaTypes
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def exhaustive!
|
39
|
-
ValidationOptions.new(context, exhaustive: true, strict: strict, backtrace: backtrace, expected_key_type: expected_key_type)
|
40
|
+
ValidationOptions.new(context, exhaustive: true, strict: strict, backtrace: backtrace, expected_key_type: expected_key_type, loose: loose)
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
data/lib/media_types/scheme.rb
CHANGED
@@ -51,13 +51,14 @@ module MediaTypes
|
|
51
51
|
end
|
52
52
|
|
53
53
|
class FixtureData
|
54
|
-
def initialize(caller:, fixture:, expect_to_pass:)
|
54
|
+
def initialize(caller:, fixture:, expect_to_pass:, loose:)
|
55
55
|
self.caller = caller
|
56
56
|
self.fixture = fixture
|
57
57
|
self.expect_to_pass = expect_to_pass
|
58
|
+
self.loose = loose
|
58
59
|
end
|
59
60
|
|
60
|
-
attr_accessor :caller, :fixture, :expect_to_pass
|
61
|
+
attr_accessor :caller, :fixture, :expect_to_pass, :loose
|
61
62
|
|
62
63
|
alias expect_to_pass? expect_to_pass
|
63
64
|
end
|
@@ -93,11 +94,13 @@ module MediaTypes
|
|
93
94
|
#
|
94
95
|
# @see MissingValidation
|
95
96
|
#
|
96
|
-
def initialize(allow_empty: false, expected_type: ::Object, &block)
|
97
|
+
def initialize(allow_empty: false, expected_type: ::Object, current_type: nil, registry: nil, &block)
|
97
98
|
self.rules = Rules.new(allow_empty: allow_empty, expected_type: expected_type)
|
98
99
|
self.type_attributes = {}
|
99
100
|
self.fixtures = []
|
100
101
|
self.asserted_sane = false
|
102
|
+
@registry = registry
|
103
|
+
@current_type = current_type
|
101
104
|
|
102
105
|
instance_exec(&block) if block_given?
|
103
106
|
end
|
@@ -269,7 +272,7 @@ module MediaTypes
|
|
269
272
|
return rules.default = Attribute.new(scheme)
|
270
273
|
end
|
271
274
|
|
272
|
-
rules.default = Scheme.new(allow_empty: allow_empty, expected_type: expected_type, &block)
|
275
|
+
rules.default = Scheme.new(allow_empty: allow_empty, expected_type: expected_type, registry: @registry, current_type: @current_type, &block)
|
273
276
|
end
|
274
277
|
|
275
278
|
##
|
@@ -347,10 +350,20 @@ module MediaTypes
|
|
347
350
|
# MyMedia.valid?({ foo: [{ required: 'test', number: 42 }, { required: 'other', number: 0 }] })
|
348
351
|
# # => true
|
349
352
|
#
|
350
|
-
def collection(key, scheme = nil, allow_empty: false, expected_type: ::Array, optional: false, &block)
|
353
|
+
def collection(key, scheme = nil, view: nil, allow_empty: false, expected_type: ::Array, optional: false, &block)
|
351
354
|
raise ConflictingTypeDefinitionError, 'You cannot apply a block to a non-hash typed collection, either remove the type or the block' if scheme != ::Hash && block_given? && !scheme.nil?
|
352
355
|
|
353
356
|
unless block_given?
|
357
|
+
if scheme.nil?
|
358
|
+
dependent_key = @current_type.as_key.dup
|
359
|
+
dependent_key[1] = view
|
360
|
+
|
361
|
+
unless @registry.has_key? dependent_key
|
362
|
+
raise Errors::CollectionDefinitionNotFound.new(@current_type.override_suffix('json').to_s, @current_type.view(view).override_suffix('json').to_s)
|
363
|
+
end
|
364
|
+
scheme = @registry[dependent_key]
|
365
|
+
end
|
366
|
+
|
354
367
|
return rules.add(
|
355
368
|
key,
|
356
369
|
EnumerationOfType.new(
|
@@ -362,7 +375,16 @@ module MediaTypes
|
|
362
375
|
)
|
363
376
|
end
|
364
377
|
|
365
|
-
rules.add(key, Scheme.new(allow_empty: allow_empty, expected_type: expected_type, &block), optional: optional)
|
378
|
+
rules.add(key, Scheme.new(allow_empty: allow_empty, expected_type: expected_type, registry: @registry, current_type: @current_type, &block), optional: optional)
|
379
|
+
end
|
380
|
+
|
381
|
+
##
|
382
|
+
# Expect an index of links
|
383
|
+
#
|
384
|
+
def index(optional: false)
|
385
|
+
collection(:_links, optional: optional) do
|
386
|
+
link :_self
|
387
|
+
end
|
366
388
|
end
|
367
389
|
|
368
390
|
##
|
@@ -431,14 +453,14 @@ module MediaTypes
|
|
431
453
|
].join("\n")
|
432
454
|
end
|
433
455
|
|
434
|
-
def assert_pass(fixture)
|
456
|
+
def assert_pass(fixture, loose: false)
|
435
457
|
reduced_stack = remove_current_dir_from_stack(caller_locations)
|
436
|
-
@fixtures << FixtureData.new(caller: reduced_stack.first, fixture: fixture, expect_to_pass: true)
|
458
|
+
@fixtures << FixtureData.new(caller: reduced_stack.first, fixture: fixture, expect_to_pass: true, loose: loose)
|
437
459
|
end
|
438
460
|
|
439
|
-
def assert_fail(fixture)
|
461
|
+
def assert_fail(fixture, loose: false)
|
440
462
|
reduced_stack = remove_current_dir_from_stack(caller_locations)
|
441
|
-
@fixtures << FixtureData.new(caller: reduced_stack.first, fixture: fixture, expect_to_pass: false)
|
463
|
+
@fixtures << FixtureData.new(caller: reduced_stack.first, fixture: fixture, expect_to_pass: false, loose: loose)
|
442
464
|
end
|
443
465
|
|
444
466
|
# Removes all calls originating in current dir from given stack
|
@@ -496,7 +518,7 @@ module MediaTypes
|
|
496
518
|
expected_key_type = expect_symbol_keys ? Symbol : String
|
497
519
|
|
498
520
|
begin
|
499
|
-
validate(json, expected_key_type: expected_key_type, backtrace: backtrace)
|
521
|
+
validate(json, expected_key_type: expected_key_type, backtrace: backtrace, loose: fixture_data.loose)
|
500
522
|
unless fixture_data.expect_to_pass?
|
501
523
|
raise UnexpectedValidationResultError.new(fixture_data.caller, 'No error encounterd whilst expecting to')
|
502
524
|
end
|
@@ -25,7 +25,7 @@ module MediaTypes
|
|
25
25
|
# @see Constructable
|
26
26
|
# @see Scheme
|
27
27
|
#
|
28
|
-
def initialize(media_type, registry = {}, scheme = Scheme.new, &block)
|
28
|
+
def initialize(media_type, registry = {}, scheme = Scheme.new(registry: registry, current_type: media_type), &block)
|
29
29
|
self.media_type = media_type
|
30
30
|
self.registry = registry.merge!(media_type.as_key => scheme)
|
31
31
|
self.scheme = scheme
|
@@ -89,6 +89,19 @@ module MediaTypes
|
|
89
89
|
Validations.new(media_type.version(version), registry, &block)
|
90
90
|
end
|
91
91
|
|
92
|
+
##
|
93
|
+
# Runs the block for multiple versions
|
94
|
+
#
|
95
|
+
# @param [Array] list of versions to run this on
|
96
|
+
#
|
97
|
+
def versions(versions, &block)
|
98
|
+
versions.each do |v|
|
99
|
+
Validations.new(media_type.version(v), registry) do
|
100
|
+
block(v)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
92
105
|
##
|
93
106
|
# Switches the inner block to a specific view
|
94
107
|
#
|
data/lib/media_types/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: media_types
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2
|
4
|
+
version: 2.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derk-Jan Karrenbeld
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: awesome_print
|
@@ -119,6 +119,8 @@ extensions: []
|
|
119
119
|
extra_rdoc_files: []
|
120
120
|
files:
|
121
121
|
- ".github/workflows/debian.yml"
|
122
|
+
- ".github/workflows/publish-bookworm.yml"
|
123
|
+
- ".github/workflows/publish-sid.yml"
|
122
124
|
- ".github/workflows/ruby.yml"
|
123
125
|
- ".gitignore"
|
124
126
|
- ".rubocop.yml"
|