pacto 0.3.0.pre → 0.3.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.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rubocop-todo.yml +0 -27
  4. data/.rubocop.yml +9 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +4 -5
  8. data/CONTRIBUTING.md +112 -0
  9. data/Gemfile +5 -0
  10. data/Guardfile +18 -13
  11. data/README.md +157 -101
  12. data/Rakefile +3 -3
  13. data/features/configuration/strict_matchers.feature +97 -0
  14. data/features/evolve/README.md +11 -0
  15. data/features/evolve/existing_services.feature +82 -0
  16. data/features/generate/README.md +5 -0
  17. data/features/generate/generation.feature +28 -0
  18. data/features/steps/pacto_steps.rb +75 -0
  19. data/features/stub/README.md +2 -0
  20. data/features/stub/templates.feature +46 -0
  21. data/features/support/env.rb +11 -5
  22. data/features/validate/README.md +1 -0
  23. data/features/validate/body_only.feature +85 -0
  24. data/features/{journeys/validation.feature → validate/meta_validation.feature} +41 -24
  25. data/features/validate/validation.feature +36 -0
  26. data/lib/pacto.rb +61 -33
  27. data/lib/pacto/contract.rb +18 -15
  28. data/lib/pacto/contract_factory.rb +14 -11
  29. data/lib/pacto/contract_files.rb +17 -0
  30. data/lib/pacto/contract_list.rb +17 -0
  31. data/lib/pacto/contract_validator.rb +29 -0
  32. data/lib/pacto/core/configuration.rb +19 -17
  33. data/lib/pacto/core/contract_registry.rb +43 -0
  34. data/lib/pacto/core/{callback.rb → hook.rb} +3 -3
  35. data/lib/pacto/core/modes.rb +33 -0
  36. data/lib/pacto/core/validation_registry.rb +45 -0
  37. data/lib/pacto/erb_processor.rb +0 -1
  38. data/lib/pacto/extensions.rb +18 -4
  39. data/lib/pacto/generator.rb +34 -49
  40. data/lib/pacto/generator/filters.rb +41 -0
  41. data/lib/pacto/hooks/erb_hook.rb +4 -3
  42. data/lib/pacto/logger.rb +4 -2
  43. data/lib/pacto/meta_schema.rb +4 -2
  44. data/lib/pacto/rake_task.rb +28 -25
  45. data/lib/pacto/request_clause.rb +43 -0
  46. data/lib/pacto/request_pattern.rb +8 -0
  47. data/lib/pacto/response_clause.rb +15 -0
  48. data/lib/pacto/rspec.rb +102 -0
  49. data/lib/pacto/stubs/uri_pattern.rb +23 -0
  50. data/lib/pacto/stubs/webmock_adapter.rb +69 -0
  51. data/lib/pacto/stubs/webmock_helper.rb +71 -0
  52. data/lib/pacto/ui.rb +7 -0
  53. data/lib/pacto/uri.rb +9 -0
  54. data/lib/pacto/validation.rb +57 -0
  55. data/lib/pacto/validators/body_validator.rb +41 -0
  56. data/lib/pacto/validators/request_body_validator.rb +23 -0
  57. data/lib/pacto/validators/response_body_validator.rb +23 -0
  58. data/lib/pacto/validators/response_header_validator.rb +49 -0
  59. data/lib/pacto/validators/response_status_validator.rb +24 -0
  60. data/lib/pacto/version.rb +1 -1
  61. data/pacto.gemspec +33 -29
  62. data/resources/contract_schema.json +8 -176
  63. data/resources/draft-03.json +174 -0
  64. data/spec/integration/data/strict_contract.json +2 -2
  65. data/spec/integration/e2e_spec.rb +22 -31
  66. data/spec/integration/rspec_spec.rb +94 -0
  67. data/spec/integration/templating_spec.rb +9 -12
  68. data/{lib → spec}/pacto/server.rb +0 -0
  69. data/{lib → spec}/pacto/server/dummy.rb +11 -8
  70. data/{lib → spec}/pacto/server/playback_servlet.rb +1 -1
  71. data/spec/spec_helper.rb +2 -0
  72. data/spec/unit/hooks/erb_hook_spec.rb +15 -15
  73. data/spec/unit/pacto/configuration_spec.rb +2 -10
  74. data/spec/unit/pacto/contract_factory_spec.rb +16 -13
  75. data/spec/unit/pacto/contract_files_spec.rb +42 -0
  76. data/spec/unit/pacto/contract_list_spec.rb +35 -0
  77. data/spec/unit/pacto/contract_spec.rb +43 -44
  78. data/spec/unit/pacto/contract_validator_spec.rb +85 -0
  79. data/spec/unit/pacto/core/configuration_spec.rb +4 -11
  80. data/spec/unit/pacto/core/contract_registry_spec.rb +119 -0
  81. data/spec/unit/pacto/core/modes_spec.rb +18 -0
  82. data/spec/unit/pacto/core/validation_registry_spec.rb +76 -0
  83. data/spec/unit/pacto/core/validation_spec.rb +60 -0
  84. data/spec/unit/pacto/extensions_spec.rb +14 -23
  85. data/spec/unit/pacto/generator/filters_spec.rb +99 -0
  86. data/spec/unit/pacto/generator_spec.rb +34 -73
  87. data/spec/unit/pacto/meta_schema_spec.rb +46 -6
  88. data/spec/unit/pacto/pacto_spec.rb +17 -15
  89. data/spec/unit/pacto/{request_spec.rb → request_clause_spec.rb} +32 -44
  90. data/spec/unit/pacto/request_pattern_spec.rb +22 -0
  91. data/spec/unit/pacto/response_clause_spec.rb +54 -0
  92. data/spec/unit/pacto/stubs/uri_pattern_spec.rb +28 -0
  93. data/spec/unit/pacto/stubs/webmock_adapter_spec.rb +205 -0
  94. data/spec/unit/pacto/stubs/webmock_helper_spec.rb +20 -0
  95. data/spec/unit/pacto/uri_spec.rb +20 -0
  96. data/spec/unit/pacto/validators/body_validator_spec.rb +105 -0
  97. data/spec/unit/pacto/validators/response_header_validator_spec.rb +94 -0
  98. data/spec/unit/pacto/validators/response_status_validator_spec.rb +20 -0
  99. metadata +230 -146
  100. data/features/generation/generation.feature +0 -25
  101. data/lib/pacto/core/contract_repository.rb +0 -44
  102. data/lib/pacto/hash_merge_processor.rb +0 -14
  103. data/lib/pacto/request.rb +0 -57
  104. data/lib/pacto/response.rb +0 -63
  105. data/lib/pacto/response_adapter.rb +0 -24
  106. data/lib/pacto/stubs/built_in.rb +0 -57
  107. data/spec/unit/pacto/core/contract_repository_spec.rb +0 -133
  108. data/spec/unit/pacto/hash_merge_processor_spec.rb +0 -20
  109. data/spec/unit/pacto/response_adapter_spec.rb +0 -25
  110. data/spec/unit/pacto/response_spec.rb +0 -201
  111. data/spec/unit/pacto/stubs/built_in_spec.rb +0 -168
