sinatra-param 0.1.1 → 0.1.2

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 (62) hide show
  1. data/Gemfile +9 -1
  2. data/Gemfile.lock +7 -1
  3. data/README.md +4 -9
  4. data/Rakefile +0 -1
  5. data/coverage/assets/0.7.1/application.css +1110 -0
  6. data/coverage/assets/0.7.1/application.js +626 -0
  7. data/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  8. data/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  9. data/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  10. data/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  11. data/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  12. data/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  13. data/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  14. data/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  15. data/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  16. data/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  17. data/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  18. data/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  19. data/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  20. data/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  21. data/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  22. data/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  23. data/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  24. data/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  25. data/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  26. data/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  27. data/coverage/assets/0.7.1/favicon_green.png +0 -0
  28. data/coverage/assets/0.7.1/favicon_red.png +0 -0
  29. data/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  30. data/coverage/assets/0.7.1/loading.gif +0 -0
  31. data/coverage/assets/0.7.1/magnify.png +0 -0
  32. data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  33. data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  34. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  35. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  36. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  37. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  38. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  39. data/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  40. data/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  41. data/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  42. data/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  43. data/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  44. data/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  45. data/coverage/index.html +788 -0
  46. data/{lib/example → example}/Gemfile +0 -0
  47. data/{lib/example → example}/Gemfile.lock +0 -0
  48. data/{lib/example → example}/Procfile +0 -0
  49. data/{lib/example → example}/app.rb +7 -7
  50. data/{lib/example → example}/config.ru +0 -0
  51. data/lib/sinatra/param.rb +36 -32
  52. data/lib/sinatra/param/version.rb +1 -1
  53. data/sinatra-param.gemspec +3 -6
  54. data/spec/dummy/app.rb +146 -0
  55. data/spec/parameter_sets_spec.rb +33 -0
  56. data/spec/parameter_transformations_spec.rb +21 -0
  57. data/spec/parameter_type_coercion_spec.rb +90 -0
  58. data/spec/parameter_validations_spec.rb +174 -0
  59. data/spec/spec_helper.rb +19 -2
  60. metadata +65 -39
  61. data/sinatra-param-0.1.0.gem +0 -0
  62. data/spec/exclude_spec.rb +0 -36
File without changes
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  require 'sinatra/base'
2
2
  require 'json'
3
3
 
4
- require_relative '../sinatra/param'
4
+ require_relative '../lib/sinatra/param'
5
5
 
6
6
  class App < Sinatra::Base
7
7
  helpers Sinatra::Param
@@ -9,32 +9,32 @@ class App < Sinatra::Base
9
9
  before do
10
10
  content_type :json
11
11
  end
12
-
12
+
13
13
  # GET /messages
14
14
  # GET /messages?sort=name&order=ASC
15
15
  get '/messages' do
16
16
  param :sort, String, default: "name"
17
17
  param :order, String, in: ["ASC", "DESC"], transform: :upcase, default: "ASC"
18
-
18
+
19
19
  {
20
20
  sort: params[:sort],
21
21
  order: params[:order]
22
22
  }.to_json
23
23
  end
24
-
24
+
25
25
  # GET /messages/1,2,3,4,5
26
26
  get '/messages/:ids' do
27
27
  param :ids, Array, required: true
28
-
28
+
29
29
  {
30
30
  ids: params[:ids]
31
31
  }.to_json
32
32
  end
33
-
33
+
34
34
  # POST /messages/1/response
35
35
  post '/messages/:id/response' do
36
36
  param :message, String, max: 1024, required: true
37
-
37
+
38
38
  {
39
39
  message: params[:message]
40
40
  }.to_json
File without changes
data/lib/sinatra/param.rb CHANGED
@@ -14,7 +14,7 @@ module Sinatra
14
14
  validate!(params[name], options)
15
15
  rescue
16
16
  error = "Invalid parameter, #{name}"
17
- if content_type && content_type.match(mime_type(:json))
17
+ if content_type and content_type.match(mime_type(:json))
18
18
  error = {message: error}.to_json
19
19
  end
20
20
 
