interpol 0.5.0 → 0.6.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.
data/Rakefile CHANGED
@@ -14,11 +14,9 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' # MRI only
14
14
  desc "Run cane to check quality metrics"
15
15
  Cane::RakeTask.new(:quality) do |cane|
16
16
  cane.abc_max = 13
17
- cane.add_threshold 'coverage/coverage_percent.txt', :==, 100
18
17
  cane.style_measure = 100
19
18
 
20
19
  cane.abc_exclude = %w[
21
- Interpol::Configuration#register_default_callbacks
22
20
  Interpol::StubApp::Builder#initialize
23
21
  ]
24
22
 
@@ -26,11 +24,24 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' # MRI only
26
24
  spec/unit/interpol/sinatra/request_params_parser_spec.rb
27
25
  ]
28
26
  end
27
+
28
+ desc "Checks the spec coverage and fails if it is less than 100%"
29
+ task :check_coverage do
30
+ puts "Checking code coverage..."
31
+ percent = File.read("coverage/coverage_percent.txt").to_f
32
+
33
+ if percent < 100
34
+ raise "Failed to achieve 100% code coverage: #{percent}"
35
+ else
36
+ puts "Nice work! Code coverage is still 100%"
37
+ end
38
+ end
29
39
  else
30
40
  task(:quality) { } # no-op
41
+ task(:check_coverage) { } # no-op
31
42
  end
32
43
 
33
- task :default => [:spec, :quality]
44
+ task :default => [:spec, :quality, :check_coverage]
34
45
 
35
46
  desc "Watch Documentation App Compass Files"
36
47
  task :compass_watch do
@@ -0,0 +1,86 @@
1
+ define_request_param_parser('integer') do |param|
2
+ param.string_validation_options 'pattern' => '^\-?\d+$'
3
+
4
+ param.parse do |value|
5
+ begin
6
+ raise TypeError unless value # On 1.8.7 Integer(nil) does not raise an error
7
+ Integer(value)
8
+ rescue TypeError
9
+ raise ArgumentError, "Could not convert #{value.inspect} to an integer"
10
+ end
11
+ end
12
+ end
13
+
14
+ define_request_param_parser('number') do |param|
15
+ param.string_validation_options 'pattern' => '^\-?\d+(\.\d+)?$'
16
+
17
+ param.parse do |value|
18
+ begin
19
+ Float(value)
20
+ rescue TypeError
21
+ raise ArgumentError, "Could not convert #{value.inspect} to a float"
22
+ end
23
+ end
24
+ end
25
+
26
+ define_request_param_parser('boolean') do |param|
27
+ param.string_validation_options 'enum' => %w[ true false ]
28
+
29
+ booleans = { 'true' => true, true => true,
30
+ 'false' => false, false => false }
31
+ param.parse do |value|
32
+ booleans.fetch(value) do
33
+ raise ArgumentError, "Could not convert #{value.inspect} to a boolean"
34
+ end
35
+ end
36
+ end
37
+
38
+ define_request_param_parser('null') do |param|
39
+ param.string_validation_options 'enum' => ['']
40
+
41
+ nulls = { '' => nil, nil => nil }
42
+ param.parse do |value|
43
+ nulls.fetch(value) do
44
+ raise ArgumentError, "Could not convert #{value.inspect} to a null"
45
+ end
46
+ end
47
+ end
48
+
49
+ define_request_param_parser('string') do |param|
50
+ param.parse do |value|
51
+ unless value.is_a?(String)
52
+ raise ArgumentError, "#{value.inspect} is not a string"
53
+ end
54
+
55
+ value
56
+ end
57
+ end
58
+
59
+ define_request_param_parser('string', 'format' => 'date') do |param|
60
+ param.parse do |value|
61
+ unless value =~ /\A\d{4}\-\d{2}\-\d{2}\z/
62
+ raise ArgumentError, "#{value.inspect} is not in iso8601 format"
63
+ end
64
+
65
+ Date.new(*value.split('-').map(&:to_i))
66
+ end
67
+ end
68
+
69
+ define_request_param_parser('string', 'format' => 'date-time') do |param|
70
+ param.parse &Time.method(:iso8601)
71
+ end
72
+
73
+ define_request_param_parser('string', 'format' => 'uri') do |param|
74
+ param.parse do |value|
75
+ begin
76
+ URI(value).tap do |uri|
77
+ unless uri.scheme && uri.host
78
+ raise ArgumentError, "#{uri.inspect} is not a valid full URI"
79
+ end
80
+ end
81
+ rescue URI::InvalidURIError => e
82
+ raise ArgumentError, e.message, e.backtrace
83
+ end
84
+ end
85
+ end
86
+
@@ -0,0 +1,46 @@
1
+ request_version do
2
+ raise ConfigurationError, "request_version has not been configured"
3
+ end
4
+
5
+ response_version do
6
+ raise ConfigurationError, "response_version has not been configured"
7
+ end
8
+
9
+ validate_response_if do |env, status, headers, body|
10
+ headers['Content-Type'].to_s.include?('json') &&
11
+ status >= 200 && status <= 299 && status != 204 # No Content
12
+ end
13
+
14
+ validate_request_if do |env|
15
+ env['CONTENT_TYPE'].to_s.include?('json') &&
16
+ %w[ POST PUT PATCH ].include?(env.fetch('REQUEST_METHOD'))
17
+ end
18
+
19
+ on_unavailable_request_version do |env, requested, available|
20
+ message = "The requested request version is invalid. " +
21
+ "Requested: #{requested}. " +
22
+ "Available: #{available}"
23
+
24
+ rack_json_response(406, :error => message)
25
+ end
26
+
27
+ on_unavailable_sinatra_request_version do |requested, available|
28
+ message = "The requested request version is invalid. " +
29
+ "Requested: #{requested}. " +
30
+ "Available: #{available}"
31
+
32
+ halt 406, JSON.dump(:error => message)
33
+ end
34
+
35
+ on_invalid_request_body do |env, error|
36
+ rack_json_response(400, :error => error.message)
37
+ end
38
+
39
+ on_invalid_sinatra_request_params do |error|
40
+ halt 400, JSON.dump(:error => error.message)
41
+ end
42
+
43
+ select_example_response do |endpoint_def, _|
44
+ endpoint_def.examples.first
45
+ end
46
+
@@ -2,6 +2,7 @@ require 'interpol/endpoint'
2
2
  require 'interpol/errors'
