ivy-serializers 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 53cc58ca39399bdcc72ecb47fd0aeecac296be43
4
- data.tar.gz: ad5208023b028606b093a3056added2c7574ba82
3
+ metadata.gz: c4f730c6f599627a61aa2d51d349ac7bfa0b893a
4
+ data.tar.gz: e2b0e59978d005a5ffc7decb845f8d782965d061
5
5
  SHA512:
6
- metadata.gz: 329051d45ee2fbbd118e992ffcd83e69fcac05128e96606ba2fdd64e53ee1b2b74ad75649d1c48c32fddd83fa04c121706b6f0b79b15eb67171f34e368f0cb12
7
- data.tar.gz: 6a6540f204ccb754c0c0846924708e4ee0a5caed80827ef1abcea481176c4d7f2a8a3f8c44ed9f45deb93f203d7b450b3098fde5ab003029a75f9445b998880e
6
+ metadata.gz: eb1814bce93d75c634a8ef055c7ea494c5d665a379a3ba0abcf790b0aece91b2f8b8dc68ed12f330c4aca260de48b3f55d49659362d589eaae91fc23a8909ae6
7
+ data.tar.gz: 4aee5deab59fcf959d77f46fb9c8cd928c78c6d6fbaaa699b67e4a40fd9bcf33055c16c4bb8b2f5f95ce9b0bf789d9d280eeae086628e643fa61582a5921a01a
@@ -1,8 +1,9 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.2.2
5
- - 1.9.3
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
6
7
 
7
8
  cache: bundler
8
9
 
@@ -0,0 +1,34 @@
1
+ # ivy-serializers
2
+
3
+ See [changes since release][HEAD]
4
+
5
+ ## [0.4.0][] / 2016-11-12
6
+
7
+ * Drop Ruby 1.9 support.
8
+ * Remove `activesupport` dependency in favor of `inflecto`.
9
+ * Change `included` into an array, per the JSON-API spec.
10
+
11
+ ## [0.3.0][] / 2015-06-05
12
+
13
+ * Gracefully handle `nil` in belongs-to relationships.
14
+ * Update JSON-API format for 1.0.
15
+ * Always include an `id` attribute for all resources, per JSON-API spec.
16
+
17
+ ## [0.2.0][] / 2015-05-05
18
+
19
+ * Fixes a bug where the JSON-API format wouldn't use the `:data` key as the
20
+ top-level when rendering a collection, and ensures that the
21
+ `ActiveModel::Serializers` format uses a singular key when rendering an
22
+ individual resource.
23
+ * Extract Rails integration into [ivy-serializers-rails][].
24
+
25
+ ## [0.1.0][] / 2015-05-01
26
+
27
+ * Initial release.
28
+
29
+ [0.1.0]: https://github.com/IvyApp/ivy-serializers/tree/v0.1.0
30
+ [0.2.0]: https://github.com/IvyApp/ivy-serializers/compare/v0.1.0...v0.2.0
31
+ [0.3.0]: https://github.com/IvyApp/ivy-serializers/compare/v0.2.0...v0.3.0
32
+ [0.4.0]: https://github.com/IvyApp/ivy-serializers/compare/v0.3.0...v0.4.0
33
+ [HEAD]: https://github.com/IvyApp/ivy-serializers/compare/v0.4.0...master
34
+ [ivy-serializers-rails]: https://github.com/IvyApp/ivy-serializers-rails
@@ -14,11 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
15
  spec.require_paths = ['lib']
16
16
 
17
- spec.add_dependency 'activesupport', '>= 2.2.1'
18
17
  spec.add_dependency 'hash_generator', '~> 1.1'
18
+ spec.add_dependency 'inflecto', '~> 0.0.2'
19
19
 
20
20
  spec.add_development_dependency 'bundler', '~> 1.6'
21
+ spec.add_development_dependency 'json-schema-rspec', '~> 0.0.4'
21
22
  spec.add_development_dependency 'rake'
