pacto 0.3.1 → 0.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +29 -7
  4. data/.travis.yml +8 -1
  5. data/CONTRIBUTING.md +3 -6
  6. data/Gemfile +13 -2
  7. data/Guardfile +4 -4
  8. data/Procfile +1 -0
  9. data/README.md +47 -13
  10. data/Rakefile +66 -19
  11. data/TODO.md +33 -10
  12. data/bin/pacto +4 -0
  13. data/changelog.md +30 -0
  14. data/docs/configuration.md +69 -0
  15. data/docs/consumer.md +18 -0
  16. data/docs/cops.md +39 -0
  17. data/docs/forensics.md +66 -0
  18. data/docs/generation.md +65 -0
  19. data/docs/rake_tasks.md +10 -0
  20. data/docs/rspec.md +0 -0
  21. data/docs/samples.md +133 -0
  22. data/docs/server.md +34 -0
  23. data/docs/server_cli.md +18 -0
  24. data/docs/stenographer.md +20 -0
  25. data/features/configuration/strict_matchers.feature +10 -10
  26. data/features/evolve/existing_services.feature +12 -10
  27. data/features/generate/generation.feature +11 -11
  28. data/features/steps/pacto_steps.rb +17 -12
  29. data/features/stub/templates.feature +4 -4
  30. data/features/support/env.rb +21 -9
  31. data/features/validate/meta_validation.feature +9 -17
  32. data/features/validate/validation.feature +5 -6
  33. data/lib/pacto.rb +41 -33
  34. data/lib/pacto/actor.rb +5 -0
  35. data/lib/pacto/actors/from_examples.rb +67 -0
  36. data/lib/pacto/actors/json_generator.rb +20 -0
  37. data/lib/pacto/cli.rb +75 -0
  38. data/lib/pacto/cli/helpers.rb +20 -0
  39. data/lib/pacto/consumer.rb +80 -0
  40. data/lib/pacto/consumer/faraday_driver.rb +34 -0
  41. data/lib/pacto/contract.rb +48 -20
  42. data/lib/pacto/contract_builder.rb +125 -0
  43. data/lib/pacto/contract_factory.rb +31 -12
  44. data/lib/pacto/contract_files.rb +1 -0
  45. data/lib/pacto/contract_set.rb +12 -0
  46. data/lib/pacto/cops.rb +46 -0
  47. data/lib/pacto/cops/body_cop.rb +23 -0
  48. data/lib/pacto/cops/request_body_cop.rb +10 -0
  49. data/lib/pacto/cops/response_body_cop.rb +10 -0
  50. data/lib/pacto/{validators/response_header_validator.rb → cops/response_header_cop.rb} +9 -15
  51. data/lib/pacto/cops/response_status_cop.rb +18 -0
  52. data/lib/pacto/core/configuration.rb +16 -5
  53. data/lib/pacto/core/contract_registry.rb +13 -32
  54. data/lib/pacto/core/hook.rb +1 -0
  55. data/lib/pacto/core/http_middleware.rb +23 -0
  56. data/lib/pacto/core/investigation_registry.rb +60 -0
  57. data/lib/pacto/core/modes.rb +1 -0
  58. data/lib/pacto/core/pacto_request.rb +59 -0
  59. data/lib/pacto/core/pacto_response.rb +41 -0
  60. data/lib/pacto/dash.rb +9 -0
  61. data/lib/pacto/erb_processor.rb +1 -0
  62. data/lib/pacto/exceptions/invalid_contract.rb +1 -0
  63. data/lib/pacto/extensions.rb +3 -16
  64. data/lib/pacto/forensics/investigation_filter.rb +90 -0
  65. data/lib/pacto/forensics/investigation_matcher.rb +80 -0
  66. data/lib/pacto/generator.rb +31 -53
  67. data/lib/pacto/generator/filters.rb +8 -7
  68. data/lib/pacto/generator/hint.rb +26 -0
  69. data/lib/pacto/generator/native_contract_generator.rb +74 -0
  70. data/lib/pacto/hooks/erb_hook.rb +2 -1
  71. data/lib/pacto/investigation.rb +49 -0
  72. data/lib/pacto/logger.rb +1 -0
  73. data/lib/pacto/meta_schema.rb +12 -6
  74. data/lib/pacto/native_contract_factory.rb +60 -0
  75. data/lib/pacto/observers/stenographer.rb +42 -0
  76. data/lib/pacto/provider.rb +27 -0
  77. data/lib/pacto/rake_task.rb +25 -70
  78. data/lib/pacto/request_clause.rb +31 -29
  79. data/lib/pacto/request_pattern.rb +20 -3
  80. data/lib/pacto/resettable.rb +22 -0
  81. data/lib/pacto/response_clause.rb +5 -12
  82. data/lib/pacto/rspec.rb +38 -31
  83. data/lib/pacto/server.rb +4 -0
  84. data/lib/pacto/stubs/uri_pattern.rb +21 -11
  85. data/lib/pacto/stubs/webmock_adapter.rb +69 -34
  86. data/lib/pacto/swagger_contract_factory.rb +90 -0
  87. data/lib/pacto/test_helper.rb +37 -0
  88. data/lib/pacto/ui.rb +32 -2
  89. data/lib/pacto/uri.rb +2 -1
  90. data/lib/pacto/version.rb +2 -1
  91. data/pacto-server.gemspec +24 -0
  92. data/pacto.gemspec +13 -9
  93. data/resources/contract_schema.json +46 -18
  94. data/resources/draft-04.json +150 -0
  95. data/sample_apis/album/cover_api.rb +12 -0
  96. data/sample_apis/config.ru +25 -0
  97. data/sample_apis/echo_api.rb +26 -0
  98. data/sample_apis/files_api.rb +50 -0
  99. data/sample_apis/hello_api.rb +14 -0
  100. data/sample_apis/ping_api.rb +11 -0
  101. data/sample_apis/reverse_api.rb +20 -0
  102. data/samples/README.md +11 -0
  103. data/samples/Rakefile +2 -0
  104. data/samples/configuration.rb +33 -0
  105. data/samples/consumer.rb +15 -0
  106. data/samples/contracts/README.md +1 -0
  107. data/samples/contracts/contract.js +93 -0
  108. data/samples/contracts/get_album_cover.json +48 -0
  109. data/samples/contracts/localhost/api/echo.json +37 -0
  110. data/samples/contracts/localhost/api/ping.json +38 -0
  111. data/samples/cops.rb +30 -0
  112. data/samples/forensics.rb +54 -0
  113. data/samples/generation.rb +48 -0
  114. data/samples/rake_tasks.sh +7 -0
  115. data/samples/rspec.rb +1 -0
  116. data/samples/samples.rb +92 -0
  117. data/samples/scripts/bootstrap +2 -0
  118. data/samples/scripts/wrapper +11 -0
  119. data/samples/server.rb +24 -0
  120. data/samples/server_cli.sh +12 -0
  121. data/samples/stenographer.rb +17 -0
  122. data/spec/coveralls_helper.rb +1 -0
  123. data/spec/fabricators/contract_fabricator.rb +94 -0
  124. data/spec/fabricators/http_fabricator.rb +48 -0
  125. data/spec/fabricators/webmock_fabricator.rb +24 -0
  126. data/spec/{unit/data → fixtures/contracts}/contract.json +2 -2
  127. data/spec/fixtures/contracts/contract_with_examples.json +58 -0
  128. data/spec/{unit/data → fixtures/contracts}/simple_contract.json +5 -3
  129. data/spec/{integration/data → fixtures/contracts}/strict_contract.json +5 -3
  130. data/spec/{integration/data → fixtures/contracts}/templating_contract.json +3 -2
  131. data/spec/{integration/data/simple_contract.json → fixtures/deprecated_contracts/deprecated_contract.json} +2 -1
  132. data/spec/fixtures/swagger/petstore.yaml +101 -0
  133. data/spec/integration/e2e_spec.rb +19 -20
  134. data/spec/integration/forensics/integration_matcher_spec.rb +90 -0
  135. data/spec/integration/rspec_spec.rb +22 -25
  136. data/spec/integration/templating_spec.rb +7 -6
  137. data/spec/pacto/dummy_server.rb +4 -0
  138. data/spec/pacto/{server → dummy_server}/dummy.rb +7 -6
  139. data/spec/pacto/dummy_server/jruby_workaround_helper.rb +23 -0
  140. data/spec/pacto/{server → dummy_server}/playback_servlet.rb +3 -2
  141. data/spec/spec_helper.rb +16 -7
  142. data/spec/unit/actors/from_examples_spec.rb +70 -0
  143. data/spec/unit/actors/json_generator_spec.rb +105 -0
  144. data/spec/unit/pacto/actor_spec.rb +23 -0
  145. data/spec/unit/pacto/configuration_spec.rb +7 -6
  146. data/spec/unit/pacto/consumer/faraday_driver_spec.rb +40 -0
  147. data/spec/unit/pacto/contract_builder_spec.rb +89 -0
  148. data/spec/unit/pacto/contract_factory_spec.rb +62 -11
  149. data/spec/unit/pacto/contract_files_spec.rb +1 -0
  150. data/spec/unit/pacto/contract_set_spec.rb +36 -0
  151. data/spec/unit/pacto/contract_spec.rb +51 -39
  152. data/spec/unit/pacto/cops/body_cop_spec.rb +107 -0
  153. data/spec/unit/pacto/{validators/response_header_validator_spec.rb → cops/response_header_cop_spec.rb} +30 -19
  154. data/spec/unit/pacto/cops/response_status_cop_spec.rb +26 -0
  155. data/spec/unit/pacto/cops_spec.rb +75 -0
  156. data/spec/unit/pacto/core/configuration_spec.rb +6 -5
  157. data/spec/unit/pacto/core/contract_registry_spec.rb +16 -83
  158. data/spec/unit/pacto/core/http_middleware_spec.rb +36 -0
  159. data/spec/unit/pacto/core/investigation_spec.rb +62 -0
  160. data/spec/unit/pacto/core/modes_spec.rb +5 -4
  161. data/spec/unit/pacto/erb_processor_spec.rb +3 -2
  162. data/spec/unit/pacto/extensions_spec.rb +10 -20
  163. data/spec/unit/pacto/generator/filters_spec.rb +11 -10
  164. data/spec/unit/pacto/generator/native_contract_generator_spec.rb +171 -0
  165. data/spec/unit/{hooks → pacto/hooks}/erb_hook_spec.rb +18 -11
  166. data/spec/unit/pacto/investigation_registry_spec.rb +77 -0
  167. data/spec/unit/pacto/logger_spec.rb +6 -5
  168. data/spec/unit/pacto/meta_schema_spec.rb +5 -4
  169. data/spec/unit/pacto/native_contract_factory_spec.rb +26 -0
  170. data/spec/unit/pacto/pacto_spec.rb +13 -28
  171. data/spec/unit/pacto/request_clause_spec.rb +16 -51
  172. data/spec/unit/pacto/request_pattern_spec.rb +6 -5
  173. data/spec/unit/pacto/response_clause_spec.rb +6 -19
  174. data/spec/unit/pacto/server/playback_servlet_spec.rb +21 -18
  175. data/spec/unit/pacto/stubs/observers/stenographer_spec.rb +33 -0
  176. data/spec/unit/pacto/stubs/uri_pattern_spec.rb +39 -11
  177. data/spec/unit/pacto/stubs/webmock_adapter_spec.rb +67 -117
  178. data/spec/unit/pacto/swagger_contract_factory_spec.rb +56 -0
  179. data/spec/unit/pacto/uri_spec.rb +1 -0
  180. data/tasks/release.rake +57 -0
  181. metadata +247 -76
  182. data/.rubocop-todo.yml +0 -24
  183. data/.ruby-gemset +0 -1
  184. data/.ruby-version +0 -1
  185. data/CHANGELOG +0 -12
  186. data/features/validate/body_only.feature +0 -85
  187. data/lib/pacto/contract_list.rb +0 -17
  188. data/lib/pacto/contract_validator.rb +0 -29
  189. data/lib/pacto/core/validation_registry.rb +0 -40
  190. data/lib/pacto/stubs/webmock_helper.rb +0 -69
  191. data/lib/pacto/validation.rb +0 -54
  192. data/lib/pacto/validators/body_validator.rb +0 -49
  193. data/lib/pacto/validators/request_body_validator.rb +0 -26
  194. data/lib/pacto/validators/response_body_validator.rb +0 -26
  195. data/lib/pacto/validators/response_status_validator.rb +0 -24
  196. data/spec/pacto/server.rb +0 -2
  197. data/spec/unit/pacto/contract_list_spec.rb +0 -35
  198. data/spec/unit/pacto/contract_validator_spec.rb +0 -85
  199. data/spec/unit/pacto/core/validation_registry_spec.rb +0 -76
  200. data/spec/unit/pacto/core/validation_spec.rb +0 -60
  201. data/spec/unit/pacto/generator_spec.rb +0 -132
  202. data/spec/unit/pacto/stubs/webmock_helper_spec.rb +0 -20
  203. data/spec/unit/pacto/validators/body_validator_spec.rb +0 -118
  204. data/spec/unit/pacto/validators/response_status_validator_spec.rb +0 -20