3
3
  require 'yaml'
4
4
  require 'interpol/configuration_ruby_18_extensions' if RUBY_VERSION.to_f < 1.9
5
+ require 'uri'
5
6
 
6
7
  module Interpol
7
8
  module DefinitionFinder
@@ -40,6 +41,7 @@ module Interpol
40
41
  self.endpoint_definition_merge_key_files = []
41
42
  self.documentation_title = "API Documentation Provided by Interpol"
42
43
  register_default_callbacks
44
+ register_built_in_param_parsers
43
45
  @filter_example_data_blocks = []
44
46
 
45
47
  yield self if block_given?
@@ -163,6 +165,23 @@ module Interpol
163
165
  dup.tap(&block)
164
166
  end
165
167
 
168
+ def define_request_param_parser(type, options = {}, &block)
169
+ ParamParser.new(type, options, &block).tap do |parser|
170
+ # Use unshift so that new parsers take precedence over older ones.
171
+ param_parsers[type].unshift parser
172
+ end
173
+ end
174
+
175
+ def param_parser_for(type, options)
176
+ match = param_parsers[type].find do |parser|
177
+ parser.matches_options?(options)
178
+ end
179
+
180
+ return match if match
181
+
182
+ raise UnsupportedTypeError.new(type, options)
183
+ end
184
+
166
185
  private
167
186
 
168
187
  # 1.9 version
@@ -204,51 +223,70 @@ module Interpol
204
223
  @named_example_selectors ||= {}
205
224
  end
206
225
 
207
- def register_default_callbacks
208
- request_version do
209
- raise ConfigurationError, "request_version has not been configured"
210
- end
226
+ def param_parsers
227
+ @param_parsers ||= Hash.new { |h, k| h[k] = [] }
228
+ end
211
229
 
212
- response_version do
213
- raise ConfigurationError, "response_version has not been configured"
214
- end
230
+ def self.instance_eval_args_for(file)
231
+ filename = File.expand_path("../configuration/#{file}.rb", __FILE__)
232
+ contents = File.read(filename)
233
+ [contents, filename, 1]
234
+ end
215
235
 
216
- validate_response_if do |env, status, headers, body|
217
- headers['Content-Type'].to_s.include?('json') &&
218
- status >= 200 && status <= 299 && status != 204 # No Content
219
- end
236
+ BUILT_IN_PARSER_EVAL_ARGS = instance_eval_args_for("built_in_param_parsers")
220
237
 