@@ -23,14 +23,17 @@ module Sinatra
23
23
  end
24
24
 
25
25
  def one_of(*names)
26
- found = 0
26
+ count = 0
27
27
  names.each do |name|
28
- found += 1 if params[name] && present?(params[name])
29
- if found > 1
28
+ if params[name] and present?(params[name])
29
+ count += 1
30
+ next unless count > 1
31
+
30
32
  error = "Parameters #{names.join(', ')} are mutually exclusive"
31
- if content_type.match(mime_type(:json))
33
+ if content_type and content_type.match(mime_type(:json))
32
34
  error = {message: error}.to_json
33
35
  end
36
+
34
37
  halt 406, error
35
38
  end
36
39
  end
@@ -58,44 +61,45 @@ module Sinatra
58
61
  case key
59
62
  when :required
60
63
  raise InvalidParameterError if value && param.nil?
61
- when :blank
62
- raise InvalidParameterError if !value && case param
63
- when String
64
- !(/\S/ === param)
65
- when Array, Hash
66
- param.empty?
67
- else
68
- param.nil?
64
+ when :blank
65
+ raise InvalidParameterError if !value && case param
66
+ when String
67
+ !(/\S/ === param)
68
+ when Array, Hash
69
+ param.empty?
70
+ else
71
+ param.nil?
72
+ end
73
+ when :is
74
+ raise InvalidParameterError unless value === param
75
+ when :in, :within, :range
76
+ raise InvalidParameterError unless param.nil? || case value
77
+ when Range
78
+ value.include?(param)
79
+ else
80
+ Array(value).include?(param)
69
81
  end
70
- when :is
71
- raise InvalidParameterError unless value === param
72
- when :in, :within, :range
73
- raise InvalidParameterError unless param.nil? || case value
74
- when Range
75
- value.include?(param)
76
- else
77
- Array(value).include?(param)
78
- end
79
- when :min
80
- raise InvalidParameterError unless param.nil? || value <= param
81
- when :max
82
- raise InvalidParameterError unless param.nil? || value >= param
83
- when :min_length
84
- raise InvalidParameterError unless param.nil? || value <= param.length
85
- when :max_length
86
- raise InvalidParameterError unless param.nil? || value >= param.length
82
+ when :min
83
+ raise InvalidParameterError unless param.nil? || value <= param
84
+ when :max
85
+ raise InvalidParameterError unless param.nil? || value >= param
86
+ when :min_length
87
+ raise InvalidParameterError unless param.nil? || value <= param.length
88
+ when :max_length
89
+ raise InvalidParameterError unless param.nil? || value >= param.length
87
90
  end
88
91
  end
89
92
  end
90
-
93
+
91
94
  # ActiveSupport #present? and #blank? without patching Object
92
95
  def present?(object)
93
96
  !blank?(object)
94
97
  end
95
-
98
+
96
99
  def blank?(object)
97
100
  object.respond_to?(:empty?) ? object.empty? : !object
98
101
  end
99
102
  end
103
+
100
104
  helpers Param
101
105
  end
@@ -1,5 +1,5 @@
1
1
  module Sinatra
2
2
  module Param
3
- VERSION = "0.1.1"
3
+ VERSION = '0.1.2'
4
4
  end
5
5
  end
@@ -1,6 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "sinatra/param/version"
2
+ require File.expand_path('../lib/sinatra/param/version', __FILE__)
4
3
 
5
4
  Gem::Specification.new do |s|
6
5
  s.name = "sinatra-param"
@@ -11,12 +10,10 @@ Gem::Specification.new do |s|
11
10
  s.platform = Gem::Platform::RUBY
12
11
  s.summary = "sinatra-param"
13
12
  s.description = "Parameter Contracts for Sinatra"
14
-
13
+
15
14
  s.add_dependency "sinatra", "~> 1.3"
16
15
 
17
- s.add_development_dependency "rspec", "~> 2.10"
18
- s.add_development_dependency "rack-test"
19
- s.add_development_dependency "rake", "~> 0.9.2"
16
+ s.add_development_dependency 'simplecov'
20
17
 
