media_types 0.6.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b854726c0783d1e7f27c66a195362a9df615500fb0bc329a935aa589d3451138
4
- data.tar.gz: 3699e6ea389a304a2a7970911a39ae269e0705b3283c8b816868f1ba76abc6fa
3
+ metadata.gz: 8285f897870c9a66139c5129db60c7abf31f870ef20103e6d21da6be99c139b8
4
+ data.tar.gz: a62bbb54c1e1de59cdbef2c98050f1aa0d040dc6aa15a7559aa8e016014d26b0
5
5
  SHA512:
6
- metadata.gz: 05a9e6bb7d2cf222148750830b4efb69fc73a7b955e4a7cf51de6dbe3ed4866187cc498c7b11c8060f0a3dc53eac76fa7bc762049ed6174bdaccc0ea3fa118c7
7
- data.tar.gz: c811c45d8ed2355a39f49f924d09a6a3326abe715e86b5ce4634d6a7dc1d2a18c565e6f1f6de60a769aa2fd6a863bd328da82a15ee3a8e6eaded39beab35856d
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
@@ -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
@@ -1,109 +1,114 @@
1
- PATH
2
- remote: .
3
- specs:
4
- media_types (0.6.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- actionpack (5.2.3)
10
- actionview (= 5.2.3)
11
- activesupport (= 5.2.3)
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.3)
17
- activesupport (= 5.2.3)
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.3)
23
- concurrent-ruby (~> 1.0, >= 1.0.2)
24
- i18n (>= 0.7, < 2)
25
- minitest (~> 5.1)
26
- tzinfo (~> 1.1)
27
- addressable (2.6.0)
28
- public_suffix (>= 2.0.2, < 4.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.4)
34
- docile (1.3.1)
35
- domain_name (0.5.20180417)
36
- unf (>= 0.0.5, < 1.0.0)
37
- erubi (1.8.0)
38
- http (4.1.1)
39
- addressable (~> 2.3)
40
- http-cookie (~> 1.0)
41
- http-form_data (~> 2.0)
42
- http_parser.rb (~> 0.6.0)
43
- http-cookie (1.0.3)
44
- domain_name (~> 0.5)
45
- http-form_data (2.1.1)
46
- http_parser.rb (0.6.0)
47
- i18n (1.6.0)
48
- concurrent-ruby (~> 1.0)
49
- json (2.2.0)
50
- loofah (2.2.3)
51
- crass (~> 1.0.2)
52
- nokogiri (>= 1.5.9)
53
- mini_portile2 (2.4.0)
54
- minitest (5.11.3)
55
- minitest-ci (3.4.0)
56
- minitest (>= 5.0.6)
57
- minitest-reporters (1.3.6)
58
- ansi
59
- builder
60
- minitest (>= 5.0)
61
- ruby-progressbar
62
- nokogiri (1.10.3)
63
- mini_portile2 (~> 2.4.0)
64
- nokogiri (1.10.3-x64-mingw32)
65
- mini_portile2 (~> 2.4.0)
66
- oj (3.7.12)
67
- public_suffix (3.0.3)
68
- rack (2.0.6)
69
- rack-test (1.1.0)
70
- rack (>= 1.0, < 3)
71
- rails-dom-testing (2.0.3)
72
- activesupport (>= 4.2.0)
73
- nokogiri (>= 1.6)
74
- rails-html-sanitizer (1.0.4)
75
- loofah (~> 2.2, >= 2.2.2)
76
- rake (12.3.2)
77
- ruby-progressbar (1.10.0)
78
- simplecov (0.16.1)
79
- docile (~> 1.1)
80
- json (>= 1.8, < 3)
81
- simplecov-html (~> 0.10.0)
82
- simplecov-html (0.10.2)
83
- thread_safe (0.3.6)
84
- tzinfo (1.2.5)
85
- thread_safe (~> 0.1)
86
- unf (0.1.4)
87
- unf_ext
88
- unf_ext (0.0.7.5)
89
- unf_ext (0.0.7.5-x64-mingw32)
90
-
91
- PLATFORMS
92
- ruby
93
- x64-mingw32
94
-
95
- DEPENDENCIES
96
- actionpack
97
- awesome_print
98
- bundler (~> 2)
99
- http
100
- media_types!
101
- minitest (~> 5.0)
102
- minitest-ci
103
- minitest-reporters
104
- oj
105
- rake (~> 12.3)
106
- simplecov
107
-
108
- BUNDLED WITH
109
- 2.0.1
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
- By default there are no media types registered or defined, except for an abstract base type.
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
- ## Definition
30
- You can define media types by inheriting from this base type, or create your own base type with a class method `.base_format` that is used to create the final media type string by injecting formatted parameters:
42
+ validations do
43
+ attribute :foo, String
44
+ end
45
+ end
46
+ end
47
+ ```
31
48
 
32
- - `%<type>s`: the type `media_type` received
33
- - `%<version>s`: the version, defaults to `:current_version`
34
- - `%<view>s`: the view, defaults to <empty>
35
- - `%<suffix>s`: the suffix
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.base_format
44
- 'application/vnd.mydomain.%<type>s.v%<version>s.%<view>s+%<suffix>s'
63
+ def self.organisation
64
+ 'mydomain'
45
65
  end
46
66
 
47
- media_type 'venue', defaults: { suffix: :json, version: 2 }
67
+ media_type 'venue', defaults: { suffix: :json }
48
68
 
49
69
  validations do
50
- attribute :name, String
51
- collection :location do
52
- attribute :latitude, Numeric
53
- attribute :longitude, Numeric
54
- attribute :altitude, AllowNil(Numeric)
55
- end
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
- link :self
58
- link :route, allow_nil: true
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 define a scheme using `current_scheme { }`, you may use any of the following dsl:
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 coerced in valid string to be used with `Content-Type` or `Accept`:
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.to_s
343
+ Venue.mime_type.identifier
322
344
  # => "application/vnd.mydomain.venue.v2+json"
323
345
 
324
- Venue.mime_type.version(1).to_s
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).to_s
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.to_s
355
+ Venue.mime_type.collection.identifier
334
356
  # => "application/vnd.mydomain.venue.v2.collection+json"
335
357
 
336
- Venue.mime_type.view('active').to_s
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
@@ -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
 
@@ -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
- to_str.hash
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
- Formatter.call(opts)
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
- __getobj__.valid?(
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
- __getobj__.validate!(
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
 
@@ -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, media_type = to_constructable, **opts)
30
- validations.find(String(media_type)).valid?(output, backtrace: ['.'], **opts)
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 validate!(output, media_type = to_constructable, **opts)
34
- validations.find(String(media_type)).validate(output, backtrace: ['.'], **opts)
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(String(media_type), -> { nil })
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
- private
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 media_type(name, defaults: {})
78
+ def identifier
79
+ to_constructable.to_s
80
+ end
53
81
 
54
- unless defined?(:base_format)
55
- define_method(:base_format) do
56
- raise format('Implement the class method "base_format" in %<klass>s', klass: self)
57
- end
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
- self.media_type_constructable = Constructable.new(self, format: base_format, type: name)
61
- .version(defaults.fetch(:version) { nil })
62
- .suffix(defaults.fetch(:suffix) { nil })
63
- .view(defaults.fetch(:view) { nil })
64
- self
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)
@@ -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.to_s => scheme)
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(String(media_type)) do
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MediaTypes
4
- VERSION = '0.6.2'
4
+ VERSION = '1.0.0'
5
5
  end
@@ -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', '~> 12.3'
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.6.2
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: 2019-05-10 00:00:00.000000000 Z
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: '12.3'
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: '12.3'
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