221
- validate_request_if do |env|
222
- env['CONTENT_TYPE'].to_s.include?('json') &&
223
- %w[ POST PUT PATCH ].include?(env.fetch('REQUEST_METHOD'))
224
- end
238
+ def register_built_in_param_parsers
239
+ instance_eval(*BUILT_IN_PARSER_EVAL_ARGS)
240
+ end
225
241
 
226
- on_unavailable_request_version do |env, requested, available|
227
- message = "The requested request version is invalid. " +
228
- "Requested: #{requested}. " +
229
- "Available: #{available}"
242
+ DEFAULT_CALLBACK_EVAL_ARGS = instance_eval_args_for("default_callbacks")
243
+ def register_default_callbacks
244
+ instance_eval(*DEFAULT_CALLBACK_EVAL_ARGS)
245
+ end
246
+ end
230
247
 
231
- rack_json_response(406, :error => message)
232
- end
248
+ # Holds the validation/parsing logic for a particular parameter
249
+ # type (w/ additional options).
250
+ class ParamParser
251
+ def initialize(type, options = {})
252
+ @type = type
253
+ @options = options
254
+ yield self
255
+ end
233
256
 
234
- on_unavailable_sinatra_request_version do |requested, available|
235
- message = "The requested request version is invalid. " +
236
- "Requested: #{requested}. " +
237
- "Available: #{available}"
257
+ def string_validation_options(options = nil, &block)
258
+ @string_validation_options_block = block || Proc.new { options }
259
+ end
238
260
 
239
- halt 406, JSON.dump(:error => message)
240
- end
261
+ def parse(&block)
262
+ @parse_block = block
263
+ end
241
264
 
242
- on_invalid_request_body do |env, error|
243
- rack_json_response(400, :error => error.message)
265
+ def matches_options?(options)
266
+ @options.all? do |key, value|
267
+ options.has_key?(key) && options[key] == value
244
268
  end
269
+ end
270
+
271
+ def type_validation_options_for(type, options)
272
+ return type unless @string_validation_options_block
273
+ string_options = @string_validation_options_block.call(options)
274
+ Array(type) + [string_options.merge('type' => 'string')]
275
+ end
245
276
 
246
- on_invalid_sinatra_request_params do |error|
247
- halt 400, JSON.dump(:error => error.message)
277
+ def parse_value(value)
278
+ unless @parse_block
279
+ raise "No parse callback has been set for param type definition: #{description}"
248
280
  end
249
281
 
250
- select_example_response do |endpoint_def, _|
251
- endpoint_def.examples.first
282
+ @parse_block.call(value)
283
+ end
284
+
285
+ def description
286
+ @description ||= @type.inspect.tap do |desc|
287
+ if @options.any?
288
+ desc << " (with options: #{@options.inspect})"
289
+ end
252
290
  end
253
291
  end
254
292
  end
@@ -25,10 +25,16 @@ module Interpol
25
25
  when Array
26
26
  object.each { |obj| recursively_freeze(obj) }
27
27
  when Hash
28
- object.default_proc = DEFAULT_PROC
28
+ set_default_proc_on(object)
29
29
  recursively_freeze(object.values)
30
30
  end
31
31
  end
32
+
33
+ def self.set_default_proc_on(hash)
34
+ hash.default_proc = DEFAULT_PROC
35
+ end
32
36
  end
33
37
  end
34
38
 
39
+ require 'interpol/hash_set_default_proc_18' unless {}.respond_to?(:default_proc=)
40
+
@@ -201,14 +201,6 @@ module Interpol
201
201
  @example_status_code ||= @status_codes.example_status_code
202
202
  end
203
203
 
204
- def parse_request_params(request_params)
205
- request_params_parser.parse(request_params)
206
- end
207
-
208
- def request_params_parser
209
- @request_params_parser ||= RequestParamsParser.new(self)
210
- end
211
-
212
204
  private
213
205
 
214
206
  def make_schema_strict!(raw_schema, modify_object=true)
@@ -38,5 +38,35 @@ module Interpol
38
38
 
39
39
  # Raised when an invalid status code is found during validate_codes!
40
40
  class StatusCodeMatcherArgumentError < ArgumentError; end
