deas 0.34.0 → 0.35.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/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