deas 0.34.0 → 0.35.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/deas/router.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rack'
1
2
  require 'deas/exceptions'
2
3
  require 'deas/url'
3
4
 
@@ -8,11 +9,13 @@ module Deas
8
9
  DEFAULT_REQUEST_TYPE_NAME = 'default'
9
10
 
10
11
  attr_reader :request_types, :urls, :routes
12
+ attr_reader :escape_query_value_proc
11
13
 
12
14
  def initialize(&block)
13
15
  @request_types = []
14
16
  @urls, @routes = {}, []
15
17
  default_request_type_name(DEFAULT_REQUEST_TYPE_NAME)
18
+ escape_query_value{ |v| Rack::Utils.escape(v) }
16
19
  self.instance_eval(&block) if !block.nil?
17
20
  end
18
21
 
@@ -21,6 +24,11 @@ module Deas
21
24
  @view_handler_ns
22
25
  end
23
26
 
27
+ def escape_query_value(&block)
28
+ raise(ArgumentError, "no block given") unless block
29
+ @escape_query_value_proc = block
30
+ end
31
+
24
32
  def base_url(value = nil)
25
33
  @base_url = value if !value.nil?
26
34
  @base_url
@@ -30,12 +38,12 @@ module Deas
30
38
  "#{base_url}#{url_path}"
31
39
  end
32
40
 
33
- def url(name, path)
41
+ def url(name, path, options = nil)
34
42
  if !path.kind_of?(::String)
35
43
  raise ArgumentError, "invalid path `#{path.inspect}` - "\
36
44
  "can only provide a url name with String paths"
37
45
  end
38
- add_url(name.to_sym, path)
46
+ add_url(name.to_sym, path, options || {})
39
47
  end
40
48
 
41
49
  def url_for(name, *args)
@@ -101,8 +109,11 @@ module Deas
101
109
 
102
110
  private
103
111
 
104
- def add_url(name, path)
105
- self.urls[name] = Deas::Url.new(name, path)
112
+ def add_url(name, path, options)
113
+ options[:escape_query_value] ||= self.escape_query_value_proc
114
+ self.urls[name] = Deas::Url.new(name, path, {
115
+ :escape_query_value => options[:escape_query_value]
116
+ })
106
117
  end
107
118
 
108
119
  def add_route(http_method, path, proxies)
data/lib/deas/url.rb CHANGED
@@ -1,12 +1,20 @@
1
- require 'deas/cgi'
2
-
3
1
  module Deas
4
2
  class Url
5
3
 
4
+ def self.http_query(hash, &escape_value_proc)
5
+ escape_value_proc ||= proc{ |v| v.to_s }
6
+ hash.map do |(key, value)|
7
+ "#{key}=#{escape_value_proc.call(value)}"
8
+ end.sort.join('&')
9
+ end
10
+
6
11
  attr_reader :name, :path
12
+ attr_reader :escape_query_value_proc
7
13
 
8
- def initialize(name, path)
14
+ def initialize(name, path, options = nil)
15
+ options ||= {}
9
16
  @name, @path = name, path
17
+ @escape_query_value_proc = options[:escape_query_value]
10
18
  end
11
19
 
12
20
  def path_for(*args)
@@ -51,7 +59,9 @@ module Deas
51
59
  end
52
60
 
53
61
  def apply_extra(path, params)
54
- params.empty? ? path : "#{path}?#{Deas::Cgi.http_query(params)}"
62
+ return path if params.empty?
63
+ query_string = Deas::Url.http_query(params, &self.escape_query_value_proc)
64
+ "#{path}?#{query_string}"
55
65
  end
56
66
 
57
67
  def apply_anchor(path, anchor)
data/lib/deas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.34.0"
2
+ VERSION = "0.35.0"
3
3
  end
@@ -28,8 +28,10 @@ class Deas::Router
28
28
  subject{ @router }
29
29
 
30
30
  should have_readers :request_types, :urls, :routes
31
+ should have_readers :escape_query_value_proc
31
32
 
32
- should have_imeths :view_handler_ns, :base_url, :prepend_base_url
33
+ should have_imeths :view_handler_ns, :escape_query_value
34
+ should have_imeths :base_url, :prepend_base_url
33
35
  should have_imeths :url, :url_for