@@ -0,0 +1,23 @@
1
+ module Pacto
2
+ module Validators
3
+ class RequestBodyValidator < BodyValidator
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def self.section_name
9
+ 'request'
10
+ end
11
+
12
+ def call(env)
13
+ if env[:validation_results].empty? # skip body validation if we already have other errors
14
+ expected_body = env[:contract].request.schema
15
+ actual_body = env[:actual_request]
16
+ errors = self.class.validate(expected_body, actual_body)
17
+ env[:validation_results].concat errors.compact
18
+ end
19
+ @app.call env
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Pacto
2
+ module Validators
3
+ class ResponseBodyValidator < BodyValidator
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def self.section_name
9
+ 'response'
10
+ end
11
+
12
+ def call(env)
13
+ if env[:validation_results].empty? # skip body validation if we already have other errors
14
+ expected_body = env[:contract].response.schema
15
+ actual_body = env[:actual_response]
16
+ errors = self.class.validate(expected_body, actual_body)
17
+ env[:validation_results].concat errors.compact
18
+ end
19
+ @app.call env
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ module Pacto
2
+ module Validators
3
+ class ResponseHeaderValidator
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ expected_headers = env[:contract].response.headers
10
+ actual_headers = env[:actual_response].headers
11
+ env[:validation_results].concat self.class.validate(expected_headers, actual_headers)
12
+ @app.call env
13
+ end
14
+
15
+ def self.validate(expected_headers, actual_headers)
16
+ actual_headers = Pacto::Extensions.normalize_header_keys actual_headers
17
+ headers_to_validate = Pacto::Extensions.normalize_header_keys expected_headers
18
+
19
+ headers_to_validate.map do |expected_header, expected_value|
20
+ if actual_headers.key? expected_header
21
+ actual_value = actual_headers[expected_header]
22
+ HeaderValidatorMap[expected_header].call(expected_value, actual_value)
23
+ else
24
+ "Missing expected response header: #{expected_header}"
25
+ end
26
+ end.compact
27
+ end
28
+
29
+ private
30
+
31
+ HeaderValidatorMap = Hash.new do |map, key|
32
+ proc do |expected_value, actual_value|
33
+ unless expected_value.eql? actual_value
34
+ "Invalid response header #{key}: expected #{expected_value.inspect} but received #{actual_value.inspect}"
35
+ end
36
+ end
37
+ end
38
+
39
+ HeaderValidatorMap['Location'] = proc do |expected_value, actual_value|
40
+ location_template = Addressable::Template.new(expected_value)
41
+ if location_template.match(Addressable::URI.parse(actual_value))
42
+ nil
43
+ else
44
+ "Invalid response header Location: expected URI #{actual_value} to match URI Template #{location_template.pattern}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,24 @@
1
+ module Pacto
2
+ module Validators
3
+ class ResponseStatusValidator
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ expected_status = env[:contract].response.status
10
+ actual_status = env[:actual_response].status
11
+ env[:validation_results].concat self.class.validate(expected_status, actual_status)
12
+ @app.call env
13
+ end
14
+
15
+ def self.validate(expected_status, actual_status)
16
+ errors = []
17
+ if expected_status != actual_status
18
+ errors << "Invalid status: expected #{expected_status} but got #{actual_status}"
19
+ end
20
+ errors
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Pacto
2
- VERSION = '0.3.0.pre'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -4,38 +4,42 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'pacto/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
- gem.name = "pacto"
7
+ gem.name = 'pacto'
8
8
  gem.version = Pacto::VERSION
