interpol 0.3.2 → 0.3.3
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.
- data/lib/interpol/sinatra/request_params_parser.rb +78 -45
- data/lib/interpol/stub_app.rb +19 -21
- data/lib/interpol/version.rb +1 -1
- metadata +3 -3
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'interpol/request_params_parser'
|
2
|
+
require 'forwardable'
|
2
3
|
|
3
4
|
module Interpol
|
4
5
|
module Sinatra
|
@@ -11,89 +12,110 @@ module Interpol
|
|
11
12
|
# it can take a config block.
|
12
13
|
class RequestParamsParser
|
13
14
|
def initialize(app, &block)
|
14
|
-
@
|
15
|
-
|
15
|
+
@original_app_instance = app
|
16
|
+
hook_into_app(&block)
|
16
17
|
end
|
17
18
|
|
18
19
|
def call(env)
|
19
|
-
@
|
20
|
+
@original_app_instance.call(env)
|
21
|
+
end
|
22
|
+
|
23
|
+
ConfigurationError = Class.new(StandardError)
|
24
|
+
|
25
|
+
# Sinatra dups the app before each request, so we need to
|
26
|
+
# receive the app instance as an argument here.
|
27
|
+
def validate_and_parse_params(app)
|
28
|
+
return unless app.settings.parse_params?
|
29
|
+
SingleRequestParamsParser.parse_params(config, app)
|
20
30
|
end
|
21
31
|
|
22
32
|
private
|
23
33
|
|
24
|
-
|
25
|
-
|
26
|
-
|
34
|
+
attr_reader :config, :original_app_instance
|
35
|
+
|
36
|
+
def hook_into_app(&block)
|
37
|
+
return if defined?(@config)
|
38
|
+
check_configuration_validity
|
39
|
+
|
40
|
+
@config = Configuration.default.customized_duplicate(&block)
|
41
|
+
parser = self
|
27
42
|
|
28
|
-
|
43
|
+
original_app_instance.class.class_eval do
|
29
44
|
alias unparsed_params params
|
30
|
-
|
31
|
-
set :interpol_config, config
|
45
|
+
set :request_params_parser, parser
|
32
46
|
enable :parse_params unless settings.respond_to?(:parse_params)
|
33
47
|
include SinatraOverriddes
|
34
48
|
end
|
35
49
|
end
|
36
50
|
|
37
|
-
|
38
|
-
|
39
|
-
def interpol_config
|
40
|
-
self.class.interpol_config
|
41
|
-
end
|
51
|
+
def check_configuration_validity
|
52
|
+
return if original_app_instance.class.ancestors.include?(::Sinatra::Base)
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
definition = interpol_config.endpoints.find_definition \
|
48
|
-
env.fetch('REQUEST_METHOD'), request.path, 'request', nil do |endpoint|
|
49
|
-
available_versions ||= endpoint.available_versions
|
50
|
-
interpol_config.api_version_for(env, endpoint).tap do |_version|
|
51
|
-
version ||= _version
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
if definition == DefinitionFinder::NoDefinitionFound
|
56
|
-
interpol_config.request_version_unavailable(self, version, available_versions)
|
57
|
-
end
|
54
|
+
raise ConfigurationError, "#{self.class} must come last in the Sinatra " +
|
55
|
+
"middleware list but #{original_app_instance.class} " +
|
56
|
+
"currently comes after."
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
# Handles finding parsing request params for a single request.
|
60
|
+
class SingleRequestParamsParser
|
61
|
+
def self.parse_params(config, app)
|
62
|
+
new(config, app).parse_params
|
61
63
|
end
|
62
64
|
|
63
|
-
def
|
64
|
-
|
65
|
+
def initialize(config, app)
|
66
|
+
@config = config
|
67
|
+
@app = app
|
65
68
|
end
|
66
69
|
|
67
|
-
def
|
68
|
-
|
70
|
+
def parse_params
|
71
|
+
endpoint_definition.parse_request_params(params_to_parse)
|
69
72
|
rescue Interpol::ValidationError => error
|
70
73
|
request_params_invalid(error)
|
71
74
|
end
|
72
75
|
|
73
|
-
|
74
|
-
interpol_config.sinatra_request_params_invalid(self, error)
|
75
|
-
end
|
76
|
+
private
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
attr_reader :app, :config
|
79
|
+
extend Forwardable
|
80
|
+
def_delegators :app, :request
|
81
|
+
|
82
|
+
def endpoint_definition
|
83
|
+
version = available_versions = nil
|
84
|
+
|
85
|
+
definition = config.endpoints.find_definition \
|
86
|
+
request.env.fetch('REQUEST_METHOD'), request.path, 'request', nil do |endpoint|
|
87
|
+
available_versions ||= endpoint.available_versions
|
88
|
+
config.api_version_for(request.env, endpoint).tap do |_version|
|
89
|
+
version ||= _version
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if definition == DefinitionFinder::NoDefinitionFound
|
94
|
+
config.request_version_unavailable(app, version, available_versions)
|
95
|
+
end
|
96
|
+
|
97
|
+
definition
|
83
98
|
end
|
84
99
|
|
85
100
|
# Sinatra includes a couple of "meta" params that are always
|
86
101
|
# present in the params hash even though they are not declared
|
87
102
|
# as params: splat and captures.
|
88
103
|
def params_to_parse
|
89
|
-
unparsed_params.dup.tap do |p|
|
104
|
+
app.unparsed_params.dup.tap do |p|
|
90
105
|
p.delete('splat')
|
91
106
|
p.delete('captures')
|
92
107
|
end
|
93
108
|
end
|
109
|
+
|
110
|
+
def request_params_invalid(error)
|
111
|
+
config.sinatra_request_params_invalid(app, error)
|
112
|
+
end
|
94
113
|
end
|
95
114
|
|
96
115
|
module SinatraOverriddes
|
116
|
+
extend Forwardable
|
117
|
+
def_delegators :settings, :request_params_parser
|
118
|
+
|
97
119
|
# We cannot access the full params (w/ path params) in a before hook,
|
98
120
|
# due to the order that sinatra runs the hooks in relation to route
|
99
121
|
# matching.
|
@@ -115,6 +137,17 @@ module Interpol
|
|
115
137
|
return true unless block.respond_to?(:source_location)
|
116
138
|
block.source_location.first.end_with?('sinatra/base.rb')
|
117
139
|
end
|
140
|
+
|
141
|
+
def params
|
142
|
+
@_parsed_params || super
|
143
|
+
end
|
144
|
+
|
145
|
+
def with_parsed_params
|
146
|
+
@_parsed_params = request_params_parser.validate_and_parse_params(self)
|
147
|
+
yield
|
148
|
+
ensure
|
149
|
+
@_parsed_params = nil
|
150
|
+
end
|
118
151
|
end
|
119
152
|
end
|
120
153
|
end
|
data/lib/interpol/stub_app.rb
CHANGED
@@ -13,29 +13,17 @@ module Interpol
|
|
13
13
|
builder.app
|
14
14
|
end
|
15
15
|
|
16
|
-
module Helpers
|
17
|
-
def interpol_config
|
18
|
-
self.class.interpol_config
|
19
|
-
end
|
20
|
-
|
21
|
-
def example_for(endpoint, version, message_type)
|
22
|
-
example = endpoint.find_example_for!(version, message_type)
|
23
|
-
rescue NoEndpointDefinitionFoundError
|
24
|
-
interpol_config.request_version_unavailable(self, version, endpoint.available_versions)
|
25
|
-
else
|
26
|
-
example.apply_filters(interpol_config.filter_example_data_blocks, request.env)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
16
|
# Private: Builds a stub sinatra app for the given interpol
|
31
17
|
# configuration.
|
32
18
|
class Builder
|
33
|
-
attr_reader :app
|
19
|
+
attr_reader :app, :config
|
34
20
|
|
35
21
|
def initialize(config)
|
22
|
+
builder = self
|
23
|
+
@config = config
|
24
|
+
|
36
25
|
@app = ::Sinatra.new do
|
37
|
-
set :
|
38
|
-
helpers Helpers
|
26
|
+
set :stub_app_builder, builder
|
39
27
|
not_found { JSON.dump(:error => "The requested resource could not be found") }
|
40
28
|
before { content_type "application/json;charset=utf-8" }
|
41
29
|
get('/__ping') { JSON.dump(:message => "Interpol stub app running.") }
|
@@ -47,21 +35,31 @@ module Interpol
|
|
47
35
|
end
|
48
36
|
|
49
37
|
def build
|
50
|
-
|
38
|
+
config.endpoints.each do |endpoint|
|
51
39
|
app.send(endpoint.method, endpoint.route, &endpoint_definition(endpoint))
|
52
40
|
end
|
53
41
|
end
|
54
42
|
|
55
43
|
def endpoint_definition(endpoint)
|
56
44
|
lambda do
|
57
|
-
version =
|
58
|
-
|
59
|
-
|
45
|
+
example, version = settings.
|
46
|
+
stub_app_builder.
|
47
|
+
example_and_version_for(endpoint, self)
|
60
48
|
example.validate!
|
61
49
|
status endpoint.find_example_status_code_for!(version)
|
62
50
|
JSON.dump(example.data)
|
63
51
|
end
|
64
52
|
end
|
53
|
+
|
54
|
+
def example_and_version_for(endpoint, app)
|
55
|
+
version = config.api_version_for(app.request.env, endpoint)
|
56
|
+
example = endpoint.find_example_for!(version, 'response')
|
57
|
+
rescue NoEndpointDefinitionFoundError
|
58
|
+
config.request_version_unavailable(app, version, endpoint.available_versions)
|
59
|
+
else
|
60
|
+
example.apply_filters(config.filter_example_data_blocks, app.request.env)
|
61
|
+
return example, version
|
62
|
+
end
|
65
63
|
end
|
66
64
|
end
|
67
65
|
end
|
data/lib/interpol/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interpol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -223,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
223
|
version: '0'
|
224
224
|
segments:
|
225
225
|
- 0
|
226
|
-
hash:
|
226
|
+
hash: 2654545236171025309
|
227
227
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
228
|
none: false
|
229
229
|
requirements:
|
@@ -232,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
232
|
version: '0'
|
233
233
|
segments:
|
234
234
|
- 0
|
235
|
-
hash:
|
235
|
+
hash: 2654545236171025309
|
236
236
|
requirements: []
|
237
237
|
rubyforge_project:
|
238
238
|
rubygems_version: 1.8.24
|