34
36
  should have_imeths :default_request_type_name, :add_request_type
35
37
  should have_imeths :request_type_name
@@ -45,6 +47,10 @@ class Deas::Router
45
47
 
46
48
  exp = @router_class::DEFAULT_REQUEST_TYPE_NAME
47
49
  assert_equal exp, subject.default_request_type_name
50
+
51
+ value = "#%&?"
52
+ exp = Rack::Utils.escape(value)
53
+ assert_equal exp, subject.escape_query_value_proc.call(value)
48
54
  end
49
55
 
50
56
  should "set a view handler namespace" do
@@ -52,6 +58,14 @@ class Deas::Router
52
58
  assert_equal exp, subject.view_handler_ns
53
59
  end
54
60
 
61
+ should "allow configuring a custom escape query value proc" do
62
+ escape_proc = proc{ Factory.string }
63
+ subject.escape_query_value(&escape_proc)
64
+ assert_equal escape_proc, subject.escape_query_value_proc
65
+
66
+ assert_raises(ArgumentError){ subject.escape_query_value }
67
+ end
68
+
55
69
  should "set a base url" do
56
70
  subject.base_url(exp = Factory.url)
57
71
  assert_equal exp, subject.base_url
@@ -228,6 +242,16 @@ class Deas::Router
228
242
  assert_kind_of Deas::Url, url
229
243
  assert_equal :get_info, url.name
230
244
  assert_equal '/info/:for', url.path
245
+ assert_equal subject.escape_query_value_proc, url.escape_query_value_proc
246
+ end
247
+
248
+ should "define a url with a custom escape query value proc" do
249
+ name = Factory.string
250
+ escape_proc = proc{ Factory.string }
251
+ @router.url(name, Factory.path, :escape_query_value => escape_proc)
252
+
253
+ url = subject.urls[name.to_sym]
254
+ assert_equal escape_proc, url.escape_query_value_proc
231
255
  end
232
256
 
233
257
  should "complain if defining a url with a non-string path" do
@@ -7,12 +7,36 @@ class Deas::Url
7
7
 
8
8
  class UnitTests < Assert::Context
9
9
  desc "Deas::Url"
10
+ setup do
11
+ @url_class = Deas::Url
12
+ end
13
+ subject{ @url_class }
14
+
15
+ should have_imeths :http_query
16
+
17
+ should "create http query strings" do
18
+ params = {
19
+ Factory.string => Factory.string,
20
+ Factory.integer => Factory.integer(3).times.map{ Factory.string },
21
+ Factory.string.to_sym => { Factory.string => Factory.string }
22
+ }
23
+ exp = params.map{ |(k, v)| "#{k}=#{v}" }.sort.join('&')
24
+ assert_equal exp, @url_class.http_query(params)
25
+
26
+ exp = params.map{ |(k, v)| "#{k}=#{v.inspect}" }.sort.join('&')
27
+ assert_equal exp, @url_class.http_query(params){ |v| v.inspect }
28
+ end
29
+
30
+ end
31
+
32
+ class InitTests < UnitTests
33
+ desc "when init"
10
34
  setup do
11
35
  @url = Deas::Url.new(:get_info, '/info')
12
36
  end
13
37
  subject{ @url }
14
38
 
15
- should have_readers :name, :path
39
+ should have_readers :name, :path, :escape_query_value_proc
16
40
  should have_imeth :path_for
17
41
 
18
42
  should "know its name and path info" do
@@ -20,12 +44,25 @@ class Deas::Url
20
44
  assert_equal '/info', subject.path
21
45
  end
22
46
 
47
+ should "know its escape query value proc" do
48
+ assert_nil subject.escape_query_value_proc
49
+
50
+ escape_proc = proc{ Factory.string }
51
+ url = Deas::Url.new(Factory.string, Factory.path, {
52
+ :escape_query_value => escape_proc
53
+ })
54
+ assert escape_proc, subject.escape_query_value_proc
55
+ end
56
+
23
57
  end
24
58
 