9
- gem.authors = ["ThoughtWorks & Abril"]
10
- gem.email = ["abril_vejasp_dev@thoughtworks.com"]
11
- gem.description = %q{Pacto is a Ruby implementation of the [Consumer-Driven Contracts](http://martinfowler.com/articles/consumerDrivenContracts.html) pattern for evolving services}
12
- gem.summary = %q{Consumer-Driven Contracts implementation}
13
- gem.homepage = 'https://github.com/thoughtworks/pacto'
9
+ gem.authors = ['ThoughtWorks & Abril']
10
+ gem.email = ['pacto-gem@googlegroups.com']
11
+ gem.description = %q{Pacto is a judge that arbitrates contract disputes between a service provider and one or more consumers. In other words, it is a framework for Integration Contract Testing, and helps guide service evolution patterns like Consumer-Driven Contracts or Documentation-Driven Contracts.}
12
+ gem.summary = %q{Integration Contract Testing framework}
13
+ gem.homepage = 'http://thoughtworks.github.io/pacto/'
14
14
  gem.license = 'MIT'
15
15
 
16
- gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
- gem.require_paths = ["lib"]
16
+ gem.files = `git ls-files`.split($/) # rubocop:disable SpecialGlobalVars
17
+ gem.executables = gem.files.grep(/^bin\//).map { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(/^(test|spec|features)\//)
19
+ gem.require_paths = ['lib']
20
20
 
21
- gem.add_dependency "webmock"
22
- gem.add_dependency "multi_json"
23
- gem.add_dependency "json-schema", "~> 2.0"
24
- gem.add_dependency "json-generator"
25
- gem.add_dependency "hash-deep-merge"
26
- gem.add_dependency "httparty"
27
- gem.add_dependency "addressable"
28
- gem.add_dependency "coveralls"
29
- gem.add_dependency "json-schema-generator"
21
+ gem.add_dependency 'webmock', '~> 1.17'
22
+ gem.add_dependency 'middleware', '~> 0.1'
23
+ gem.add_dependency 'multi_json', '~> 1.8'
24
+ gem.add_dependency 'json-schema', '~> 2.0'
25
+ gem.add_dependency 'json-generator', '>= 0.0.5'
26
+ gem.add_dependency 'hash-deep-merge', '~> 0.1'
27
+ gem.add_dependency 'faraday', '~> 0.9'
28
+ gem.add_dependency 'addressable', '~> 2.3'
29
+ gem.add_dependency 'json-schema-generator', '>= 0.0.7'
30
+ gem.add_dependency 'term-ansicolor', '~> 1.3'
30
31
 
31
- gem.add_development_dependency "rake"
32
- gem.add_development_dependency "rspec"
33
- gem.add_development_dependency "should_not"
34
- gem.add_development_dependency "aruba"
35
- gem.add_development_dependency "guard-rspec"
36
- gem.add_development_dependency "rubocop"
37
- gem.add_development_dependency "guard-rubocop"
38
- gem.add_development_dependency "guard-cucumber"
39
- gem.add_development_dependency "rb-fsevent" if RUBY_PLATFORM =~ /darwin/i
40
- gem.add_development_dependency "terminal-notifier-guard" if RUBY_PLATFORM =~ /darwin/i
32
+ gem.add_development_dependency 'coveralls'
33
+ gem.add_development_dependency 'rake'
34
+ gem.add_development_dependency 'rake-notes'
35
+ gem.add_development_dependency 'rspec', '~> 2.14'
36
+ gem.add_development_dependency 'should_not'
37
+ gem.add_development_dependency 'aruba'
38
+ gem.add_development_dependency 'relish'
39
+ gem.add_development_dependency 'guard-rspec'
40
+ gem.add_development_dependency 'rubocop', '~> 0.16.0'
41
+ gem.add_development_dependency 'guard-rubocop'
42
+ gem.add_development_dependency 'guard-cucumber'
43
+ gem.add_development_dependency 'rb-fsevent' if RUBY_PLATFORM =~ /darwin/i
44
+ gem.add_development_dependency 'terminal-notifier-guard' if RUBY_PLATFORM =~ /darwin/i
41
45
  end
@@ -2,6 +2,10 @@
2
2
  "title": "Example Schema",
3
3
  "type": "object",
4
4
  "properties": {
5
+ "name": {
6
+ "type": "string",
7
+ "required": false
8
+ },
5
9
  "request": {
6
10
  "type": "object",
7
11
  "required": true,
@@ -21,6 +25,9 @@
21
25
  "params": {
22
26
  "type": "object",
23
27
  "required": false
28
+ },
29
+ "body": {
30
+ "$ref": "http://json-schema.org/draft-03/schema#"
24
31
  }
25
32
  }
26
33
  },
@@ -36,181 +43,6 @@
36
43
  "$ref": "http://json-schema.org/draft-03/schema#"
37
44
  }
38
45
  }
39
- },
40
- "json-schema": {
41
- "_comment": "this should be refactored to not need the whole schema here",
42
- "$schema": "http://json-schema.org/draft-03/schema#",
43
- "id": "http://json-schema.org/draft-03/schema#",
44
- "type": "object",
45
-
46
- "properties": {
47
- "type": {
48
- "type": [ "string", "array" ],
49
- "items": {
50
- "type": [ "string", { "$ref": "#" } ]
51
- },
52
- "uniqueItems": true,
53
- "default": "any"
54
- },
55
-
56
- "properties": {
57
- "type": "object",
58
- "additionalProperties": { "$ref": "#" },
59
- "default": {}
60
- },
61
-
62
- "patternProperties": {
63
- "type": "object",
64
- "additionalProperties": { "$ref": "#" },
65
- "default": {}
66
- },
67
-
68
- "additionalProperties": {
69
- "type": [ { "$ref": "#" }, "boolean" ],
70
- "default": {}
71
- },
72
-
73
- "items": {
74
- "type": [ { "$ref": "#" }, "array" ],
75
- "items": { "$ref": "#" },
76
- "default": {}
77
- },
78
-
79
- "additionalItems": {
80
- "type": [ { "$ref": "#" }, "boolean" ],
81
- "default": {}
82
- },
83
-
84
- "required": {
85
- "type": "boolean",
86
- "default": false
87
- },
88
-
89
- "dependencies": {
90
- "type": "object",
91
- "additionalProperties": {
92
- "type": [ "string", "array", { "$ref": "#" } ],
93
- "items": {
94
- "type": "string"
95
- }
96
- },
97
- "default": {}
98
- },
99
-
100
- "minimum": {
101
- "type": "number"
102
- },
103
-
104
- "maximum": {
105
- "type": "number"
106
- },
107
-
108
- "exclusiveMinimum": {
109
- "type": "boolean",
110
- "default": false
111
- },
112
-
113
- "exclusiveMaximum": {
114
- "type": "boolean",
115
- "default": false
116
- },
117
-
118
- "minItems": {
119
- "type": "integer",
120
- "minimum": 0,
121
- "default": 0
122
- },
123
-
124
- "maxItems": {
125
- "type": "integer",
126
- "minimum": 0
127
- },
128
-
129
- "uniqueItems": {
130
- "type": "boolean",
131
- "default": false
132
- },
133
-
134
- "pattern": {
135
- "type": "string",
136
- "format": "regex"
137
- },
138
-
139
- "minLength": {
140
- "type": "integer",
141
- "minimum": 0,
142
- "default": 0
143
- },
144
-
145
- "maxLength": {
146
- "type": "integer"
147
- },
148
-
149
- "enum": {
150
- "type": "array",
151
- "minItems": 1,
152
- "uniqueItems": true
153
- },
154
-
155
- "default": {
156
- "type": "any"
157
- },
158
-
159
- "title": {
160
- "type": "string"
161
- },
162
-
163
- "description": {
164
- "type": "string"
165
- },
166
-
167
- "format": {
168
- "type": "string"
169
- },
170
-
171
- "divisibleBy": {
172
- "type": "number",
173
- "minimum": 0,
174
- "exclusiveMinimum": true,
175
- "default": 1
176
- },
177
-
178
- "disallow": {
179
- "type": [ "string", "array" ],
180
- "items": {
181
- "type": [ "string", { "$ref": "#" } ]
182
- },
183
- "uniqueItems": true
184
- },
185
-
186
- "extends": {
187
- "type": [ { "$ref": "#" }, "array" ],
188
- "items": { "$ref": "#" },
189
- "default": {}
190
- },
191
-
192
- "id": {
193
- "type": "string",
194
- "format": "uri"
195
- },
196
-
197
- "$ref": {
198
- "type": "string",
199
- "format": "uri"
200
- },
201
-
202
- "$schema": {
203
- "type": "string",
204
- "format": "uri"
205
- }
206
- },
207
-
208
- "dependencies": {
209
- "exclusiveMinimum": "minimum",
210
- "exclusiveMaximum": "maximum"
211
- },
212
-
213
- "default": {}
214
- }
46
+ }
215
47
  }