21
18
  s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
22
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
data/spec/dummy/app.rb ADDED
@@ -0,0 +1,146 @@
1
+ require 'sinatra/base'
2
+ require 'json'
3
+ require 'time'
4
+
5
+ class App < Sinatra::Base
6
+ helpers Sinatra::Param
7
+
8
+ before do
9
+ content_type :json
10
+ end
11
+
12
+ get '/coerce/string' do
13
+ params[:arg] = params[:arg].to_i
14
+ param :arg, String
15
+ params.to_json
16
+ end
17
+
18
+ get '/coerce/integer' do
19
+ param :arg, Integer
20
+ params.to_json
21
+ end
22
+
23
+ get '/coerce/float' do
24
+ param :arg, Float
25
+ params.to_json
26
+ end
27
+
28
+ get '/coerce/time' do
29
+ param :arg, Time
30
+ params.to_json
31
+ end
32
+
33
+ get '/coerce/date' do
34
+ param :arg, Date
35
+ params.to_json
36
+ end
37
+
38
+ get '/coerce/datetime' do
39
+ param :arg, DateTime
40
+ params.to_json
41
+ end
42
+
43
+ get '/coerce/array' do
44
+ param :arg, Array
45
+ params.to_json
46
+ end
47
+
48
+ get '/coerce/hash' do
49
+ param :arg, Hash
50
+ params.to_json
51
+ end
52
+
53
+ get '/coerce/boolean' do
54
+ param :arg, :boolean
55
+ params.to_json
56
+ end
57
+
58
+ # transformations
59
+ get '/default' do
60
+ param :sort, String, default: "title"
61
+ params.to_json
62
+ end
63
+
64
+ get '/transform' do
65
+ param :order, String, transform: :upcase
66
+ params.to_json
67
+ end
68
+
69
+ # validations
70
+ get '/validation/required' do
71
+ param :arg, String, required: true
72
+ params.to_json
73
+ end
74
+
75
+ get '/validation/blank/string' do
76
+ param :arg, String, blank: false
77
+ end
78
+
79
+ get '/validation/blank/array' do
80
+ param :arg, Array, blank: false
81
+ end
82
+
83
+ get '/validation/blank/hash' do
84
+ param :arg, Hash, blank: false
85
+ end
86
+
87
+ get '/validation/blank/other' do
88
+ param :arg, Class, blank: false
89
+ end
90
+
91
+ get '/validation/nonblank/string' do
92
+ param :arg, String, blank: true
93
+ end
94
+
95
+ get '/validation/is' do
96
+ param :arg, String, is: 'foo'
97
+ params.to_json
98
+ end
99
+
100
+ get '/validation/in' do
101
+ param :arg, String, in: ['ASC', 'DESC']
102
+ params.to_json
103
+ end
104
+
105
+ get '/validation/within' do
106
+ param :arg, Integer, within: 1..10
107
+ params.to_json
108
+ end
109
+
110
+ get '/validation/range' do
111
+ param :arg, Integer, range: 1..10
112
+ params.to_json
113
+ end
114
+
115
+ get '/validation/min' do
116
+ param :arg, Integer, min: 12
117
+ params.to_json
118
+ end
119
+
120
+ get '/validation/max' do
121
+ param :arg, Integer, max: 20
122
+ params.to_json
123
+ end
124
+
125
+ get '/validation/min_length' do
126
+ param :arg, String, min_length: 5
127
+ params.to_json
128
+ end
129
+
130
+ get '/validation/max_length' do
131
+ param :arg, String, max_length: 10
132
+ params.to_json
133
+ end
134
+
135
+ get '/choice' do
136
+ param :a, String
137
+ param :b, String
138
+ param :c, String
139
+
140
+ one_of(:a, :b, :c)
141
+
142
+ {
143
+ message: 'OK'
144
+ }.to_json
145
+ end
146
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Parameter Sets' do
4
+ describe 'one_of' do
5
+ it 'returns 406 on requests that contain more than one mutually exclusive parameter' do
6
+ params = [
7
+ {a: 1, b: 2},
8
+ {b: 2, c: 3},
9
+ {a: 1, b: 2, c: 3}
10
+ ]
11
+ params.each do |param|
12
+ get('/choice', param) do |response|
13
+ response.status.should == 406
14
+ JSON.parse(response.body)['message'].should =~ /mutually exclusive/
15
+ end
16
+ end
17
+ end
18
+
19
+ it 'returns successfully for requests that only have one parameter' do
20
+ params = [
21
+ {a: 1},
22
+ {b: 2},
23
+ {c: 3}
24
+ ]
25
+ params.each do |param|
26
+ get('/choice', param) do |response|
27
+ response.status.should == 200
28
+ JSON.parse(response.body)['message'].should =~ /OK/
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Parameter Transformations' do
4
+ describe 'default' do
5
+ it 'sets a default value when none is given' do
6
+ get('/default') do |response|
7
+ response.status.should == 200
8
+ JSON.parse(response.body)['sort'].should == 'title'
9
+ end
10
+ end
11
+ end
12
+
13
+ describe 'transform' do
14
+ it 'transforms the input using to_proc' do
15
+ get('/transform', order: 'asc') do |response|
16
+ response.status.should == 200
17
+ JSON.parse(response.body)['order'].should == 'ASC'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Parameter Types' do
4
+ describe 'String' do
5
+ it 'coerces strings' do
6
+ get('/coerce/string', arg: '1234') do |response|
7
+ response.status.should == 200
8
+ JSON.parse(response.body)['arg'].should eq('1234')
9
+ end
10
+ end
11
+ end
12
+
13
+ describe 'Integer' do
14
+ it 'coerces integers' do
15
+ get('/coerce/integer', arg: '1234') do |response|
16
+ response.status.should == 200
17
+ JSON.parse(response.body)['arg'].should eq(1234)
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'Float' do
23
+ it 'coerces floats' do
24
+ get('/coerce/float', arg: '1234') do |response|
25
+ response.status.should == 200
26
+ JSON.parse(response.body)['arg'].should eq(1234.0)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'Time' do
32
+ it 'coerces time' do
33
+ get('/coerce/time', arg: '20130117') do |response|
34
+ response.status.should == 200
35
+ JSON.parse(response.body)['arg'].should eq('2013-01-17 00:00:00 -0500')
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'Date' do
41
+ it 'coerces date' do
42
+ get('/coerce/date', arg: '20130117') do |response|
43
+ response.status.should == 200
44
+ JSON.parse(response.body)['arg'].should eq('2013-01-17')
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'DateTime' do
50
+ it 'coerces datetimes' do
51
+ get('/coerce/datetime', arg: '20130117') do |response|
52
+ response.status.should == 200
53
+ JSON.parse(response.body)['arg'].should eq('2013-01-17T00:00:00+00:00')
54
+ end
55
+ end
56
+ end
57
+
58
+ describe 'Array' do
59
+ it 'coerces arrays' do
60
+ get('/coerce/array', arg: '1,2,3,4,5') do |response|
61
+ response.status.should == 200
62
+ parsed_body = JSON.parse(response.body)
63
+ parsed_body['arg'].should be_an(Array)
64
+ parsed_body['arg'].should eq(%w(1 2 3 4 5))
65
+ end
66
+ end
67
+ end
68
+
69
+ describe 'Hash' do
70
+ it 'coerces hashes' do
71
+ get('/coerce/hash', arg: 'a:b,c:d') do |response|
72
+ response.status.should == 200
73
+ parsed_body = JSON.parse(response.body)
74
+ parsed_body['arg'].should be_an(Hash)
75
+ parsed_body['arg'].should eq({ 'a' => 'b', 'c' => 'd'})
76
+ end
77
+ end
78
+ end
79
+
80
+ describe 'Boolean' do
81
+ it 'coerces truthy booleans to true' do
82
+ %w(1 true t yes y).each do |bool|
83
+ get('/coerce/boolean', arg: bool) do |response|
84
+ response.status.should == 200
85
+ JSON.parse(response.body)['arg'].should be_true
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end