@@ -1,48 +1,76 @@
1
1
  {
2
2
  "title": "Example Schema",
3
3
  "type": "object",
4
+ "required": ["request", "response"],
5
+ "definitions": {
6
+ "subschema": {
7
+ "anyOf": [
8
+ { "$ref": "http://json-schema.org/draft-03/schema#" },
9
+ { "$ref": "http://json-schema.org/draft-04/schema#" }
10
+ ]
11
+ }
12
+ },
4
13
  "properties": {
5
14
  "name": {
6
- "type": "string",
7
- "required": false
15
+ "type": "string"
8
16
  },
9
17
  "request": {
10
18
  "type": "object",
11
- "required": true,
19
+ "required": ["path"],
12
20
  "properties": {
13
21
  "method": {
14
- "type": "string",
15
- "required": true
22
+ "_deprecated": true,
23
+ "type": "string"
24
+ },
25
+ "http_method": {
26
+ "type": "string"
16
27
  },
17
28
  "path": {
18
- "type": "string",
19
- "required": true
29
+ "type": "string"
20
30
  },
21
31
  "headers": {
22
- "type": "object",
23
- "required": false
32
+ "type": "object"
24
33
  },
25
- "params": {
26
- "type": "object",
27
- "required": false
34
+ "params": {
35
+ "type": "object"
28
36
  },
29
37
  "body": {
30
- "$ref": "http://json-schema.org/draft-03/schema#"
38
+ "description": "body is deprecated, use schema",
39
+ "$ref": "#/definitions/subschema"
40
+ },
41
+ "schema": {
42
+ "$ref": "#/definitions/subschema"
31
43
  }
32
44
  }
33
45
  },
34
46
  "response": {
35
47
  "type": "object",
36
- "required": true,
48
+ "required": ["status"],
37
49
  "properties": {
38
50
  "status":{
39
- "type": "integer",
40
- "required": true
51
+ "type": "integer"
41
52
  },
42
53
  "body": {
43
- "$ref": "http://json-schema.org/draft-03/schema#"
54
+ "description": "body is deprecated, use schema",
55
+ "$ref": "#/definitions/subschema"
56
+ },
57
+ "schema": {
58
+ "$ref": "#/definitions/subschema"
59
+ }
60
+ }
61
+ },
62
+ "examples": {
63
+ "type": "object",
64
+ "additionalProperties": {
65
+ "type": "object",
66
+ "required": ["request", "response"],
67
+ "properties": {
68
+ "request": {
69
+ },
70
+ "response": {
71
+ }
44
72
  }
45
73
  }
46
74
  }
47
75
  }
48
- }
76
+ }
@@ -0,0 +1,150 @@
1
+ {
2
+ "id": "http://json-schema.org/draft-04/schema#",
3
+ "$schema": "http://json-schema.org/draft-04/schema#",
4
+ "description": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "positiveInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "positiveIntegerDefault0": {
16
+ "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
17
+ },
18
+ "simpleTypes": {
19
+ "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
20
+ },
21
+ "stringArray": {
22
+ "type": "array",
23
+ "items": { "type": "string" },
24
+ "minItems": 1,
25
+ "uniqueItems": true
26
+ }
27
+ },
28
+ "type": "object",
29
+ "properties": {
30
+ "id": {
31
+ "type": "string",
32
+ "format": "uri"
33
+ },
34
+ "$schema": {
35
+ "type": "string",
36
+ "format": "uri"
37
+ },
38
+ "title": {
39
+ "type": "string"
40
+ },
41
+ "description": {
42
+ "type": "string"
43
+ },
44
+ "default": {},
45
+ "multipleOf": {
46
+ "type": "number",
47
+ "minimum": 0,
48
+ "exclusiveMinimum": true
49
+ },
50
+ "maximum": {
51
+ "type": "number"
52
+ },
53
+ "exclusiveMaximum": {
54
+ "type": "boolean",
55
+ "default": false
56
+ },
57
+ "minimum": {
58
+ "type": "number"
59
+ },
60
+ "exclusiveMinimum": {
61
+ "type": "boolean",
62
+ "default": false
63
+ },
64
+ "maxLength": { "$ref": "#/definitions/positiveInteger" },
65
+ "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
66
+ "pattern": {
67
+ "type": "string",
68
+ "format": "regex"
69
+ },
70
+ "additionalItems": {
71
+ "anyOf": [
72
+ { "type": "boolean" },
73
+ { "$ref": "#" }
74
+ ],
75
+ "default": {}
76
+ },
77
+ "items": {
78
+ "anyOf": [
79
+ { "$ref": "#" },
80
+ { "$ref": "#/definitions/schemaArray" }
81
+ ],
82
+ "default": {}
83
+ },
84
+ "maxItems": { "$ref": "#/definitions/positiveInteger" },
85
+ "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
86
+ "uniqueItems": {
87
+ "type": "boolean",
88
+ "default": false
89
+ },
90
+ "maxProperties": { "$ref": "#/definitions/positiveInteger" },
91
+ "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
92
+ "required": { "$ref": "#/definitions/stringArray" },
93
+ "additionalProperties": {
94
+ "anyOf": [
95
+ { "type": "boolean" },
96
+ { "$ref": "#" }
97
+ ],
98
+ "default": {}
99
+ },
100
+ "definitions": {
101
+ "type": "object",
102
+ "additionalProperties": { "$ref": "#" },
103
+ "default": {}
104
+ },
105
+ "properties": {
106
+ "type": "object",
107
+ "additionalProperties": { "$ref": "#" },
108
+ "default": {}
109
+ },
110
+ "patternProperties": {
111
+ "type": "object",
112
+ "additionalProperties": { "$ref": "#" },
113
+ "default": {}
114
+ },
115
+ "dependencies": {
116
+ "type": "object",
117
+ "additionalProperties": {
118
+ "anyOf": [
119
+ { "$ref": "#" },
120
+ { "$ref": "#/definitions/stringArray" }
121
+ ]
122
+ }
123
+ },
124
+ "enum": {
125
+ "type": "array",
126
+ "minItems": 1,
127
+ "uniqueItems": true
128
+ },
129
+ "type": {
130
+ "anyOf": [
131
+ { "$ref": "#/definitions/simpleTypes" },
132
+ {
133
+ "type": "array",
134
+ "items": { "$ref": "#/definitions/simpleTypes" },
135
+ "minItems": 1,
136
+ "uniqueItems": true
137
+ }
138
+ ]
139
+ },
140
+ "allOf": { "$ref": "#/definitions/schemaArray" },
141
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
142
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
143
+ "not": { "$ref": "#" }
144
+ },
145
+ "dependencies": {
146
+ "exclusiveMaximum": [ "maximum" ],
147
+ "exclusiveMinimum": [ "minimum" ]
148
+ },
149
+ "default": {}
150
+ }
@@ -0,0 +1,12 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module AlbumServices
3
+ class Cover < Grape::API
4
+ format :json
5
+ desc 'Ping'
6
+ namespace :album do
7
+ get ':id/cover' do
8
+ { cover: 'image' }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ require 'grape'
2
+ require 'grape-swagger'
3
+ require 'json'
4
+ Dir[File.expand_path('../**/*_api.rb', __FILE__)].each do |f|
5
+ puts "Requiring #{f}"
6
+ require f
7
+ end
8
+
9
+ module DummyServices
10
+ class API < Grape::API
11
+ prefix 'api'
12
+ format :json
13
+ mount DummyServices::Hello
14
+ mount DummyServices::Ping
15
+ mount DummyServices::Echo
16
+ mount DummyServices::Files
17
+ mount DummyServices::Reverse
18
+ mount AlbumServices::Cover
19
+ add_swagger_documentation # api_version: 'v1'
20
+ end
21
+ end
22
+ DummyServices::API.routes.each do |route|
23
+ p route
24
+ end
25
+ run DummyServices::API
@@ -0,0 +1,26 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This illustrates simple get w/ params and post w/ body services
3
+ # It also illustrates having two services w/ the same endpoint (just different HTTP methods)
4
+ module DummyServices
5
+ class Echo < Grape::API
6
+ format :json
7
+ content_type :txt, 'text/plain'
8
+
9
+ helpers do
10
+ def echo(message)
11
+ error!('Bad Request', 400) unless message
12
+ message
13
+ end
14
+ end
15
+
16
+ # curl localhost:5000/api/echo --get --data-urlencode 'msg={"one fish": "two fish"}' -vv
17
+ get '/echo' do
18
+ echo params[:msg]
19
+ end
20
+
21
+ # curl localhost:5000/api/echo -H 'Content-Type: text/plain' -d '{"red fish": "blue fish"}' -vv
22
+ post '/echo' do
23
+ echo env['api.request.body']
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This example should illustrate
3
+ # - Authentication
4
+ # - Expect: 100-continue
5
+ # - Binary data
6
+ # - Content negotiation
7
+ # - Etags
8
+ # - Collections
9
+ module DummyServices
10
+ class PartialRequestException < StandardError
11
+ attr_reader :http_status, :msg
12
+ def initialize(http_status, msg)
13
+ @http_status = http_status
14
+ @msg = msg
15
+ end
16
+ end
17
+
18
+ class Files < Grape::API
19
+ format :json
20
+ content_type :binary, 'application/octet-stream'
21
+ content_type :pdf, 'application/pdf'
22
+
23
+ before do
24
+ error!('Unauthorized', 401) unless env['HTTP_X_AUTH_TOKEN'] == '12345'
25
+
26
+ if env['HTTP_EXPECT'] == '100-continue'
27
+ # Can't use Content-Type because Grape tries to handle it, causing problems
28
+ case env['CONTENT_TYPE']
29
+ when 'application/pdf'
30
+ fail DummyServices::PartialRequestException.new(100, 'Continue')
31
+ when 'application/webm'
32
+ fail DummyServices::PartialRequestException.new(415, 'Unsupported Media Type')
33
+ else
34
+ fail DummyServices::PartialRequestException.new(417, 'Expectation Failed')
35
+ end
36
+ end
37
+ end
38
+
39
+ rescue_from DummyServices::PartialRequestException do |e|
40
+ Rack::Response.new([], e.http_status, {}).finish
41
+ end
42
+
43
+ namespace '/files' do
44
+ # curl localhost:5000/api/files/myfile.txt -H 'X-Auth-Token: 12345' -d @myfile.txt -vv
45
+ put ':name' do
46
+ params[:name]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This illustrates a simple get service
3
+ module DummyServices
4
+ class Hello < Grape::API
5
+ format :json
6
+ content_type :json, 'application/json'
7
+
8
+ desc 'Hello'
9
+ get '/hello' do
10
+ header 'Vary', 'Accept'
11
+ { message: 'Hello World!' }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This illustrates a simple get service
3
+ module DummyServices
4
+ class Ping < Grape::API
5
+ format :json
6
+ desc 'Ping'
7
+ get '/ping' do
8
+ { ping: 'pong' }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This illustrates simple get w/ params and post w/ body services
3
+ # It also illustrates having two services w/ the same endpoint (just different HTTP methods)
4
+ module DummyServices
5
+ class Reverse < Grape::API
6
+ format :txt
7
+
8
+ helpers do
9
+ def echo(message)
10
+ error!('Bad Request', 400) unless message
11
+ message
12
+ end
13
+ end
14
+
15
+ # curl localhost:5000/api/echo -H 'Content-Type: application/json' -d '{"red fish": "blue fish"}' -vv
16
+ post '/reverse' do
17
+ echo(env['api.request.body']).reverse
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ Welcome to the Pacto usage samples!
2
+
3
+ We have a listing of [sample contracts](contracts/README.html).
4
+
5
+ Highlighted samples:
6
+
7
+ - *[Configuration](configuration.html)*: Shows the available Pacto configuration
8
+ - *[Generation](generation.html)*: Shows how to generate Contracts
9
+ - *[RSpec](rspec.html)*: Shows the usage of RSpec expectations for collaboration tests
10
+
11
+ See the Table of Contents (upper right corner) for a full list of available samples.
@@ -0,0 +1,2 @@
1
+ require 'pacto/rake_task' # FIXME: This require turns on WebMock
2
+ WebMock.allow_net_connect!
@@ -0,0 +1,33 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Just require pacto to add it to your project.
3
+ require 'pacto'
4
+ # Pacto will disable live connections, so you will get an error if
5
+ # your code unexpectedly calls an service that was not stubbed. If you
6
+ # want to re-enable connections, run `WebMock.allow_net_connect!`
7
+ WebMock.allow_net_connect!
8
+
9
+ # Pacto can be configured via a block:
10
+ Pacto.configure do |c|
11
+ # Path for loading/storing contracts.
12
+ c.contracts_path = 'contracts'
13
+ # If the request matching should be strict (especially regarding HTTP Headers).
14
+ c.strict_matchers = true
15
+ # You can set the Ruby Logger used by Pacto.
16
+ c.logger = Pacto::Logger::SimpleLogger.instance
17
+ # (Deprecated) You can specify a callback for post-processing responses. Note that only one hook
18
+ # can be active, and specifying your own will disable ERB post-processing.
19
+ c.register_hook do |_contracts, request, _response|
20
+ puts "Received #{request}"
21
+ end
22
+ # Options to pass to the [json-schema-generator](https://github.com/maxlinc/json-schema-generator) while generating contracts.
23
+ c.generator_options = { schema_version: 'draft3' }
24
+ end
25
+
26
+ # You can also do inline configuration. This example tells the json-schema-generator to store default values in the schema.
27
+ Pacto.configuration.generator_options = { defaults: true }
28
+
29
+ # If you're using Pacto's rspec matchers you might want to configure a reset between each scenario
30
+ require 'pacto/rspec'
31
+ RSpec.configure do |c|
32
+ c.after(:each) { Pacto.clear! }
33
+ end