25
- class PathForTests < UnitTests
59
+ class PathForTests < InitTests
26
60
  desc "when generating paths"
27
61
  setup do
28
62
  @url = Deas::Url.new(:some_thing, '/:some/:thing/*/*')
63
+ @url_with_escape = Deas::Url.new(:some_thing, '/:some/:thing/*/*', {
64
+ :escape_query_value => proc{ |v| Rack::Utils.escape(v) }
65
+ })
29
66
  end
30
67
 
31
68
  should "generate given named params only" do
@@ -51,13 +88,31 @@ class Deas::Url
51
88
  end
52
89
 
53
90
  should "append other (additional) params as query params" do
54
- exp_path = "/a/goose/cooked/well?aye=a%20a%20a&bee=b"
91
+ exp_path = "/a/goose/cooked/well?aye=a&bee=b"
55
92
  assert_equal exp_path, subject.path_for({
56
93
  'some' => 'a',
57
94
  :thing => 'goose',
58
95
  'splat' => ['cooked', 'well'],
59
96
  'bee' => 'b',
60
- :aye => 'a a a'
97
+ :aye => 'a'
98
+ })
99
+ end
100
+
101
+ should "escape query values when built with an escape query value proc" do
102
+ exp_path = "/a/goose/cooked/well?aye=a?a&a"
103
+ assert_equal exp_path, subject.path_for({
104
+ 'some' => 'a',
105
+ :thing => 'goose',
106
+ 'splat' => ['cooked', 'well'],
107
+ :aye => 'a?a&a'
108
+ })
109
+
110
+ exp_path = "/a/goose/cooked/well?aye=a%3Fa%26a"
111
+ assert_equal exp_path, @url_with_escape.path_for({
112
+ 'some' => 'a',
113
+ :thing => 'goose',
114
+ 'splat' => ['cooked', 'well'],
115
+ :aye => 'a?a&a'
61
116
  })
62
117
  end
63
118
 
@@ -142,10 +197,10 @@ class Deas::Url
142
197
 
143
198
  should "not alter the given params" do
144
199
  params = {
145
- 'some' => 'thing',
200
+ 'some' => 'thing',
146
201
  :captures => 'captures',
147
- :splat => 'splat',
148
- '#' => 'anchor'
202
+ :splat => 'splat',
203
+ '#' => 'anchor'
149
204
  }
150
205
  exp_params = params.dup
151
206
 
metadata CHANGED
@@ -1,108 +1,123 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: deas
3
- version: !ruby/object:Gem::Version
4
- version: 0.34.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 147
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 35
9
+ - 0
10
+ version: 0.35.0
5
11
  platform: ruby
6
- authors:
12
+ authors:
7
13
  - Kelly Redding
8
14
  - Collin Redding
9
15
  autorequire:
10
16
  bindir: bin
11
17
  cert_chain: []
12
- date: 2015-06-07 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: ns-options
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.1'
18
+
19
+ date: 2015-06-24 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ hash: 13
28
+ segments:
29
+ - 1
30
+ - 1
31
+ version: "1.1"
21
32
  - - ">="
22
- - !ruby/object:Gem::Version
33
+ - !ruby/object:Gem::Version
34
+ hash: 27
35
+ segments:
36
+ - 1
37
+ - 1
38
+ - 4
23
39
  version: 1.1.4
24
40
  type: :runtime
41
+ name: ns-options
42
+ version_requirements: *id001
25
43
  prerelease: false
26
- version_requirements: !ruby/object:Gem::Requirement
27
- requirements:
28
- - - "~>"
29
- - !ruby/object:Gem::Version
30
- version: '1.1'
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.1.4
34
- - !ruby/object:Gem::Dependency
35
- name: rack
36
- requirement: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.5'
44
+ - !ruby/object:Gem::Dependency
45
+ requirement: &id002 !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ~>
49
+ - !ruby/object:Gem::Version
50
+ hash: 5
51
+ segments:
52
+ - 1
53
+ - 5
54
+ version: "1.5"
41
55
  type: :runtime
56
+ name: rack
57
+ version_requirements: *id002
42
58
  prerelease: false