41
+
42
+ # Raised when an unsupported parameter type is defined.
43
+ class UnsupportedTypeError < ArgumentError
44
+ attr_reader :type, :options
45
+
46
+ def initialize(type, options = {})
47
+ @type = type
48
+ @options = options
49
+
50
+ description = type.inspect
51
+ description << " (#{options.inspect})" if options.any?
52
+ super("No param parser can be found for #{description}")
53
+ end
54
+ end
55
+
56
+ # Raised when the path_params are not part of the endpoint route.
57
+ class InvalidPathParamsError < ArgumentError
58
+ attr_reader :invalid_params
59
+
60
+ def initialize(*invalid_params)
61
+ @invalid_params = invalid_params
62
+ super("The path params #{invalid_params.join(', ')} are not in the route")
63
+ end
64
+ end
65
+
66
+ # Raised when a parameter value cannot be parsed.
67
+ CannotBeParsedError = Class.new(ArgumentError)
68
+
69
+ # Raised when a params definition is invalid.
70
+ InvalidParamsDefinitionError = Class.new(ArgumentError)
41
71
  end
42
72
 
@@ -0,0 +1,9 @@
1
+ module Interpol
2
+ module DynamicStruct
3
+ # Hash#default_proc= isn't defined on 1.8; this is the best we can do.
4
+ def self.set_default_proc_on(hash)
5
+ hash.replace(Hash.new(&DEFAULT_PROC).merge(hash))
6
+ end
7
+ end
8
+ end
9
+
@@ -1,6 +1,5 @@
1
1
  require 'interpol'
2
2
  require 'interpol/dynamic_struct'
3
- require 'uri'
4
3
  require 'interpol/each_with_object' unless Enumerable.method_defined?(:each_with_object)
5
4
 
6
5
  module Interpol
@@ -20,10 +19,10 @@ module Interpol
20
19
  # The parsed params object supports dot-syntax for accessing parameters
21
20
  # and will convert values where feasible (e.g. '3' = 3, 'true' => true, etc).
22
21
  class RequestParamsParser
23
- def initialize(endpoint_definition)
24
- @validator = ParamValidator.new(endpoint_definition)
22
+ def initialize(endpoint_definition, configuration)
23
+ @validator = ParamValidator.new(endpoint_definition, configuration)
25
24
  @validator.validate_path_params_valid_for_route!
26
- @converter = ParamConverter.new(@validator.param_definitions)
25
+ @converter = ParamConverter.new(@validator.param_definitions, configuration)
27
26
  end
28
27
 
29
28
  def parse(params)
@@ -37,8 +36,9 @@ module Interpol
37
36
 
38
37
  # Private: This takes care of the validation.
39
38
  class ParamValidator
40
- def initialize(endpoint_definition)
39
+ def initialize(endpoint_definition, configuration)
41
40
  @endpoint_definition = endpoint_definition
41
+ @configuration = configuration
42
42
  @params_schema = build_params_schema
43
43
  end
44
44
 
@@ -107,26 +107,19 @@ module Interpol
107
107
  ].none? { |params| params['additionalProperties'] }
108
108
  end
109
109
 
110
- STRING_EQUIVALENTS = {
111
- 'string' => nil,
112
- 'integer' => { 'type' => 'string', 'pattern' => '^\-?\d+$' },
113
- 'number' => { 'type' => 'string', 'pattern' => '^\-?\d+(\.\d+)?$' },
114
- 'boolean' => { 'type' => 'string', 'enum' => %w[ true false ] },
115
- 'null' => { 'type' => 'string', 'enum' => [''] }
116
- }
117
-
118
110
  def adjusted_schema(schema)
119
- types = Array(schema['type'])
120
-
121
- string_equivalents = types.map do |type|
122
- STRING_EQUIVALENTS.fetch(type) do
123
- unless type.is_a?(Hash) # a nested union type
124
- raise UnsupportedTypeError.new(type)
125
- end
111
+ adjusted_types = Array(schema['type']).inject([]) do |type_list, type|
112
+ type_string, options = if type.is_a?(Hash)
113
+ [type.fetch('type'), type]
114
+ else
115
+ [type, schema]
126
116
  end
127
- end.compact
128
117
 
129
- schema.merge('type' => (types + string_equivalents)).tap do |adjusted|
118
+ @configuration.param_parser_for(type_string, options).
119
+ type_validation_options_for([type] + type_list, options)
120
+ end
121
+
122
+ schema.merge('type' => adjusted_types).tap do |adjusted|
130
123
  adjusted['required'] = true unless adjusted['optional']
