interpol 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- @app = app
15
- hook_into(app, &block)
15
+ @original_app_instance = app
16
+ hook_into_app(&block)
16
17
  end
17
18
 
18
19
  def call(env)
19
- @app.call(env)
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
- def hook_into(app, &block)
25
- return if defined?(app.settings.interpol_config)
26
- config = Configuration.default.customized_duplicate(&block)
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
- app.class.class_eval do
43
+ original_app_instance.class.class_eval do
29
44
  alias unparsed_params params
30
- helpers SinatraHelpers
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
- module SinatraHelpers
38
- # Make the config available at the instance level for convenience.
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
- def endpoint_definition
44
- @endpoint_definition ||= begin
45
- version = available_versions = nil
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
- definition
60
- end
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 params
64
- (@_use_parsed_params && @_parsed_params) || super
65
+ def initialize(config, app)
66
+ @config = config
67
+ @app = app
65
68
  end
66
69
 
67
- def validate_params
68
- @_parsed_params ||= endpoint_definition.parse_request_params(params_to_parse)
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
- def request_params_invalid(error)
74
- interpol_config.sinatra_request_params_invalid(self, error)
75
- end
76
+ private
76
77
 
77
- def with_parsed_params
78
- @_use_parsed_params = true
79
- validate_params if settings.parse_params?
80
- yield
81
- ensure
82
- @_use_parsed_params = false
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
@@ -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 :interpol_config, config
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
- @app.interpol_config.endpoints.each do |endpoint|
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 = interpol_config.api_version_for(request.env, endpoint)
58
- message_type = 'response'
59
- example = example_for(endpoint, version, message_type)
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
@@ -1,3 +1,3 @@
1
1
  module Interpol
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
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.2
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: -4117955588587785690
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: -4117955588587785690
235
+ hash: 2654545236171025309
236
236
  requirements: []
237
237
  rubyforge_project:
238
238
  rubygems_version: 1.8.24