43
- version_requirements: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.5'
48
- - !ruby/object:Gem::Dependency
49
- name: sinatra
50
- requirement: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.4'
59
+ - !ruby/object:Gem::Dependency
60
+ requirement: &id003 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ hash: 7
66
+ segments:
67
+ - 1
68
+ - 4
69
+ version: "1.4"
55
70
  type: :runtime
71
+ name: sinatra
72
+ version_requirements: *id003
56
73
  prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- - !ruby/object:Gem::Dependency
63
- name: assert
64
- requirement: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.12'
74
+ - !ruby/object:Gem::Dependency
75
+ requirement: &id004 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ hash: 27
81
+ segments:
82
+ - 2
83
+ - 12
84
+ version: "2.12"
69
85
  type: :development
86
+ name: assert
87
+ version_requirements: *id004
70
88
  prerelease: false
71
- version_requirements: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '2.12'
76
- - !ruby/object:Gem::Dependency
77
- name: assert-rack-test
78
- requirement: !ruby/object:Gem::Requirement
79
- requirements:
89
+ - !ruby/object:Gem::Dependency
90
+ requirement: &id005 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
80
93
  - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
83
99
  type: :development
100
+ name: assert-rack-test
101
+ version_requirements: *id005
84
102
  prerelease: false
85
- version_requirements: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
103
  description: Handler-based web framework powered by Sinatra
91
- email:
104
+ email:
92
105
  - kelly@kellyredding.com
93
106
  - collin.redding@me.com
94
107
  executables: []
108
+
95
109
  extensions: []
110
+
96
111
  extra_rdoc_files: []
97
- files:
98
- - ".gitignore"
112
+
113
+ files:
114
+ - .gitignore
99
115
  - Gemfile
100
116
  - LICENSE.txt
101
117
  - README.md
102
118
  - Rakefile
103
119
  - deas.gemspec
104
120
  - lib/deas.rb
105
- - lib/deas/cgi.rb
106
121
  - lib/deas/deas_runner.rb
107
122
  - lib/deas/error_handler.rb
108
123
  - lib/deas/exceptions.rb
@@ -139,7 +154,6 @@ files:
139
154
  - test/support/test_template.test
140
155
  - test/support/view_handlers.rb
141
156
  - test/system/rack_tests.rb
142
- - test/unit/cgi_tests.rb
143
157
  - test/unit/deas_runner_tests.rb
144
158
  - test/unit/error_handler_tests.rb
145
159
  - test/unit/exceptions_tests.rb
@@ -163,30 +177,39 @@ files:
163
177
  - test/unit/view_handler_tests.rb
164
178
  - tmp/.gitkeep
165
179
  homepage: http://github.com/redding/deas
166
- licenses:
180
+ licenses:
167
181
  - MIT
168
- metadata: {}
169
182
  post_install_message:
170
183
  rdoc_options: []
171
- require_paths:
184
+
185
+ require_paths:
172
186
  - lib
173
- required_ruby_version: !ruby/object:Gem::Requirement
174
- requirements:
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
175
190
  - - ">="
176
- - !ruby/object:Gem::Version
177
- version: '0'
178
- required_rubygems_version: !ruby/object:Gem::Requirement
179
- requirements:
191
+ - !ruby/object:Gem::Version
192
+ hash: 3
193
+ segments:
194
+ - 0
195
+ version: "0"
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ none: false
198
+ requirements:
180
199
  - - ">="
181
- - !ruby/object:Gem::Version
182
- version: '0'
200
+ - !ruby/object:Gem::Version
201
+ hash: 3
202
+ segments:
203
+ - 0
204
+ version: "0"
183
205
  requirements: []
206
+
184
207
  rubyforge_project:
185
- rubygems_version: 2.4.5
208
+ rubygems_version: 1.8.25
186
209
  signing_key:
187
- specification_version: 4
210
+ specification_version: 3
188
211
  summary: Handler-based web framework powered by Sinatra
189
- test_files:
212
+ test_files:
190
213
  - test/helper.rb
191
214
  - test/support/factory.rb
192
215
  - test/support/fake_sinatra_call.rb
@@ -199,7 +222,6 @@ test_files:
199
222
  - test/support/test_template.test