216
48
  }
@@ -0,0 +1,174 @@
1
+ {
2
+ "$schema" : "http://json-schema.org/draft-03/schema#",
3
+ "id" : "http://json-schema.org/draft-03/schema#",
4
+ "type" : "object",
5
+
6
+ "properties" : {
7
+ "type" : {
8
+ "type" : ["string", "array"],
9
+ "items" : {
10
+ "type" : ["string", {"$ref" : "#"}]
11
+ },
12
+ "uniqueItems" : true,
13
+ "default" : "any"
14
+ },
15
+
16
+ "properties" : {
17
+ "type" : "object",
18
+ "additionalProperties" : {"$ref" : "#"},
19
+ "default" : {}
20
+ },
21
+
22
+ "patternProperties" : {
23
+ "type" : "object",
24
+ "additionalProperties" : {"$ref" : "#"},
25
+ "default" : {}
26
+ },
27
+
28
+ "additionalProperties" : {
29
+ "type" : [{"$ref" : "#"}, "boolean"],
30
+ "default" : {}
31
+ },
32
+
33
+ "items" : {
34
+ "type" : [{"$ref" : "#"}, "array"],
35
+ "items" : {"$ref" : "#"},
36
+ "default" : {}
37
+ },
38
+
39
+ "additionalItems" : {
40
+ "type" : [{"$ref" : "#"}, "boolean"],
41
+ "default" : {}
42
+ },
43
+
44
+ "required" : {
45
+ "type" : "boolean",
46
+ "default" : false
47
+ },
48
+
49
+ "dependencies" : {
50
+ "type" : "object",
51
+ "additionalProperties" : {
52
+ "type" : ["string", "array", {"$ref" : "#"}],
53
+ "items" : {
54
+ "type" : "string"
55
+ }
56
+ },
57
+ "default" : {}
58
+ },
59
+
60
+ "minimum" : {
61
+ "type" : "number"
62
+ },
63
+
64
+ "maximum" : {
65
+ "type" : "number"
66
+ },
67
+
68
+ "exclusiveMinimum" : {
69
+ "type" : "boolean",
70
+ "default" : false
71
+ },
72
+
73
+ "exclusiveMaximum" : {
74
+ "type" : "boolean",
75
+ "default" : false
76
+ },
77
+
78
+ "minItems" : {
79
+ "type" : "integer",
80
+ "minimum" : 0,
81
+ "default" : 0
82
+ },
83
+
84
+ "maxItems" : {
85
+ "type" : "integer",
86
+ "minimum" : 0
87
+ },
88
+
89
+ "uniqueItems" : {
90
+ "type" : "boolean",
91
+ "default" : false
92
+ },
93
+
94
+ "pattern" : {
95
+ "type" : "string",
96
+ "format" : "regex"
97
+ },
98
+
99
+ "minLength" : {
100
+ "type" : "integer",
101
+ "minimum" : 0,
102
+ "default" : 0
103
+ },
104
+
105
+ "maxLength" : {
106
+ "type" : "integer"
107
+ },
108
+
109
+ "enum" : {
110
+ "type" : "array",
111
+ "minItems" : 1,
112
+ "uniqueItems" : true
113
+ },
114
+
115
+ "default" : {
116
+ "type" : "any"
117
+ },
118
+
119
+ "title" : {
120
+ "type" : "string"
121
+ },
122
+
123
+ "description" : {
124
+ "type" : "string"
125
+ },
126
+
127
+ "format" : {
128
+ "type" : "string"
129
+ },
130
+
131
+ "divisibleBy" : {
132
+ "type" : "number",
133
+ "minimum" : 0,
134
+ "exclusiveMinimum" : true,
135
+ "default" : 1
136
+ },
137
+
138
+ "disallow" : {
139
+ "type" : ["string", "array"],
140
+ "items" : {
141
+ "type" : ["string", {"$ref" : "#"}]
142
+ },
143
+ "uniqueItems" : true
144
+ },
145
+
146
+ "extends" : {
147
+ "type" : [{"$ref" : "#"}, "array"],
148
+ "items" : {"$ref" : "#"},
149
+ "default" : {}
150
+ },
151
+
152
+ "id" : {
153
+ "type" : "string",
154
+ "format" : "uri"
155
+ },
156
+
157
+ "$ref" : {
158
+ "type" : "string",
159
+ "format" : "uri"
160
+ },
161
+
162
+ "$schema" : {
163
+ "type" : "string",
164
+ "format" : "uri"
165
+ }
166
+ },
167
+
168
+ "dependencies" : {
169
+ "exclusiveMinimum" : "minimum",
170
+ "exclusiveMaximum" : "maximum"
171
+ },
172
+
173
+ "default" : {}
174
+ }