media_types 0.6.2 → 1.0.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 +20 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +114 -109
- data/README.md +105 -25
- data/lib/media_types.rb +13 -0
- data/lib/media_types/.dsl.rb.swp +0 -0
- data/lib/media_types/constructable.rb +25 -5
- data/lib/media_types/dsl.rb +64 -16
- data/lib/media_types/scheme.rb +37 -0
- data/lib/media_types/validations.rb +4 -2
- data/lib/media_types/version.rb +1 -1
- data/media_types.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8285f897870c9a66139c5129db60c7abf31f870ef20103e6d21da6be99c139b8
|
|
4
|
+
data.tar.gz: a62bbb54c1e1de59cdbef2c98050f1aa0d040dc6aa15a7559aa8e016014d26b0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 132ca0f0f8acf1dcd915c75c7b7b283ee3cc3a896d3fb53acffd8adc958300535bf7dde1d030e26865b317905c5da62ad18e507dbb1f04829ef5582bd4b187b3
|
|
7
|
+
data.tar.gz: ee0d5bd2f3e51f492d5530bbfa45e1acfb067ebc2a690a4b4cdf02d1284792bed60eebfaa6757c0b8a36fb520566932da784c9434d235fa59fb7c58f97231da3
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on: [push]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v1
|
|
12
|
+
- name: Set up Ruby 2.6
|
|
13
|
+
uses: actions/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
ruby-version: 2.6.x
|
|
16
|
+
- name: Build and test with Rake
|
|
17
|
+
run: |
|
|
18
|
+
gem install bundler
|
|
19
|
+
bundle install --jobs 4 --retry 3
|
|
20
|
+
bundle exec rake
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# 1.0.0
|
|
2
|
+
- Added the ability to do inline tests when defining validations using `assert_pass '<json>'` and `assert_fail '<json>'`.
|
|
3
|
+
- `media_type` has been replaced with `use_name`.
|
|
4
|
+
- It is no longer possible to set a default version. Please use `version <x> do` instead.
|
|
5
|
+
- 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.
|
|
6
|
+
- `self.base_format` has been replaced by `identifier_format do |type:, view:, version:, suffix:|`.
|
|
7
|
+
- Added the `empty` validation to mark an empty object as valid.
|
|
8
|
+
- Added the `identifier` function to get the [Media Type Identifier](https://en.wikipedia.org/wiki/Media_type) for the validator.
|
|
9
|
+
- Added `version(x)` and `view(x)` functions.
|
|
10
|
+
- Added an `available_validations` functions that returns all defined validations.
|
|
11
|
+
- Fixed an issue where validations could accidentally merge if defined with a bad `base_format`.
|
|
12
|
+
- Fixed an issue where undefined validations would accept an empty object.
|
|
13
|
+
|
|
1
14
|
# 0.6.2
|
|
2
15
|
|
|
3
16
|
- Fix handling empty collections
|
data/Gemfile.lock
CHANGED
|
@@ -1,109 +1,114 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
media_types (0.
|
|
5
|
-
|
|
6
|
-
GEM
|
|
7
|
-
remote: https://rubygems.org/
|
|
8
|
-
specs:
|
|
9
|
-
actionpack (5.2.
|
|
10
|
-
actionview (= 5.2.
|
|
11
|
-
activesupport (= 5.2.
|
|
12
|
-
rack (~> 2.0)
|
|
13
|
-
rack-test (>= 0.6.3)
|
|
14
|
-
rails-dom-testing (~> 2.0)
|
|
15
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
16
|
-
actionview (5.2.
|
|
17
|
-
activesupport (= 5.2.
|
|
18
|
-
builder (~> 3.1)
|
|
19
|
-
erubi (~> 1.4)
|
|
20
|
-
rails-dom-testing (~> 2.0)
|
|
21
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
22
|
-
activesupport (5.2.
|
|
23
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
24
|
-
i18n (>= 0.7, < 2)
|
|
25
|
-
minitest (~> 5.1)
|
|
26
|
-
tzinfo (~> 1.1)
|
|
27
|
-
addressable (2.
|
|
28
|
-
public_suffix (>= 2.0.2, <
|
|
29
|
-
ansi (1.5.0)
|
|
30
|
-
awesome_print (1.8.0)
|
|
31
|
-
builder (3.2.3)
|
|
32
|
-
concurrent-ruby (1.1.5)
|
|
33
|
-
crass (1.0.
|
|
34
|
-
docile (1.3.
|
|
35
|
-
domain_name (0.5.
|
|
36
|
-
unf (>= 0.0.5, < 1.0.0)
|
|
37
|
-
erubi (1.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
http
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
media_types (1.0.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
actionpack (5.2.4)
|
|
10
|
+
actionview (= 5.2.4)
|
|
11
|
+
activesupport (= 5.2.4)
|
|
12
|
+
rack (~> 2.0)
|
|
13
|
+
rack-test (>= 0.6.3)
|
|
14
|
+
rails-dom-testing (~> 2.0)
|
|
15
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
16
|
+
actionview (5.2.4)
|
|
17
|
+
activesupport (= 5.2.4)
|
|
18
|
+
builder (~> 3.1)
|
|
19
|
+
erubi (~> 1.4)
|
|
20
|
+
rails-dom-testing (~> 2.0)
|
|
21
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
22
|
+
activesupport (5.2.4)
|
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
24
|
+
i18n (>= 0.7, < 2)
|
|
25
|
+
minitest (~> 5.1)
|
|
26
|
+
tzinfo (~> 1.1)
|
|
27
|
+
addressable (2.7.0)
|
|
28
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
29
|
+
ansi (1.5.0)
|
|
30
|
+
awesome_print (1.8.0)
|
|
31
|
+
builder (3.2.3)
|
|
32
|
+
concurrent-ruby (1.1.5)
|
|
33
|
+
crass (1.0.5)
|
|
34
|
+
docile (1.3.2)
|
|
35
|
+
domain_name (0.5.20190701)
|
|
36
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
37
|
+
erubi (1.9.0)
|
|
38
|
+
ffi (1.11.1)
|
|
39
|
+
ffi (1.11.1-x64-mingw32)
|
|
40
|
+
ffi-compiler (1.0.1)
|
|
41
|
+
ffi (>= 1.0.0)
|
|
42
|
+
rake
|
|
43
|
+
http (4.2.0)
|
|
44
|
+
addressable (~> 2.3)
|
|
45
|
+
http-cookie (~> 1.0)
|
|
46
|
+
http-form_data (~> 2.0)
|
|
47
|
+
http-parser (~> 1.2.0)
|
|
48
|
+
http-cookie (1.0.3)
|
|
49
|
+
domain_name (~> 0.5)
|
|
50
|
+
http-form_data (2.1.1)
|
|
51
|
+
http-parser (1.2.1)
|
|
52
|
+
ffi-compiler (>= 1.0, < 2.0)
|
|
53
|
+
i18n (1.7.0)
|
|
54
|
+
concurrent-ruby (~> 1.0)
|
|
55
|
+
json (2.2.0)
|
|
56
|
+
loofah (2.4.0)
|
|
57
|
+
crass (~> 1.0.2)
|
|
58
|
+
nokogiri (>= 1.5.9)
|
|
59
|
+
mini_portile2 (2.4.0)
|
|
60
|
+
minitest (5.13.0)
|
|
61
|
+
minitest-ci (3.4.0)
|
|
62
|
+
minitest (>= 5.0.6)
|
|
63
|
+
minitest-reporters (1.4.2)
|
|
64
|
+
ansi
|
|
65
|
+
builder
|
|
66
|
+
minitest (>= 5.0)
|
|
67
|
+
ruby-progressbar
|
|
68
|
+
nokogiri (1.10.7)
|
|
69
|
+
mini_portile2 (~> 2.4.0)
|
|
70
|
+
nokogiri (1.10.7-x64-mingw32)
|
|
71
|
+
mini_portile2 (~> 2.4.0)
|
|
72
|
+
oj (3.10.0)
|
|
73
|
+
public_suffix (4.0.1)
|
|
74
|
+
rack (2.0.7)
|
|
75
|
+
rack-test (1.1.0)
|
|
76
|
+
rack (>= 1.0, < 3)
|
|
77
|
+
rails-dom-testing (2.0.3)
|
|
78
|
+
activesupport (>= 4.2.0)
|
|
79
|
+
nokogiri (>= 1.6)
|
|
80
|
+
rails-html-sanitizer (1.3.0)
|
|
81
|
+
loofah (~> 2.3)
|
|
82
|
+
rake (13.0.1)
|
|
83
|
+
ruby-progressbar (1.10.1)
|
|
84
|
+
simplecov (0.17.1)
|
|
85
|
+
docile (~> 1.1)
|
|
86
|
+
json (>= 1.8, < 3)
|
|
87
|
+
simplecov-html (~> 0.10.0)
|
|
88
|
+
simplecov-html (0.10.2)
|
|
89
|
+
thread_safe (0.3.6)
|
|
90
|
+
tzinfo (1.2.5)
|
|
91
|
+
thread_safe (~> 0.1)
|
|
92
|
+
unf (0.1.4)
|
|
93
|
+
unf_ext
|
|
94
|
+
unf_ext (0.0.7.6)
|
|
95
|
+
|
|
96
|
+
PLATFORMS
|
|
97
|
+
ruby
|
|
98
|
+
x64-mingw32
|
|
99
|
+
|
|
100
|
+
DEPENDENCIES
|
|
101
|
+
actionpack
|
|
102
|
+
awesome_print
|
|
103
|
+
bundler (~> 2)
|
|
104
|
+
http
|
|
105
|
+
media_types!
|
|
106
|
+
minitest (~> 5.0)
|
|
107
|
+
minitest-ci
|
|
108
|
+
minitest-reporters
|
|
109
|
+
oj
|
|
110
|
+
rake (~> 13.0)
|
|
111
|
+
simplecov
|
|
112
|
+
|
|
113
|
+
BUNDLED WITH
|
|
114
|
+
2.0.1
|
data/README.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
Media Types based on scheme, with versioning, views, suffixes and validations. Integrations available for [Rails](https://github.com/rails/rails) / ActionPack and [http.rb](https://github.com/httprb/http).
|
|
8
8
|
|
|
9
|
+
This library makes it easy to define schemas that can be used to validate JSON objects based on their Content-Type.
|
|
10
|
+
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
11
13
|
Add this line to your application's Gemfile:
|
|
@@ -24,15 +26,33 @@ Or install it yourself as:
|
|
|
24
26
|
|
|
25
27
|
## Usage
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
Define a validation:
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
require 'media_types'
|
|
33
|
+
|
|
34
|
+
module Acme
|
|
35
|
+
MediaTypes::set_organisation Acme, 'acme'
|
|
36
|
+
|
|
37
|
+
class FooValidator
|
|
38
|
+
include MediaTypes::Dsl
|
|
39
|
+
|
|
40
|
+
use_name 'foo'
|
|
28
41
|
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
validations do
|
|
43
|
+
attribute :foo, String
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
```
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
Validate an object:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
Acme::FooValidator.validate!({ foo: 'bar' })
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Full example
|
|
36
56
|
|
|
37
57
|
```Ruby
|
|
38
58
|
require 'media_types'
|
|
@@ -40,22 +60,24 @@ require 'media_types'
|
|
|
40
60
|
class Venue
|
|
41
61
|
include MediaTypes::Dsl
|
|
42
62
|
|
|
43
|
-
def self.
|
|
44
|
-
'
|
|
63
|
+
def self.organisation
|
|
64
|
+
'mydomain'
|
|
45
65
|
end
|
|
46
66
|
|
|
47
|
-
media_type 'venue', defaults: { suffix: :json
|
|
67
|
+
media_type 'venue', defaults: { suffix: :json }
|
|
48
68
|
|
|
49
69
|
validations do
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
version 2 do
|
|
71
|
+
attribute :name, String
|
|
72
|
+
collection :location do
|
|
73
|
+
attribute :latitude, Numeric
|
|
74
|
+
attribute :longitude, Numeric
|
|
75
|
+
attribute :altitude, AllowNil(Numeric)
|
|
76
|
+
end
|
|
56
77
|
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
link :self
|
|
79
|
+
link :route, allow_nil: true
|
|
80
|
+
end
|
|
59
81
|
|
|
60
82
|
version 1 do
|
|
61
83
|
attribute :name, String
|
|
@@ -97,7 +119,7 @@ end
|
|
|
97
119
|
|
|
98
120
|
## Schema Definitions
|
|
99
121
|
|
|
100
|
-
If you
|
|
122
|
+
If you include 'MediaTypes::Dsl' in your class you can use the following functions within a `validation do` block to define your schema:
|
|
101
123
|
|
|
102
124
|
### `attribute`
|
|
103
125
|
|
|
@@ -315,25 +337,25 @@ expected_object.valid?([{ foo: 'string' }])
|
|
|
315
337
|
```
|
|
316
338
|
|
|
317
339
|
## Formatting for headers
|
|
318
|
-
Any media type object can be
|
|
340
|
+
Any media type object can be converted in valid string to be used with `Content-Type` or `Accept`:
|
|
319
341
|
|
|
320
342
|
```Ruby
|
|
321
|
-
Venue.mime_type.
|
|
343
|
+
Venue.mime_type.identifier
|
|
322
344
|
# => "application/vnd.mydomain.venue.v2+json"
|
|
323
345
|
|
|
324
|
-
Venue.mime_type.version(1).
|
|
346
|
+
Venue.mime_type.version(1).identifier
|
|
325
347
|
# => "application/vnd.mydomain.venue.v1+json"
|
|
326
348
|
|
|
327
|
-
Venue.mime_type.version(1).suffix(:xml).
|
|
349
|
+
Venue.mime_type.version(1).suffix(:xml).identifier
|
|
328
350
|
# => "application/vnd.mydomain.venue.v1+xml"
|
|
329
351
|
|
|
330
352
|
Venue.mime_type.to_s(0.2)
|
|
331
353
|
# => "application/vnd.mydomain.venue.v2+json; q=0.2"
|
|
332
354
|
|
|
333
|
-
Venue.mime_type.collection.
|
|
355
|
+
Venue.mime_type.collection.identifier
|
|
334
356
|
# => "application/vnd.mydomain.venue.v2.collection+json"
|
|
335
357
|
|
|
336
|
-
Venue.mime_type.view('active').
|
|
358
|
+
Venue.mime_type.view('active').identifier
|
|
337
359
|
# => "application/vnd.mydomain.venue.v2.active+json"
|
|
338
360
|
```
|
|
339
361
|
|
|
@@ -374,6 +396,64 @@ Load the `http` integration and call `.register` on all media types you want to
|
|
|
374
396
|
|
|
375
397
|
Currently uses `oj` under the hood and this can not be changed.
|
|
376
398
|
|
|
399
|
+
## API
|
|
400
|
+
|
|
401
|
+
A defined schema has the following functions available:
|
|
402
|
+
|
|
403
|
+
### `valid?`
|
|
404
|
+
|
|
405
|
+
Example: `Venue.valid?({ foo: 'bar' })`
|
|
406
|
+
|
|
407
|
+
Allows passing in validation options as a second parameter.
|
|
408
|
+
|
|
409
|
+
### `validate!`
|
|
410
|
+
|
|
411
|
+
Example: `Venue.validate!({ foo: 'bar' })`
|
|
412
|
+
|
|
413
|
+
Allows passing in validation options as a second parameter.
|
|
414
|
+
|
|
415
|
+
### `validatable?`
|
|
416
|
+
|
|
417
|
+
Example: `Venue.version(42).validatable?`
|
|
418
|
+
|
|
419
|
+
Tests wether the current configuration of the schema has a validation defined.
|
|
420
|
+
|
|
421
|
+
### `register`
|
|
422
|
+
|
|
423
|
+
Example: `Venue.register`
|
|
424
|
+
|
|
425
|
+
Registers the media type to the registry.
|
|
426
|
+
|
|
427
|
+
### `view`
|
|
428
|
+
|
|
429
|
+
Example: `Venue.view('create')`
|
|
430
|
+
|
|
431
|
+
Returns a schema validator configured with the specified view.
|
|
432
|
+
|
|
433
|
+
### `version`
|
|
434
|
+
|
|
435
|
+
Example: `Venue.version(42)`
|
|
436
|
+
|
|
437
|
+
Returns a schema validator configured with the specified version.
|
|
438
|
+
|
|
439
|
+
### `suffix`
|
|
440
|
+
|
|
441
|
+
Example: `Venue.suffix(:json)`
|
|
442
|
+
|
|
443
|
+
Returns a schema validator configured with the specified suffix.
|
|
444
|
+
|
|
445
|
+
### `identifier`
|
|
446
|
+
|
|
447
|
+
Example: `Venue.version(2).identifier` (returns `'application/vnd.application.venue.v2'`)
|
|
448
|
+
|
|
449
|
+
Returns the IANA compatible [Media Type Identifier](https://en.wikipedia.org/wiki/Media_type) for the configured schema.
|
|
450
|
+
|
|
451
|
+
### `available_validations`
|
|
452
|
+
|
|
453
|
+
Example: `Venue.available_validations`
|
|
454
|
+
|
|
455
|
+
Returns a list of all the schemas that are defined.
|
|
456
|
+
|
|
377
457
|
## Related
|
|
378
458
|
|
|
379
459
|
- [`MediaTypes::Serialization`](https://github.com/XPBytes/media_types-serialization): :cyclone: Add media types supported serialization using your favourite serializer
|
data/lib/media_types.rb
CHANGED
|
@@ -12,6 +12,19 @@ require 'media_types/views'
|
|
|
12
12
|
require 'media_types/integrations'
|
|
13
13
|
|
|
14
14
|
module MediaTypes
|
|
15
|
+
def self.set_organisation(mod, organisation)
|
|
16
|
+
@organisation_prefixes ||= {}
|
|
17
|
+
@organisation_prefixes[mod.name] = organisation
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.get_organisation(mod)
|
|
21
|
+
name = mod.name
|
|
22
|
+
prefixes = @organisation_prefixes.keys.select { |p| name.start_with? p }
|
|
23
|
+
return nil unless prefixes.any?
|
|
24
|
+
best = prefixes.max_by { |p| p.length }
|
|
25
|
+
|
|
26
|
+
@organisation_prefixes[best]
|
|
27
|
+
end
|
|
15
28
|
end
|
|
16
29
|
|
|
17
30
|
|
|
Binary file
|
|
@@ -73,20 +73,35 @@ module MediaTypes
|
|
|
73
73
|
to_str.split(pattern, *limit)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
def as_key
|
|
77
|
+
[type, view, version, suffix]
|
|
78
|
+
end
|
|
79
|
+
|
|
76
80
|
def hash
|
|
77
|
-
|
|
81
|
+
as_key.hash
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def to_str(qualifier = nil)
|
|
81
|
-
# TODO: remove warning by slicing out these arguments if they don't appear in the format
|
|
82
85
|
qualified(
|
|
83
86
|
qualifier,
|
|
84
|
-
|
|
87
|
+
__getobj__.media_type_name_for.call(
|
|
88
|
+
type: opts[:type],
|
|
89
|
+
view: opts[:view],
|
|
90
|
+
version: opts[:version],
|
|
91
|
+
suffix: opts[:suffix],
|
|
92
|
+
)
|
|
85
93
|
)
|
|
86
94
|
end
|
|
95
|
+
|
|
96
|
+
def available_validations
|
|
97
|
+
return [] if !validatable?
|
|
98
|
+
[self]
|
|
99
|
+
end
|
|
87
100
|
|
|
88
101
|
def valid?(output, **validation_opts)
|
|
89
|
-
|
|
102
|
+
raise ArgumentError, "Unable to validate #{to_s} type without a corresponding validation. Please mark objects that should be empty with 'empty'." unless validatable?
|
|
103
|
+
|
|
104
|
+
__getobj__.valid_unsafe?(
|
|
90
105
|
output,
|
|
91
106
|
self,
|
|
92
107
|
**validation_opts
|
|
@@ -94,7 +109,9 @@ module MediaTypes
|
|
|
94
109
|
end
|
|
95
110
|
|
|
96
111
|
def validate!(output, **validation_opts)
|
|
97
|
-
|
|
112
|
+
raise ArgumentError, "Unable to validate #{to_s} type without a corresponding validation. Please mark objects that should be empty with 'empty'." unless validatable?
|
|
113
|
+
|
|
114
|
+
__getobj__.validate_unsafe!(
|
|
98
115
|
output,
|
|
99
116
|
self,
|
|
100
117
|
**validation_opts
|
|
@@ -102,11 +119,14 @@ module MediaTypes
|
|
|
102
119
|
end
|
|
103
120
|
|
|
104
121
|
def validatable?
|
|
122
|
+
return false unless media_type_combinations.include? as_key
|
|
123
|
+
|
|
105
124
|
__getobj__.validatable?(self)
|
|
106
125
|
end
|
|
107
126
|
|
|
108
127
|
alias inspect to_str
|
|
109
128
|
alias to_s to_str
|
|
129
|
+
alias identifier to_str
|
|
110
130
|
|
|
111
131
|
private
|
|
112
132
|
|
data/lib/media_types/dsl.rb
CHANGED
|
@@ -7,14 +7,18 @@ require 'media_types/validations'
|
|
|
7
7
|
|
|
8
8
|
module MediaTypes
|
|
9
9
|
module Dsl
|
|
10
|
+
|
|
10
11
|
def self.included(base)
|
|
11
12
|
base.extend ClassMethods
|
|
12
13
|
base.class_eval do
|
|
13
14
|
class << self
|
|
15
|
+
attr_accessor :media_type_name_for, :media_type_combinations
|
|
16
|
+
|
|
14
17
|
private
|
|
15
18
|
|
|
16
19
|
attr_accessor :media_type_constructable, :symbol_base, :media_type_registrar, :media_type_validations
|
|
17
20
|
end
|
|
21
|
+
base.media_type_combinations = Set.new
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
|
|
@@ -26,18 +30,26 @@ module MediaTypes
|
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
|
|
29
|
-
def valid?(output,
|
|
30
|
-
|
|
33
|
+
def valid?(output, **opts)
|
|
34
|
+
to_constructable.valid?(output, **opts)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def valid_unsafe?(output, media_type = to_constructable, **opts)
|
|
38
|
+
validations.find(media_type).valid?(output, backtrace: ['.'], **opts)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def validate!(output, **opts)
|
|
42
|
+
to_constructable.validate!(output, **opts)
|
|
31
43
|
end
|
|
32
44
|
|
|
33
|
-
def
|
|
34
|
-
validations.find(
|
|
45
|
+
def validate_unsafe!(output, media_type = to_constructable, **opts)
|
|
46
|
+
validations.find(media_type).validate(output, backtrace: ['.'], **opts)
|
|
35
47
|
end
|
|
36
48
|
|
|
37
49
|
def validatable?(media_type = to_constructable)
|
|
38
50
|
return false unless validations
|
|
39
51
|
|
|
40
|
-
validations.find(
|
|
52
|
+
validations.find(media_type, -> { nil })
|
|
41
53
|
end
|
|
42
54
|
|
|
43
55
|
def register
|
|
@@ -46,22 +58,58 @@ module MediaTypes
|
|
|
46
58
|
registerable
|
|
47
59
|
end
|
|
48
60
|
end
|
|
61
|
+
|
|
62
|
+
def view(v)
|
|
63
|
+
to_constructable.view(v)
|
|
64
|
+
end
|
|
65
|
+
def version(v)
|
|
66
|
+
to_constructable.version(v)
|
|
67
|
+
end
|
|
68
|
+
def suffix(s)
|
|
69
|
+
to_constructable.suffix(s)
|
|
70
|
+
end
|
|
49
71
|
|
|
50
|
-
|
|
72
|
+
def identifier_format
|
|
73
|
+
self.media_type_name_for = Proc.new do |type:, view:, version:, suffix:|
|
|
74
|
+
yield(type: type, view: view, version: version, suffix: suffix)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
51
77
|
|
|
52
|
-
def
|
|
78
|
+
def identifier
|
|
79
|
+
to_constructable.to_s
|
|
80
|
+
end
|
|
53
81
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
82
|
+
def available_validations
|
|
83
|
+
self.media_type_combinations.map do |a|
|
|
84
|
+
_, view, version, suffix = a
|
|
85
|
+
view(view).version(version).suffix(suffix)
|
|
58
86
|
end
|
|
87
|
+
end
|
|
59
88
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def use_name(name, defaults: {})
|
|
92
|
+
if self.media_type_name_for.nil?
|
|
93
|
+
self.media_type_name_for = Proc.new do |type:, view:, version:, suffix:|
|
|
94
|
+
resolved_org = nil
|
|
95
|
+
if defined?(organisation)
|
|
96
|
+
resolved_org = organisation
|
|
97
|
+
else
|
|
98
|
+
resolved_org = MediaTypes::get_organisation(self)
|
|
99
|
+
|
|
100
|
+
raise format('Implement the class method "organisation" in %<klass>s or specify a global organisation using MediaTypes::set_organisation', klass: self) if resolved_org.nil?
|
|
101
|
+
end
|
|
102
|
+
raise ArgumentError, 'Unable to create a name for a schema with a nil name.' if type.nil?
|
|
103
|
+
raise ArgumentError, 'Unable to create a name for a schema with a nil organisation.' if resolved_org.nil?
|
|
104
|
+
|
|
105
|
+
result = "application/vnd.#{resolved_org}.#{type}"
|
|
106
|
+
result += ".v#{version}" unless version.nil?
|
|
107
|
+
result += ".#{view}" unless view.nil?
|
|
108
|
+
result += "+#{suffix}" unless suffix.nil?
|
|
109
|
+
result
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
self.media_type_constructable = Constructable.new(self, type: name).suffix(defaults.fetch(:suffix) { nil })
|
|
65
113
|
end
|
|
66
114
|
|
|
67
115
|
def defaults(&block)
|
data/lib/media_types/scheme.rb
CHANGED
|
@@ -17,7 +17,12 @@ require 'media_types/scheme/output_empty_guard'
|
|
|
17
17
|
require 'media_types/scheme/output_type_guard'
|
|
18
18
|
require 'media_types/scheme/rules_exhausted_guard'
|
|
19
19
|
|
|
20
|
+
require 'json'
|
|
21
|
+
|
|
20
22
|
module MediaTypes
|
|
23
|
+
class AssertionError < StandardError
|
|
24
|
+
end
|
|
25
|
+
|
|
21
26
|
##
|
|
22
27
|
# Media Type Schemes can validate content to a media type, by itself. Used by the `validations` dsl.
|
|
23
28
|
#
|
|
@@ -346,6 +351,21 @@ module MediaTypes
|
|
|
346
351
|
end.link(*args, **opts, &block)
|
|
347
352
|
end
|
|
348
353
|
|
|
354
|
+
##
|
|
355
|
+
# Mark object as a valid empty object
|
|
356
|
+
#
|
|
357
|
+
# @example Empty object
|
|
358
|
+
#
|
|
359
|
+
# class MyMedia
|
|
360
|
+
# include MediaTypes::Dsl
|
|
361
|
+
#
|
|
362
|
+
# validations do
|
|
363
|
+
# empty
|
|
364
|
+
# end
|
|
365
|
+
# end
|
|
366
|
+
def empty
|
|
367
|
+
end
|
|
368
|
+
|
|
349
369
|
def inspect(indentation = 0)
|
|
350
370
|
tabs = ' ' * indentation
|
|
351
371
|
[
|
|
@@ -355,6 +375,23 @@ module MediaTypes
|
|
|
355
375
|
].join("\n")
|
|
356
376
|
end
|
|
357
377
|
|
|
378
|
+
def assert_pass(fixture)
|
|
379
|
+
json = JSON.parse(fixture)
|
|
380
|
+
|
|
381
|
+
validate(json)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def assert_fail(fixture)
|
|
385
|
+
json = JSON.parse(fixture)
|
|
386
|
+
|
|
387
|
+
begin
|
|
388
|
+
validate(json)
|
|
389
|
+
rescue MediaTypes::Scheme::ValidationError
|
|
390
|
+
return
|
|
391
|
+
end
|
|
392
|
+
raise AssertionError
|
|
393
|
+
end
|
|
394
|
+
|
|
358
395
|
private
|
|
359
396
|
|
|
360
397
|
attr_accessor :rules
|
|
@@ -25,7 +25,7 @@ module MediaTypes
|
|
|
25
25
|
#
|
|
26
26
|
def initialize(media_type, registry = {}, scheme = Scheme.new, &block)
|
|
27
27
|
self.media_type = media_type
|
|
28
|
-
self.registry = registry.merge!(media_type.
|
|
28
|
+
self.registry = registry.merge!(media_type.as_key => scheme)
|
|
29
29
|
self.scheme = scheme
|
|
30
30
|
|
|
31
31
|
instance_exec(&block) if block_given?
|
|
@@ -39,13 +39,15 @@ module MediaTypes
|
|
|
39
39
|
# @return [Scheme] the scheme for the given +media_type+
|
|
40
40
|
#
|
|
41
41
|
def find(media_type, default = -> { Scheme.new(allow_empty: true) { not_strict } })
|
|
42
|
-
registry.fetch(
|
|
42
|
+
registry.fetch(media_type.as_key) do
|
|
43
43
|
default.call
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def method_missing(method_name, *arguments, &block)
|
|
48
48
|
if scheme.respond_to?(method_name)
|
|
49
|
+
media_type.__getobj__.media_type_combinations.add(media_type.as_key)
|
|
50
|
+
|
|
49
51
|
return scheme.send(method_name, *arguments, &block)
|
|
50
52
|
end
|
|
51
53
|
|
data/lib/media_types/version.rb
CHANGED
data/media_types.gemspec
CHANGED
|
@@ -31,6 +31,6 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.add_development_dependency 'minitest-ci'
|
|
32
32
|
spec.add_development_dependency 'minitest-reporters'
|
|
33
33
|
spec.add_development_dependency 'oj'
|
|
34
|
-
spec.add_development_dependency 'rake', '~>
|
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
35
35
|
spec.add_development_dependency 'simplecov'
|
|
36
36
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: media_types
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Derk-Jan Karrenbeld
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-01-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -128,14 +128,14 @@ dependencies:
|
|
|
128
128
|
requirements:
|
|
129
129
|
- - "~>"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
131
|
+
version: '13.0'
|
|
132
132
|
type: :development
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - "~>"
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
138
|
+
version: '13.0'
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: simplecov
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -158,6 +158,7 @@ executables: []
|
|
|
158
158
|
extensions: []
|
|
159
159
|
extra_rdoc_files: []
|
|
160
160
|
files:
|
|
161
|
+
- ".github/workflows/ruby.yml"
|
|
161
162
|
- ".gitignore"
|
|
162
163
|
- ".rubocop.yml"
|
|
163
164
|
- ".travis.yml"
|
|
@@ -169,6 +170,7 @@ files:
|
|
|
169
170
|
- bin/console
|
|
170
171
|
- bin/setup
|
|
171
172
|
- lib/media_types.rb
|
|
173
|
+
- lib/media_types/.dsl.rb.swp
|
|
172
174
|
- lib/media_types/constructable.rb
|
|
173
175
|
- lib/media_types/defaults.rb
|
|
174
176
|
- lib/media_types/dsl.rb
|