200
223
  - test/support/view_handlers.rb
201
224
  - test/system/rack_tests.rb
202
- - test/unit/cgi_tests.rb
203
225
  - test/unit/deas_runner_tests.rb
204
226
  - test/unit/error_handler_tests.rb
205
227
  - test/unit/exceptions_tests.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: cfa612b3fc472e3c8a14005ca567c2a20b901476
4
- data.tar.gz: c6e19d87a4393a780da387f19a5698100ab80296
5
- SHA512:
6
- metadata.gz: 99c27beacb566a4f0361aadfd85c4d504c2bf11d0ed09112082f35ea115c37df3d69273da9482b27a9d0e50d6ef4eed1b2e3b1f8431eec5d50ffb053eb1e5622
7
- data.tar.gz: 602b81f39fa49f1d92b244450248e7efc7515e06317c51b2ba951172ee9f67c29b4feb4ec7d14a30483bd0b5bfd6a68b03833848df85b6a5bbac7697fe65d409
data/lib/deas/cgi.rb DELETED
@@ -1,31 +0,0 @@
1
- module Deas
2
-
3
- module Cgi
4
- # taken from http://ruby-doc.org/stdlib/libdoc/cgi/rdoc/index.html
5
- # => not requiring 'cgi' to save on memory usage
6
-
7
- def self.escape(string)
8
- string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
9
- '%' + $1.unpack('H2' * $1.size).join('%').upcase
10
- end.gsub(' ', '%20')
11
- end
12
-
13
- def self.http_query(value, key_ns = nil)
14
- # optimized version taken from:
15
- # http://github.com/kelredd/useful/blob/master/lib/useful/ruby_extensions/hash.rb
16
- value.sort{|a,b| a[0].to_s <=> b[0].to_s}.collect do |key_val|
17
- key, val = key_val
18
- key_s = key_ns ? "#{key_ns}[#{key_val[0].to_s}]" : key_val[0].to_s
19
- if key_val[1].kind_of?(::Array)
20
- key_val[1].sort.collect{|i| "#{key_s}[]=#{Deas::Cgi.escape(i.to_s)}"}.join('&')
21
- elsif key_val[1].kind_of?(::Hash)
22
- Deas::Cgi.http_query(key_val[1], key_s)
23
- else
24
- "#{key_s}=#{Deas::Cgi.escape(key_val[1].to_s)}"
25
- end
26
- end.join('&')
27
- end
28
-
29
- end
30
-
31
- end
@@ -1,36 +0,0 @@
1
- require 'assert'
2
- require 'deas/cgi'
3
-
4
- module Deas::Cgi
5
-
6
- class UnitTests < Assert::Context
7
- desc "Deas::Cgi"
8
- subject{ Deas::Cgi }
9
-
10
- should have_imeths :escape, :http_query
11
-
12
- should "cgi-escape data values" do
13
- exp = "Right%21%20%5BSaid%5D%20Fred.%0D%0A"
14
- assert_equal exp, Deas::Cgi.escape("Right! [Said] Fred.\r\n")
15
- end
16
-
17
- should "create http query strings" do
18
- exp = "name=thomas%20hardy%20%2F%20thomas%20handy"
19
- assert_equal exp, Deas::Cgi.http_query(:name => 'thomas hardy / thomas handy')
20
-
21
- exp = "id=23423&since=2009-10-14"
22
- assert_equal exp, Deas::Cgi.http_query(:id => 23423, :since => "2009-10-14")
23
-
24
- exp = "id[]=1&id[]=2"
25
- assert_equal exp, Deas::Cgi.http_query(:id => [1,2])
26
-
27
- exp = "poo[bar]=2&poo[foo]=1"
28
- assert_equal exp, Deas::Cgi.http_query(:poo => {:foo => 1, :bar => 2})
29
-
30
- exp = "poo[bar][bar1]=1&poo[bar][bar2]=nasty&poo[foo]=1"
31
- assert_equal exp, Deas::Cgi.http_query(:poo => {:foo => 1, :bar => {:bar1 => 1, :bar2 => "nasty"}})
32
- end
33
-
34
- end
35
-
36
- end