22
- spec.add_development_dependency 'rspec', '~> 3.2.0'
23
- spec.add_development_dependency 'simplecov', '~> 0.10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.5'
24
+ spec.add_development_dependency 'simplecov', '~> 0.12.0'
24
25
  end
@@ -28,7 +28,7 @@ module Ivy
28
28
  end
29
29
 
30
30
  def generate_included_resources(generator)
31
- @included_resources.each_pair { |klass, resources| generator.included_resources(klass, resources) }
31
+ generator.included_resources(@included_resources)
32
32
  end
33
33
 
34
34
  def generate_relationships(generator, resource)
@@ -1,4 +1,4 @@
1
- require 'active_support/inflector'
1
+ require 'inflecto'
2
2
  require 'ivy/serializers/formats/json'
3
3
 
4
4
  module Ivy
@@ -41,7 +41,7 @@ module Ivy
41
41
  end
42
42
 
43
43
  def singularize(name)
44
- ActiveSupport::Inflector.singularize(name.to_s)
44
+ Inflecto.singularize(name.to_s)
45
45
  end
46
46
  end
47
47
  end
@@ -1,5 +1,5 @@
1
- require 'active_support/inflector'
2
1
  require 'hash_generator'
2
+ require 'inflecto'
3
3
 
4
4
  module Ivy
5
5
  module Serializers
@@ -48,9 +48,11 @@ module Ivy
48
48
  document.generate_included_resources(self)
49
49
  end
50
50
 
51
- def included_resources(resource_class, resources)
52
- key = key_for_collection(resource_class).to_sym
53
- @hash_gen.store_array(key) { resources(resources) }
51
+ def included_resources(included_resources)
52
+ included_resources.each_pair do |resource_class, resources|
53
+ key = key_for_collection(resource_class).to_sym
54
+ @hash_gen.store_array(key) { resources(resources) }
55
+ end
54
56
  end
55
57
 
56
58
  def primary_resource(primary_resource_name, primary_resource)
@@ -85,15 +87,15 @@ module Ivy
85
87
  end
86
88
 
87
89
  def extract_type(resource)
88
- ActiveSupport::Inflector.dasherize(key_for_individual(resource.class))
90
+ Inflecto.dasherize(key_for_individual(resource.class))
89
91
  end
90
92
 
91
93
  def key_for_collection(resource_class)
92
- ActiveSupport::Inflector.pluralize(key_for_individual(resource_class))
94
+ Inflecto.pluralize(key_for_individual(resource_class))
93
95
  end
94
96
 
95
97
  def key_for_individual(resource_class)
96
- ActiveSupport::Inflector.underscore(resource_class.name)
98
+ Inflecto.underscore(resource_class.name)
97
99
  end
98
100
  end
99
101
  end
@@ -21,7 +21,11 @@ module Ivy
21
21
  end
22
22
 
23
23
  def included(document)
24
- @hash_gen.store_object(:included) { super }
24
+ @hash_gen.store_array(:included) { super }
25
+ end
26
+
27
+ def included_resources(included_resources)
28
+ included_resources.each_value { |resources| resources(resources) }
25
29
  end
26
30
 
27
31
  def primary_resource(primary_resource_name, primary_resource)
@@ -5,13 +5,13 @@ module Ivy
5
5
  module Serializers
6
6
  class Mapping
7
7
  def initialize(klass)
8
- @attrs = {}
8
+ @attributes = {}
9
9
  @relationships = {}
10
10
  @klass = klass
11
11
  end
12
12
 
13
13
  def attribute(name, &block)
14
- @attrs[name] = Attribute.new(name, &block)
14
+ @attributes[name] = Attribute.new(name, &block)
15
15
  end
16
16
 
17
17
  def attributes(*names)
@@ -23,7 +23,7 @@ module Ivy
23
23
  end
24
24
 
25
25
  def generate_attributes(generator, resource)
26
- @attrs.each_value { |attr| attr.generate(generator, resource) }
26
+ @attributes.each_value { |attribute| attribute.generate(generator, resource) }
27
27
  end