131
124
  end
132
125
  end
@@ -136,8 +129,9 @@ module Interpol
136
129
  class ParamConverter
137
130
  attr_reader :param_definitions
138
131
 
139
- def initialize(param_definitions)
132
+ def initialize(param_definitions, configuration)
140
133
  @param_definitions = param_definitions
134
+ @configuration = configuration
141
135
  end
142
136
 
143
137
  def convert(params)
@@ -156,10 +150,10 @@ module Interpol
156
150
  definition = param_definitions.fetch(name)
157
151
 
158
152
  Array(definition['type']).each do |type|
159
- converter = converter_for(type, definition)
153
+ parser = parser_for(type, definition)
160
154
 
161
155
  begin
162
- return converter.call(value)
156
+ return parser.parse_value(value)
163
157
  rescue ArgumentError => e
164
158
  # Try the next unioned type...
165
159
  end
@@ -168,96 +162,14 @@ module Interpol
168
162
  raise CannotBeParsedError, "The #{name} #{value.inspect} cannot be parsed"
169
163
  end
170
164
 
171
- BOOLEANS = { 'true' => true, true => true,
172
- 'false' => false, false => false }
173
- def self.convert_boolean(value)
174
- BOOLEANS.fetch(value) do
175
- raise ArgumentError, "#{value} is not convertable to a boolean"
176
- end
177
- end
178
-
179
- NULLS = { '' => nil, nil => nil }
180
- def self.convert_null(value)
181
- NULLS.fetch(value) do
182
- raise ArgumentError, "#{value} is not convertable to null"
183
- end
184
- end
185
-
186
- def self.convert_date(value)
187
- unless value =~ /\A\d{4}\-\d{2}\-\d{2}\z/
188
- raise ArgumentError, "Not in iso8601 format"
165
+ def parser_for(type, options)
166
+ if type.is_a?(Hash)
167
+ return parser_for(type.fetch('type'), type)
189
168
  end
190
169
 
191
- Date.new(*value.split('-').map(&:to_i))
192
- end
193
-
194
- def self.convert_uri(value)
195
- URI(value).tap do |uri|
196
- unless uri.scheme && uri.host
197
- raise ArgumentError, "Not a valid full URI"
198
- end
199
- end
200
- rescue URI::InvalidURIError => e
201
- raise ArgumentError, e.message, e.backtrace
202
- end
203
-
204
- CONVERTERS = {
205
- 'integer' => method(:Integer),
206
- 'number' => method(:Float),
207
- 'boolean' => method(:convert_boolean),
208
- 'null' => method(:convert_null)
209
- }
210
-
211
- IDENTITY_CONVERTER = lambda { |v| v }
212
-
213
- def converter_for(type, definition)
214
- CONVERTERS.fetch(type) do
215
- if Hash === type && type['type']
216
- converter_for(type['type'], type)
217
- elsif type == 'string'
218
- string_converter_for(definition)
219
- else
220
- raise CannotBeParsedError, "#{type} cannot be parsed"
221
- end
222
- end
223
- end
224
-
225
- STRING_CONVERTERS = {
226
- 'date' => method(:convert_date),
227
- 'date-time' => Time.method(:iso8601),
228
- 'uri' => method(:convert_uri)
229
- }
230
-
231
- def string_converter_for(definition)
232
- STRING_CONVERTERS.fetch(definition['format'], IDENTITY_CONVERTER)
170
+ @configuration.param_parser_for(type, options)
233
171
  end
234
172
  end
235
-
236
- # Raised when an unsupported parameter type is defined.
237
- class UnsupportedTypeError < ArgumentError
238
- attr_reader :type
239
-
240
- def initialize(type)
241
- @type = type
242
- super("#{type} params are not supported")
243
- end
244
- end
245
-
246
- # Raised when the path_params are not part of the endpoint route.
247
- class InvalidPathParamsError < ArgumentError
248
- attr_reader :invalid_params
249
-
250
- def initialize(*invalid_params)
251
- @invalid_params = invalid_params
252
- super("The path params #{invalid_params.join(', ')} are not in the route")
253
- end
254
- end
255
-
256
- # Raised when a parameter value cannot be parsed.
257
- CannotBeParsedError = Class.new(ArgumentError)
258
-
259
- # Raised when a params definition is invalid.
260
- InvalidParamsDefinitionError = Class.new(ArgumentError)
261
173
  end
