ivy-serializers 0.3.0 → 0.4.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
  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