28
28
 
29
29
  def has_many(name, options={}, &block)
@@ -35,7 +35,7 @@ module Ivy
35
35
  end
36
36
 
37
37
  def resource(generator, resource)
38
- generator.attributes(resource) unless @attrs.empty?
38
+ generator.attributes(resource) unless @attributes.empty?
39
39
  generator.relationships(resource) unless @relationships.empty?
40
40
  end
41
41
  end
@@ -1,5 +1,5 @@
1
1
  module Ivy
2
2
  module Serializers
3
- VERSION = '0.3.0'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
@@ -16,6 +16,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
16
16
  context 'for an individual resource' do
17
17
  let(:resource) { post }
18
18
 
19
+ it { should match_json_schema(:json_api) }
20
+
19
21
  it { should eq({
20
22
  :data => {
21
23
  :type => 'post',
@@ -27,6 +29,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
27
29
  context 'for a resource collection' do
28
30
  let(:resource) { [post] }
29
31
 
32
+ it { should match_json_schema(:json_api) }
33
+
30
34
  it { should eq({
31
35
  :data => [{
32
36
  :type => 'post',
@@ -50,6 +54,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
50
54
  context 'for an individual resource' do
51
55
  let(:resource) { post }
52
56
 
57
+ it { should match_json_schema(:json_api) }
58
+
53
59
  it { should eq({
54
60
  :data => {
55
61
  :type => 'post',
@@ -64,6 +70,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
64
70
  context 'for a resource collection' do
65
71
  let(:resource) { [post] }
66
72
 
73
+ it { should match_json_schema(:json_api) }
74
+
67
75
  it { should eq({
68
76
  :data => [{
69
77
  :type => 'post',
@@ -86,6 +94,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
86
94
  context 'for an individual resource' do
87
95
  let(:resource) { post }
88
96
 
97
+ it { should match_json_schema(:json_api) }
98
+
89
99
  it { should eq({
90
100
  :data => {
91
101
  :type => 'post',
@@ -100,6 +110,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
100
110
  context 'for a resource collection' do
101
111
  let(:resource) { [post] }
102
112
 
113
+ it { should match_json_schema(:json_api) }
114
+
103
115
  it { should eq({
104
116
  :data => [{
105
117
  :type => 'post',
@@ -129,6 +141,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
129
141
  context 'for an individual resource' do
130
142
  let(:resource) { post }
131
143
 
144
+ it { should match_json_schema(:json_api) }
145
+
132
146
  it { should eq({
133
147
  :data => {
134
148
  :type => 'post',
@@ -144,6 +158,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
144
158
  context 'with no related resource' do
145
159
  let(:author) { nil }
146
160
 
161
+ it { should match_json_schema(:json_api) }
162
+
147
163
  it { should eq({
148
164
  :data => {
149
165
  :type => 'post',
@@ -159,6 +175,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
159
175
  context 'for a resource collection' do
160
176
  let(:resource) { [post] }
161
177
 
178
+ it { should match_json_schema(:json_api) }
179
+
162
180
  it { should eq({
163
181
  :data => [{
164
182
  :type => 'post',
@@ -183,6 +201,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
183
201
  context 'for an individual resource' do
184
202
  let(:resource) { post }
185
203
 
204
+ it { should match_json_schema(:json_api) }
205
+
186
206
  it { should eq({
187
207
  :data => {
188
208
  :type => 'post',
@@ -198,6 +218,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
198
218
  context 'with no related resource' do
199
219
  let(:author) { nil }
200
220
 
221
+ it { should match_json_schema(:json_api) }
222
+
201
223
  it { should eq({
202
224
  :data => {
203
225
  :type => 'post',
@@ -213,6 +235,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
213
235
  context 'for a resource collection' do
214
236
  let(:resource) { [post] }
215
237
 
238
+ it { should match_json_schema(:json_api) }
239
+
216
240
  it { should eq({
217
241
  :data => [{
218
242
  :type => 'post',
@@ -237,6 +261,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
237
261
  context 'for an individual resource' do
238
262
  let(:resource) { post }
239
263
 
264
+ it { should match_json_schema(:json_api) }
265
+
240
266
  it { should eq({
241
267
  :data => {
242
268
  :type => 'post',
@@ -248,17 +274,17 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
248
274
  }
249
275
  },
250
276
 
251
- :included => {
252
- :authors => [{
253
- :id => '1',
254
- :type => 'author'
255
- }]
256
- }
277
+ :included => [{
278
+ :id => '1',
279
+ :type => 'author'
280
+ }]
257
281
  }) }
258
282
 
259
283
  context 'with no related resource' do
260
284
  let(:author) { nil }
261
285
 
286
+ it { should match_json_schema(:json_api) }
287
+
262
288
  it { should eq({
263
289
  :data => {
264
290
  :type => 'post',
@@ -274,6 +300,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
274
300
  context 'for a resource collection' do
275
301
  let(:resource) { [post] }
276
302
 
303
+ it { should match_json_schema(:json_api) }
304
+
277
305
  it { should eq({
278
306
  :data => [{
279
307
  :type => 'post',
@@ -285,12 +313,10 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
285
313
  }
286
314
  }],
287
315
 
288
- :included => {
289
- :authors => [{
290
- :id => '1',
291
- :type => 'author'
292
- }]
293
- }
316
+ :included => [{
317
+ :id => '1',
318
+ :type => 'author'
319
+ }]
294
320
  }) }
295
321
  end
296
322
  end
@@ -305,6 +331,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
305
331
  context 'for an individual resource' do
306
332
  let(:resource) { post }
307
333
 
334
+ it { should match_json_schema(:json_api) }
335
+
308
336
  it { should eq({
309
337
  :data => {
310
338
  :type => 'post',
@@ -320,6 +348,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
320
348
  context 'with no related resource' do
321
349
  let(:author) { nil }
322
350
 
351
+ it { should match_json_schema(:json_api) }
352
+
323
353
  it { should eq({
324
354
  :data => {
325
355
  :type => 'post',
@@ -335,6 +365,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
335
365
  context 'for a resource collection' do
336
366
  let(:resource) { [post] }
337
367
 
368
+ it { should match_json_schema(:json_api) }
369
+
338
370
  it { should eq({
339
371
  :data => [{
340
372
  :type => 'post',
@@ -366,6 +398,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
366
398
  context 'for an individual resource' do
367
399
  let(:resource) { post }
368
400
 
401
+ it { should match_json_schema(:json_api) }
402
+
369
403
  it { should eq({
370
404
  :data => {
371
405
  :type => 'post',
@@ -382,6 +416,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
382
416
  context 'for a resource collection' do
383
417
  let(:resource) { [post] }
384
418
 
419
+ it { should match_json_schema(:json_api) }
420
+
385
421
  it { should eq({
386
422
  :data => [{
387
423
  :type => 'post',
@@ -406,6 +442,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
406
442
  context 'for an individual resource' do
407
443
  let(:resource) { post }
408
444
 
445
+ it { should match_json_schema(:json_api) }
446
+
409
447
  it { should eq({
410
448
  :data => {
411
449
  :type => 'post',
@@ -422,6 +460,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
422
460
  context 'for a resource collection' do
423
461
  let(:resource) { [post] }
424
462
 
463
+ it { should match_json_schema(:json_api) }
464
+
425
465
  it { should eq({
426
466
  :data => [{
427
467
  :type => 'post',
@@ -446,6 +486,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
446
486
  context 'for an individual resource' do
447
487
  let(:resource) { post }
448
488
 
489
+ it { should match_json_schema(:json_api) }
490
+
449
491
  it { should eq({
450
492
  :data => {
451
493
  :type => 'post',
@@ -457,18 +499,18 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
457
499
  }
458
500
  },
459
501
 
460
- :included => {
461
- :comments => [{
462
- :type => 'comment',
463
- :id => '1'
464
- }]
465
- }
502
+ :included => [{
503
+ :type => 'comment',
504
+ :id => '1'
505
+ }]
466
506
  }) }
467
507
  end
468
508
 
469
509
  context 'for a resource collection' do
470
510
  let(:resource) { [post] }
471
511
 
512
+ it { should match_json_schema(:json_api) }
513
+
472
514
  it { should eq({
473
515
  :data => [{
474
516
  :type => 'post',
@@ -480,12 +522,10 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
480
522
  }
481
523
  }],
482
524
 
483
- :included => {
484
- :comments => [{
485
- :type => 'comment',
486
- :id => '1'
487
- }]
488
- }
525
+ :included => [{
526
+ :type => 'comment',
527
+ :id => '1'
528
+ }]
489
529
  }) }
490
530
  end
491
531
  end
@@ -500,6 +540,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
500
540
  context 'for an individual resource' do
501
541
  let(:resource) { post }
502
542
 
543
+ it { should match_json_schema(:json_api) }
544
+
503
545
  it { should eq({
504
546
  :data => {
505
547
  :type => 'post',
@@ -516,6 +558,8 @@ RSpec.describe Ivy::Serializers::Formats::JSONAPI do
516
558
  context 'for a resource collection' do
517
559
  let(:resource) { [post] }
518
560
 
561
+ it { should match_json_schema(:json_api) }
562
+
519
563
  it { should eq({
520
564
  :data => [{
521
565
  :type => 'post',
@@ -0,0 +1,375 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "JSON API Schema",
4
+ "description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
5
+ "oneOf": [
6
+ {
7
+ "$ref": "#/definitions/success"
8
+ },
9
+ {
10
+ "$ref": "#/definitions/failure"
11
+ },
12
+ {
13
+ "$ref": "#/definitions/info"
14
+ }
15
+ ],
16
+
17
+ "definitions": {
18
+ "success": {
19
+ "type": "object",
20
+ "required": [
21
+ "data"
22
+ ],
23
+ "properties": {
24
+ "data": {
25
+ "$ref": "#/definitions/data"
26
+ },
27
+ "included": {
28
+ "description": "To reduce the number of HTTP requests, servers **MAY** allow responses that include related resources along with the requested primary resources. Such responses are called \"compound documents\".",
29
+ "type": "array",
30
+ "items": {
31
+ "$ref": "#/definitions/resource"
32
+ },
33
+ "uniqueItems": true
34
+ },
35
+ "meta": {
36
+ "$ref": "#/definitions/meta"
37
+ },
38
+ "links": {
39
+ "description": "Link members related to the primary data.",
40
+ "allOf": [
41
+ {
42
+ "$ref": "#/definitions/links"
43
+ },
44
+ {
45
+ "$ref": "#/definitions/pagination"
46
+ }
47
+ ]
48
+ },
49
+ "jsonapi": {
50
+ "$ref": "#/definitions/jsonapi"
51
+ }
52
+ },
53
+ "additionalProperties": false
54
+ },
55
+ "failure": {
56
+ "type": "object",
57
+ "required": [
58
+ "errors"
59
+ ],
60
+ "properties": {
61
+ "errors": {
62
+ "type": "array",
63
+ "items": {
64
+ "$ref": "#/definitions/error"
65
+ },
66
+ "uniqueItems": true
67
+ },
68
+ "meta": {
69
+ "$ref": "#/definitions/meta"
70
+ },
71
+ "jsonapi": {
72
+ "$ref": "#/definitions/jsonapi"
73
+ }
74
+ },
75
+ "additionalProperties": false
76
+ },
77
+ "info": {
78
+ "type": "object",
79
+ "required": [
80
+ "meta"
81
+ ],
82
+ "properties": {
83
+ "meta": {
84
+ "$ref": "#/definitions/meta"
85
+ },
86
+ "links": {
87
+ "$ref": "#/definitions/links"
88
+ },
89
+ "jsonapi": {
90
+ "$ref": "#/definitions/jsonapi"
91
+ }
92
+ },
93
+ "additionalProperties": false
94
+ },
95
+
96
+ "meta": {
97
+ "description": "Non-standard meta-information that can not be represented as an attribute or relationship.",
98
+ "type": "object",
99
+ "additionalProperties": true
100
+ },
101
+ "data": {
102
+ "description": "The document's \"primary data\" is a representation of the resource or collection of resources targeted by a request.",
103
+ "oneOf": [
104
+ {
105
+ "$ref": "#/definitions/resource"
106
+ },
107
+ {
108
+ "description": "An array of resource objects, an array of resource identifier objects, or an empty array ([]), for requests that target resource collections.",
109
+ "type": "array",
110
+ "items": {
111
+ "$ref": "#/definitions/resource"
112
+ },
113
+ "uniqueItems": true
114
+ },
115
+ {
116
+ "description": "null if the request is one that might correspond to a single resource, but doesn't currently.",
117
+ "type": "null"
118
+ }
119
+ ]
120
+ },
121
+ "resource": {
122
+ "description": "\"Resource objects\" appear in a JSON API document to represent resources.",
123
+ "type": "object",
124
+ "required": [
125
+ "type",
126
+ "id"
127
+ ],
128
+ "properties": {
129
+ "type": {
130
+ "type": "string"
131
+ },
132
+ "id": {
133
+ "type": "string"
134
+ },
135
+ "attributes": {
136
+ "$ref": "#/definitions/attributes"
137
+ },
138
+ "relationships": {
139
+ "$ref": "#/definitions/relationships"
140
+ },
141
+ "links": {
142
+ "$ref": "#/definitions/links"
143
+ },
144
+ "meta": {
145
+ "$ref": "#/definitions/meta"
146
+ }
147
+ },
148
+ "additionalProperties": false
149
+ },
150
+
151
+ "links": {
152
+ "description": "A resource object **MAY** contain references to other resource objects (\"relationships\"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object.",
153
+ "type": "object",
154
+ "properties": {
155
+ "self": {
156
+ "description": "A `self` member, whose value is a URL for the relationship itself (a \"relationship URL\"). This URL allows the client to directly manipulate the relationship. For example, it would allow a client to remove an `author` from an `article` without deleting the people resource itself.",
157
+ "type": "string",
158
+ "format": "uri"
159
+ },
160
+ "related": {
161
+ "$ref": "#/definitions/link"
162
+ }
163
+ },
164
+ "additionalProperties": true
165
+ },
166
+ "link": {
167
+ "description": "A link **MUST** be represented as either: a string containing the link's URL or a link object.",
168
+ "oneOf": [
169
+ {
170
+ "description": "A string containing the link's URL.",
171
+ "type": "string",
172
+ "format": "uri"
173
+ },
174
+ {
175
+ "type": "object",
176
+ "required": [
177
+ "href"
178
+ ],
179
+ "properties": {
180
+ "href": {
181
+ "description": "A string containing the link's URL.",
182
+ "type": "string",
183
+ "format": "uri"
184
+ },
185
+ "meta": {
186
+ "$ref": "#/definitions/meta"
187
+ }
188
+ }
189
+ }
190
+ ]
191
+ },
192
+
193
+ "attributes": {
194
+ "description": "Members of the attributes object (\"attributes\") represent information about the resource object in which it's defined.",
195
+ "type": "object",
196
+ "patternProperties": {
197
+ "^(?!relationships$|links$)\\w[-\\w]*$": {
198
+ "description": "Attributes may contain any valid JSON value."
199
+ }
200
+ },
201
+ "additionalProperties": false
202
+ },
203
+
204
+ "relationships": {
205
+ "description": "Members of the relationships object (\"relationships\") represent references from the resource object in which it's defined to other resource objects.",
206
+ "type": "object",
207
+ "patternProperties": {
208
+ "^\\w[-\\w]*$": {
209
+ "properties": {
210
+ "links": {
211
+ "$ref": "#/definitions/links"
212
+ },
213
+ "data": {
214
+ "description": "Member, whose value represents \"resource linkage\".",
215
+ "oneOf": [
216
+ {
217
+ "$ref": "#/definitions/relationshipToOne"
218
+ },
219
+ {
220
+ "$ref": "#/definitions/relationshipToMany"
221
+ }
222
+ ]
223
+ },
224
+ "meta": {
225
+ "$ref": "#/definitions/meta"
226
+ }
227
+ },
228
+ "anyOf": [
229
+ {"required": ["data"]},
230
+ {"required": ["meta"]},
231
+ {"required": ["links"]}
232
+ ],
233
+ "additionalProperties": false
234
+ }
235
+ },
236
+ "additionalProperties": false
237
+ },
238
+ "relationshipToOne": {
239
+ "description": "References to other resource objects in a to-one (\"relationship\"). Relationships can be specified by including a member in a resource's links object.",
240
+ "anyOf": [
241
+ {
242
+ "$ref": "#/definitions/empty"
243
+ },
244
+ {
245
+ "$ref": "#/definitions/linkage"
246
+ }
247
+ ]
248
+ },
249
+ "relationshipToMany": {
250
+ "description": "An array of objects each containing \"type\" and \"id\" members for to-many relationships.",
251
+ "type": "array",
252
+ "items": {
253
+ "$ref": "#/definitions/linkage"
254
+ },
255
+ "uniqueItems": true
256
+ },
257
+ "empty": {
258
+ "description": "Describes an empty to-one relationship.",
259
+ "type": "null"
260
+ },
261
+ "linkage": {
262
+ "description": "The \"type\" and \"id\" to non-empty members.",
263
+ "type": "object",
264
+ "required": [
265
+ "type",
266
+ "id"
267
+ ],
268
+ "properties": {
269
+ "type": {
270
+ "type": "string"
271
+ },
272
+ "id": {
273
+ "type": "string"
274
+ },
275
+ "meta": {
276
+ "$ref": "#/definitions/meta"
277
+ }
278
+ },
279
+ "additionalProperties": false
280
+ },
281
+ "pagination": {
282
+ "type": "object",
283
+ "properties": {
284
+ "first": {
285
+ "description": "The first page of data",
286
+ "oneOf": [
287
+ { "type": "string", "format": "uri" },
288
+ { "type": "null" }
289
+ ]
290
+ },
291
+ "last": {
292
+ "description": "The last page of data",
293
+ "oneOf": [
294
+ { "type": "string", "format": "uri" },
295
+ { "type": "null" }
296
+ ]
297
+ },
298
+ "prev": {
299
+ "description": "The previous page of data",
300
+ "oneOf": [
301
+ { "type": "string", "format": "uri" },
302
+ { "type": "null" }
303
+ ]
304
+ },
305
+ "next": {
306
+ "description": "The next page of data",
307
+ "oneOf": [
308
+ { "type": "string", "format": "uri" },
309
+ { "type": "null" }
310
+ ]
311
+ }
312
+ }
313
+ },
314
+
315
+ "jsonapi": {
316
+ "description": "An object describing the server's implementation",
317
+ "type": "object",
318
+ "properties": {
319
+ "version": {
320
+ "type": "string"
321
+ },
322
+ "meta": {
323
+ "$ref": "#/definitions/meta"
324
+ }
325
+ },
326
+ "additionalProperties": false
327
+ },
328
+
329
+ "error": {
330
+ "type": "object",
331
+ "properties": {
332
+ "id": {
333
+ "description": "A unique identifier for this particular occurrence of the problem.",
334
+ "type": "string"
335
+ },
336
+ "links": {
337
+ "$ref": "#/definitions/links"
338
+ },
339
+ "status": {
340
+ "description": "The HTTP status code applicable to this problem, expressed as a string value.",
341
+ "type": "string"
342
+ },
343
+ "code": {
344
+ "description": "An application-specific error code, expressed as a string value.",
345
+ "type": "string"
346
+ },
347
+ "title": {
348
+ "description": "A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization.",
349
+ "type": "string"
350
+ },
351
+ "detail": {
352
+ "description": "A human-readable explanation specific to this occurrence of the problem.",
353
+ "type": "string"
354
+ },
355
+ "source": {
356
+ "type": "object",
357
+ "properties": {
358
+ "pointer": {
359
+ "description": "A JSON Pointer [RFC6901] to the associated entity in the request document [e.g. \"/data\" for a primary data object, or \"/data/attributes/title\" for a specific attribute].",
360
+ "type": "string"
361
+ },
362
+ "parameter": {
363
+ "description": "A string indicating which query parameter caused the error.",
364
+ "type": "string"
365
+ }
366
+ }
367
+ },
368
+ "meta": {
369
+ "$ref": "#/definitions/meta"
370
+ }
371
+ },
372
+ "additionalProperties": false
373
+ }
374
+ }
375
+ }
@@ -2,6 +2,8 @@ require 'simplecov'
2
2
 
3
3
  SimpleCov.start
4
4
 
5
+ require 'json-schema-rspec'
6
+
5
7
  # This file was generated by the `rspec --init` command. Conventionally, all
6
8
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
9
  # The generated `.rspec` file contains `--require spec_helper` which will cause
@@ -21,6 +23,13 @@ SimpleCov.start
21
23
  #
22
24
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
23
25
  RSpec.configure do |config|
26
+ config.include JSON::SchemaMatchers
27
+
28
+ # Load schema files into config.json_schemas.
29
+ Dir[File.join(File.expand_path('../schemas', __FILE__), '**', '*.json')].each do |file|
30
+ config.json_schemas[File.basename(file, '.json').to_sym] = file
31
+ end
32
+
24
33
  # rspec-expectations config goes here. You can use an alternate
25
34
  # assertion/expectation library such as wrong or the stdlib/minitest
26
35
  # assertions if you prefer.
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ivy-serializers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dray Lacy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-05 00:00:00.000000000 Z
11
+ date: 2016-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: hash_generator
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.2.1
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.2.1
26
+ version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: hash_generator
28
+ name: inflecto
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.1'
33
+ version: 0.0.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.1'
40
+ version: 0.0.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json-schema-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.4
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.4
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -72,28 +86,28 @@ dependencies:
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: 3.2.0
89
+ version: '3.5'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: 3.2.0
96
+ version: '3.5'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: simplecov
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.10.0
103
+ version: 0.12.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 0.10.0
110
+ version: 0.12.0
97
111
  description:
98
112
  email:
99
113
  - dray@envylabs.com
@@ -104,6 +118,7 @@ files:
104
118
  - ".gitignore"
105
119
  - ".rspec"
106
120
  - ".travis.yml"
121
+ - CHANGELOG.md
107
122
  - Gemfile
108
123
  - LICENSE.txt
109
124
  - README.md
@@ -132,6 +147,7 @@ files:
132
147
  - spec/integration/formats/json_api_spec.rb
133
148
  - spec/integration/formats/json_spec.rb
134
149
  - spec/integration/serializer_spec.rb
150
+ - spec/schemas/json_api.json
135
151
  - spec/spec_helper.rb
136
152
  homepage: ''
137
153
  licenses:
@@ -153,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
169
  version: '0'
154
170
  requirements: []
155
171
  rubyforge_project:
156
- rubygems_version: 2.4.6
172
+ rubygems_version: 2.4.5.1
157
173
  signing_key:
158
174
  specification_version: 4
159
175
  summary: JSON serialization for client-side apps.
@@ -162,4 +178,5 @@ test_files:
162
178
  - spec/integration/formats/json_api_spec.rb
163
179
  - spec/integration/formats/json_spec.rb
164
180
  - spec/integration/serializer_spec.rb
181
+ - spec/schemas/json_api.json
165
182
  - spec/spec_helper.rb