262
174
  end
263
175
 
@@ -27,7 +27,13 @@ module Interpol
27
27
  # receive the app instance as an argument here.
28
28
  def validate_and_parse_params(app)
29
29
  return unless app.settings.parse_params?
30
- SingleRequestParamsParser.parse_params(config, app)
30
+ SingleRequestParamsParser.parse_params(config, app, endpoint_parsers)
31
+ end
32
+
33
+ def endpoint_parsers
34
+ @endpoint_parsers ||= Hash.new do |hash, endpoint|
35
+ hash[endpoint] = Interpol::RequestParamsParser.new(endpoint, @config)
36
+ end
31
37
  end
32
38
 
33
39
  private
@@ -57,17 +63,18 @@ module Interpol
57
63
 
58
64
  # Handles finding parsing request params for a single request.
59
65
  class SingleRequestParamsParser
60
- def self.parse_params(config, app)
61
- new(config, app).parse_params
66
+ def self.parse_params(config, app, endpoint_parsers)
67
+ new(config, app, endpoint_parsers).parse_params
62
68
  end
63
69
 
64
- def initialize(config, app)
70
+ def initialize(config, app, endpoint_parsers)
65
71
  @config = config
66
72
  @app = app
73
+ @endpoint_parsers = endpoint_parsers
67
74
  end
68
75
 
69
76
  def parse_params
70
- endpoint_definition.parse_request_params(params_to_parse)
77
+ @endpoint_parsers[endpoint_definition].parse(params_to_parse)
71
78
  rescue Interpol::ValidationError => error
72
79
  request_params_invalid(error)
73
80
  end
@@ -9,7 +9,7 @@ module Interpol
9
9
  config = Configuration.default.customized_duplicate(&block)
10
10
 
11
11
  each_definition_from(config.endpoints) do |endpoint, definition|
12
- define_definition_test(endpoint, definition)
12
+ define_definition_test(config, endpoint, definition)
13
13
 
14
14
  each_example_from(definition) do |example, example_index|
15
15
  define_example_test(config, endpoint, definition, example, example_index)
@@ -40,13 +40,13 @@ module Interpol
40
40
  define_test(description) { example.validate! }
41
41
  end
42
42
 
43
- def define_definition_test(endpoint, definition)
43
+ def define_definition_test(config, endpoint, definition)
44
44
  return unless definition.request?
45
45
 
46
46
  description = "#{endpoint.name} (v #{definition.version}) request " +
47
47
  "definition has valid params schema"
48
48
  define_test description do
49
- definition.request_params_parser # it will raise an error if it is invalid
49
+ RequestParamsParser.new(definition, config) # it will raise an error if it is invalid
50
50
  end
51
51
  end
52
52
 
@@ -1,3 +1,3 @@
1
1
  module Interpol
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
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.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-19 00:00:00.000000000 Z
12
+ date: 2012-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -199,9 +199,10 @@ files:
199
199
  - LICENSE
200
200
  - Gemfile
201
201
  - Rakefile
202
+ - lib/interpol/configuration/built_in_param_parsers.rb
203
+ - lib/interpol/configuration/default_callbacks.rb
202
204
  - lib/interpol/configuration.rb
203
205
  - lib/interpol/configuration_ruby_18_extensions.rb
204
- - lib/interpol/define_singleton_method.rb
205
206
  - lib/interpol/documentation.rb
206
207
  - lib/interpol/documentation_app/config.rb
207
208
  - lib/interpol/documentation_app.rb
@@ -209,6 +210,7 @@ files:
209
210
  - lib/interpol/each_with_object.rb
210
211
  - lib/interpol/endpoint.rb
211
212
  - lib/interpol/errors.rb
213
+ - lib/interpol/hash_set_default_proc_18.rb
212
214
  - lib/interpol/request_body_validator.rb
213
215
  - lib/interpol/request_params_parser.rb
214
216
  - lib/interpol/response_schema_validator.rb
@@ -1,10 +0,0 @@
1
- module Interpol
2
- # 1.9 has Object#define_singleton_method but 1.8 does not.
3
- # This provides 1.8 compatibility for the places we need it.
4
- module DefineSingletonMethod
5
- def define_singleton_method(name, &block)
6
- (class << self; self; end).send(:define_method, name, &block)
7
- end
8
- end
9
- end
10
-