waves 0.8.2 → 0.9.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/bin/waves +4 -3
- data/doc/VERSION +1 -1
- data/lib/waves.rb +52 -40
- data/lib/{caches → waves/caches}/file.rb +3 -1
- data/lib/waves/caches/memcached.rb +56 -0
- data/lib/{caches → waves/caches}/simple.rb +6 -7
- data/lib/{caches → waves/caches}/synchronized.rb +15 -1
- data/lib/{commands → waves/commands}/console.rb +4 -4
- data/lib/{commands → waves/commands}/generate.rb +6 -5
- data/lib/{commands → waves/commands}/help.rb +0 -0
- data/lib/{commands → waves/commands}/server.rb +1 -1
- data/lib/{dispatchers → waves/dispatchers}/base.rb +17 -31
- data/lib/waves/dispatchers/default.rb +19 -0
- data/lib/{ext → waves/ext}/float.rb +0 -0
- data/lib/{ext → waves/ext}/hash.rb +0 -0
- data/lib/{ext → waves/ext}/integer.rb +16 -1
- data/lib/{ext → waves/ext}/kernel.rb +3 -7
- data/lib/{ext → waves/ext}/module.rb +3 -3
- data/lib/{ext → waves/ext}/object.rb +2 -0
- data/lib/waves/ext/string.rb +73 -0
- data/lib/{ext → waves/ext}/symbol.rb +0 -1
- data/lib/{ext → waves/ext}/tempfile.rb +0 -0
- data/lib/waves/ext/time.rb +5 -0
- data/lib/{foundations → waves/foundations}/classic.rb +9 -21
- data/lib/{foundations → waves/foundations}/compact.rb +15 -20
- data/lib/waves/foundations/rest.rb +311 -0
- data/lib/waves/helpers/basic.rb +13 -0
- data/lib/{helpers → waves/helpers}/doc_type.rb +3 -0
- data/lib/waves/helpers/form.rb +94 -0
- data/lib/waves/helpers/formatting.rb +14 -0
- data/lib/waves/layers/mvc.rb +65 -0
- data/lib/{layers → waves/layers}/mvc/controllers.rb +0 -0
- data/lib/{layers → waves/layers}/mvc/extensions.rb +23 -11
- data/lib/{layers → waves/layers}/orm/migration.rb +0 -0
- data/lib/{layers → waves/layers}/orm/providers/active_record.rb +2 -5
- data/lib/{layers → waves/layers}/orm/providers/active_record/migrations/empty.rb.erb +0 -0
- data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/generate.rb +1 -1
- data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/schema.rb +1 -1
- data/lib/{layers → waves/layers}/orm/providers/data_mapper.rb +0 -0
- data/lib/{layers → waves/layers}/orm/providers/filebase.rb +0 -0
- data/lib/{layers → waves/layers}/orm/providers/sequel.rb +28 -29
- data/lib/{layers → waves/layers}/orm/providers/sequel/migrations/empty.rb.erb +0 -0
- data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/generate.rb +1 -1
- data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/schema.rb +2 -0
- data/lib/waves/layers/rack/rack_cache.rb +32 -0
- data/lib/waves/layers/renderers/erubis.rb +52 -0
- data/lib/waves/layers/renderers/haml.rb +67 -0
- data/lib/waves/layers/renderers/markaby.rb +41 -0
- data/lib/waves/layers/text/inflect/english.rb +42 -0
- data/lib/waves/matchers/accept.rb +47 -0
- data/lib/waves/matchers/ext.rb +27 -0
- data/lib/waves/matchers/path.rb +72 -0
- data/lib/waves/matchers/query.rb +43 -0
- data/lib/waves/matchers/request.rb +86 -0
- data/lib/waves/matchers/requested.rb +31 -0
- data/lib/{matchers → waves/matchers}/resource.rb +8 -1
- data/lib/waves/matchers/traits.rb +30 -0
- data/lib/waves/matchers/uri.rb +69 -0
- data/lib/waves/media/mime_types.rb +542 -0
- data/lib/waves/renderers/mixin.rb +9 -0
- data/lib/waves/request/accept.rb +92 -0
- data/lib/{runtime → waves/request}/request.rb +77 -61
- data/lib/waves/resources/file_mixin.rb +11 -0
- data/lib/{resources → waves/resources}/mixin.rb +42 -44
- data/lib/waves/resources/paths.rb +132 -0
- data/lib/waves/response/client_errors.rb +10 -0
- data/lib/waves/response/packaged.rb +19 -0
- data/lib/waves/response/redirects.rb +35 -0
- data/lib/{runtime → waves/response}/response.rb +29 -11
- data/lib/{runtime → waves/response}/response_mixin.rb +30 -17
- data/lib/waves/runtime/applications.rb +18 -0
- data/lib/{runtime → waves/runtime}/configuration.rb +31 -25
- data/lib/waves/runtime/console.rb +24 -0
- data/lib/{runtime → waves/runtime}/logger.rb +3 -3
- data/lib/{runtime → waves/runtime}/mocks.rb +2 -2
- data/lib/waves/runtime/rackup.rb +37 -0
- data/lib/waves/runtime/runtime.rb +48 -0
- data/lib/waves/runtime/server.rb +33 -0
- data/lib/{servers → waves/servers}/base.rb +0 -0
- data/lib/{servers → waves/servers}/mongrel.rb +0 -0
- data/lib/{servers → waves/servers}/webrick.rb +0 -0
- data/lib/{tasks → waves/tasks}/gem.rb +0 -0
- data/lib/{tasks → waves/tasks}/generate.rb +0 -0
- data/lib/waves/views/cassy.rb +173 -0
- data/lib/{views → waves/views}/errors.rb +8 -7
- data/lib/waves/views/mixin.rb +23 -0
- data/lib/waves/views/templated.rb +40 -0
- data/samples/basic/basic_startup.rb +70 -0
- data/samples/basic/config.ru +9 -0
- data/samples/blog/configurations/development.rb +17 -16
- data/samples/blog/configurations/production.rb +0 -11
- data/samples/blog/resources/entry.rb +3 -3
- data/samples/blog/resources/map.rb +10 -3
- data/samples/blog/startup.rb +4 -3
- data/templates/classic/Rakefile +28 -29
- data/templates/classic/configurations/default.rb.erb +8 -3
- data/templates/classic/configurations/development.rb.erb +1 -20
- data/templates/classic/configurations/production.rb.erb +2 -16
- data/templates/classic/public/images/favicon.ico +0 -0
- data/templates/classic/resources/server.rb.erb +9 -0
- data/templates/classic/startup.rb.erb +3 -3
- data/templates/classic/views/css.rb.erb +14 -0
- data/templates/classic/views/default.rb.erb +17 -0
- data/templates/classic/views/errors.rb.erb +10 -0
- data/templates/classic/views/pages.rb.erb +14 -0
- data/templates/compact/startup.rb.erb +8 -3
- data/test/ext/object.rb +55 -0
- data/test/ext/shortcuts.rb +73 -0
- data/test/helpers.rb +17 -0
- data/test/match/accept.rb +78 -0
- data/test/match/ext.rb +156 -0
- data/test/match/methods.rb +22 -0
- data/test/match/params.rb +33 -0
- data/test/match/path.rb +106 -0
- data/test/match/query.rb +60 -0
- data/test/match/request.rb +91 -0
- data/test/match/requested.rb +149 -0
- data/test/match/uri.rb +136 -0
- data/test/process/request.rb +75 -0
- data/test/process/resource.rb +53 -0
- data/test/resources/path.rb +166 -0
- data/test/runtime/configurations.rb +19 -0
- data/test/runtime/request.rb +63 -0
- data/test/runtime/response.rb +85 -0
- data/test/views/views.rb +40 -0
- metadata +243 -157
- data/lib/caches/memcached.rb +0 -40
- data/lib/dispatchers/default.rb +0 -25
- data/lib/ext/string.rb +0 -20
- data/lib/helpers/basic.rb +0 -11
- data/lib/helpers/extended.rb +0 -21
- data/lib/helpers/form.rb +0 -42
- data/lib/helpers/formatting.rb +0 -30
- data/lib/helpers/layouts.rb +0 -37
- data/lib/helpers/model.rb +0 -37
- data/lib/helpers/view.rb +0 -22
- data/lib/layers/inflect/english.rb +0 -67
- data/lib/layers/mvc.rb +0 -54
- data/lib/layers/renderers/erubis.rb +0 -60
- data/lib/layers/renderers/haml.rb +0 -47
- data/lib/layers/renderers/markaby.rb +0 -29
- data/lib/matchers/accept.rb +0 -21
- data/lib/matchers/base.rb +0 -30
- data/lib/matchers/content_type.rb +0 -17
- data/lib/matchers/path.rb +0 -67
- data/lib/matchers/query.rb +0 -21
- data/lib/matchers/request.rb +0 -27
- data/lib/matchers/traits.rb +0 -19
- data/lib/matchers/uri.rb +0 -20
- data/lib/renderers/mixin.rb +0 -36
- data/lib/resources/paths.rb +0 -34
- data/lib/runtime/console.rb +0 -23
- data/lib/runtime/mime_types.rb +0 -536
- data/lib/runtime/monitor.rb +0 -32
- data/lib/runtime/runtime.rb +0 -67
- data/lib/runtime/server.rb +0 -20
- data/lib/runtime/session.rb +0 -27
- data/lib/runtime/worker.rb +0 -86
- data/lib/views/mixin.rb +0 -62
- data/samples/blog/blog.db +0 -0
- data/samples/blog/log/waves.production +0 -3
- data/templates/classic/resources/map.rb.erb +0 -8
- data/templates/classic/templates/errors/not_found_404.mab +0 -7
- data/templates/classic/templates/errors/server_error_500.mab +0 -7
- data/templates/classic/templates/layouts/default.mab +0 -14
- data/templates/classic/tmp/sessions/.gitignore +0 -0
data/test/helpers.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rubygems'; %w{ bacon facon }.each { |dep| require dep }
|
|
2
|
+
|
|
3
|
+
# Framework lib goes to the front of the loadpath
|
|
4
|
+
$:.unshift('lib')
|
|
5
|
+
require 'waves'
|
|
6
|
+
require 'waves/runtime/mocks'
|
|
7
|
+
|
|
8
|
+
Waves::Runtime.instance = Waves::Runtime.new
|
|
9
|
+
|
|
10
|
+
Bacon::Context.module_eval do
|
|
11
|
+
include Waves::Mocks
|
|
12
|
+
alias_method :specification, :describe
|
|
13
|
+
alias_method :feature, :it
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Bacon.extend Bacon::TestUnitOutput
|
|
17
|
+
Bacon.summary_on_exit
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../test/helpers.rb"
|
|
2
|
+
require 'test/helpers.rb'
|
|
3
|
+
|
|
4
|
+
require 'waves/foundations/compact'
|
|
5
|
+
require "waves/runtime/mime_types"
|
|
6
|
+
|
|
7
|
+
describe "Accept header matching" do
|
|
8
|
+
|
|
9
|
+
Accept = Waves::Accept
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
13
|
+
Waves << Test
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after do
|
|
17
|
+
Waves.applications.clear
|
|
18
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
feature "matches correct accept header" do
|
|
22
|
+
|
|
23
|
+
Test::Resources::Map.on( :get, [ "foo" ], :accept => "text/javascript" ) { }
|
|
24
|
+
|
|
25
|
+
resp = get "/foo"
|
|
26
|
+
resp.status.should == 404
|
|
27
|
+
|
|
28
|
+
resp = get "/foo", "HTTP_ACCEPT" => "text/javascript"
|
|
29
|
+
resp.status.should == 200
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
feature 'Accept header is being parsed parses in the right way.' do
|
|
34
|
+
accept_header = "text/*, text/html ;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5"
|
|
35
|
+
terms = Accept.parse(accept_header)
|
|
36
|
+
terms.size.should == 6
|
|
37
|
+
terms.map{|term,params| term }.uniq[0] == %w( text html )
|
|
38
|
+
|
|
39
|
+
accept_header = "text/html,application/xhtml+xml;q=0.95,application/xml;q=0.9,*/*;q=0.8"
|
|
40
|
+
terms = Accept.parse(accept_header)
|
|
41
|
+
terms.size.should == 4
|
|
42
|
+
terms[0][0].should == %w( text html )
|
|
43
|
+
terms[1][0].should == %w( application xhtml+xml )
|
|
44
|
+
terms[2][0].should == %w( application xml )
|
|
45
|
+
terms[3][0].should == [ true, true ]
|
|
46
|
+
|
|
47
|
+
accept_header = "text/css,*/*;q=0.1"
|
|
48
|
+
terms = Accept.parse(accept_header)
|
|
49
|
+
terms.size.should == 2
|
|
50
|
+
terms[0][0].should == %w( text css )
|
|
51
|
+
terms[1][0].should == [ true, true ]
|
|
52
|
+
|
|
53
|
+
accept_header = "image/png,image/*;q=0.8,*/*;q=0.5"
|
|
54
|
+
terms = Accept.parse(accept_header)
|
|
55
|
+
terms.size.should == 3
|
|
56
|
+
terms[0][0].should == %w( image png )
|
|
57
|
+
terms[1][0].should == [ 'image', true ]
|
|
58
|
+
terms[2][0].should == [ true, true ]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
feature 'Should return all the terms in a Accept-Charset header' do
|
|
62
|
+
accept_charset_header = "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
|
|
63
|
+
terms = Accept.parse( accept_charset_header )
|
|
64
|
+
terms.size.should == 3
|
|
65
|
+
terms[0][0].should == [ 'ISO-8859-1' ]
|
|
66
|
+
terms[1][0].should == [ 'utf-8' ]
|
|
67
|
+
terms[2][0].should == [ true ]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
feature 'Should return all the terms in a Accept-Language header' do
|
|
71
|
+
accept_language_header = "en-us,en;q=0.5"
|
|
72
|
+
terms = Accept.parse(accept_language_header)
|
|
73
|
+
terms.size.should == 2
|
|
74
|
+
terms[0][0][0] == 'en-us'
|
|
75
|
+
terms[1][0][0] == 'en'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
data/test/match/ext.rb
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require 'test/helpers.rb'
|
|
2
|
+
|
|
3
|
+
require 'waves/foundations/compact'
|
|
4
|
+
require "waves/runtime/mime_types"
|
|
5
|
+
require "waves/matchers/ext"
|
|
6
|
+
|
|
7
|
+
describe "File extension matching" do
|
|
8
|
+
before do
|
|
9
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
10
|
+
Waves << Test
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after do
|
|
14
|
+
Waves.applications.clear
|
|
15
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
feature "returns falseish if single file extension Symbol is not matched" do
|
|
19
|
+
m = Waves::Matchers::Ext.new :js
|
|
20
|
+
|
|
21
|
+
request = Waves::Request.new env("http://example.com/moo",
|
|
22
|
+
:method => "GET",
|
|
23
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
24
|
+
|
|
25
|
+
(!!m.call(request)).should == false
|
|
26
|
+
|
|
27
|
+
request = Waves::Request.new env("http://example.com/moo.sj",
|
|
28
|
+
:method => "GET",
|
|
29
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
30
|
+
|
|
31
|
+
(!!m.call(request)).should == false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
feature "returns falseish if none of Array of Symbol extensions match" do
|
|
35
|
+
m = Waves::Matchers::Ext.new [:js, :html]
|
|
36
|
+
|
|
37
|
+
request = Waves::Request.new env("http://example.com/moo",
|
|
38
|
+
:method => "GET",
|
|
39
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
40
|
+
|
|
41
|
+
(!!m.call(request)).should == false
|
|
42
|
+
|
|
43
|
+
request = Waves::Request.new env("http://example.com/moo.sj",
|
|
44
|
+
:method => "GET",
|
|
45
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
46
|
+
|
|
47
|
+
(!!m.call(request)).should == false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
feature "returns trueish if single file extension Symbol does match" do
|
|
51
|
+
m = Waves::Matchers::Ext.new :js
|
|
52
|
+
|
|
53
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
54
|
+
:method => "GET",
|
|
55
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
56
|
+
|
|
57
|
+
m.call(request).should == true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
feature "returns trueish if any in Array of Symbol extensions match" do
|
|
61
|
+
m = Waves::Matchers::Ext.new [:js, :html]
|
|
62
|
+
|
|
63
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
64
|
+
:method => "GET",
|
|
65
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
66
|
+
|
|
67
|
+
(!!m.call(request)).should == true
|
|
68
|
+
|
|
69
|
+
request = Waves::Request.new env("http://example.com/moo.html",
|
|
70
|
+
:method => "GET",
|
|
71
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
72
|
+
|
|
73
|
+
(!!m.call(request)).should == true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
feature "fails to match a Symbol extension with a leading dot included" do
|
|
77
|
+
m = Waves::Matchers::Ext.new :".js"
|
|
78
|
+
|
|
79
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
80
|
+
:method => "GET",
|
|
81
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
82
|
+
|
|
83
|
+
(!!m.call(request)).should == false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
feature "matches absence of extension, returning true, if Array contains false" do
|
|
87
|
+
m = Waves::Matchers::Ext.new [ :js, :html, false ]
|
|
88
|
+
|
|
89
|
+
request = Waves::Request.new env("http://example.com/moo",
|
|
90
|
+
:method => "GET",
|
|
91
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
92
|
+
|
|
93
|
+
(!!m.call(request)).should == true
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
feature "fails to match if extension provided but no extension specified with empty String" do
|
|
97
|
+
m = Waves::Matchers::Ext.new( false )
|
|
98
|
+
|
|
99
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
100
|
+
:method => "GET",
|
|
101
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
102
|
+
|
|
103
|
+
(!!m.call(request)).should == false
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe "File extension matching in conjunction with Accept matching" do
|
|
109
|
+
before do
|
|
110
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
111
|
+
Waves << Test
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
after do
|
|
115
|
+
Waves.applications.clear
|
|
116
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
feature "fails if the Accept match fails" do
|
|
120
|
+
m = Waves::Matchers::Request.new :requested => ["text/html"],
|
|
121
|
+
:ext => :js
|
|
122
|
+
|
|
123
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
124
|
+
:method => "GET",
|
|
125
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
126
|
+
|
|
127
|
+
(!!m.call(request)).should == false
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
feature "matches if the extension is Accept-matched with or without Accept header" do
|
|
131
|
+
m = Waves::Matchers::Request.new :requested => ["text/javascript"],
|
|
132
|
+
:ext => :js
|
|
133
|
+
|
|
134
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
135
|
+
:method => "GET",
|
|
136
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
137
|
+
|
|
138
|
+
(!!m.call(request)).should == true
|
|
139
|
+
|
|
140
|
+
request = Waves::Request.new env("http://example.com/moo.js", :method => "GET")
|
|
141
|
+
|
|
142
|
+
(!!m.call(request)).should == true
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
feature "causes Accept match to fail if there is a file extension, and absence is specified" do
|
|
146
|
+
m = Waves::Matchers::Request.new :requested => ["text/javascript"],
|
|
147
|
+
:ext => false
|
|
148
|
+
|
|
149
|
+
request = Waves::Request.new env("http://example.com/moo.js",
|
|
150
|
+
:method => "GET",
|
|
151
|
+
"HTTP_ACCEPT" => "text/javascript")
|
|
152
|
+
(!!m.call(request)).should == false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../test/helpers.rb"
|
|
2
|
+
require 'waves/foundations/compact'
|
|
3
|
+
|
|
4
|
+
describe "Matching Request Methods" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
8
|
+
Test::Resources::Map.module_eval {
|
|
9
|
+
%w( get put post delete head ).each { |m| on( m ) { m } } }
|
|
10
|
+
Waves << Test
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after do
|
|
14
|
+
Waves.applications.clear
|
|
15
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
%w( get put post delete head ).each do |m|
|
|
19
|
+
feature( "Match the '#{m}' method" ) { send( m, '/' ).body.should == m }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../test/helpers.rb"
|
|
2
|
+
require 'waves/foundations/compact'
|
|
3
|
+
|
|
4
|
+
describe "A resource that has matched a request" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
8
|
+
Waves << Test
|
|
9
|
+
|
|
10
|
+
@request = Waves::Request.new( env('http://localhost/baz?bar=7', :method => 'GET', "HTTP_ACCEPT" => "text/html" ) )
|
|
11
|
+
Test::Resources::Map.on(:get, [:foo], :accept => "text/html") { }
|
|
12
|
+
@resource = Test::Resources::Map.new( @request )
|
|
13
|
+
@resource.get
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after do
|
|
17
|
+
Waves.applications.clear
|
|
18
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "makes parameters captured from the path available as #captured" do
|
|
22
|
+
@resource.captured.to_h.should == { 'foo' => 'baz' }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "makes http query parameters available as #query" do
|
|
26
|
+
@resource.query.to_h.should == { 'bar' => '7' }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "provides access to all derived parameters using #params" do
|
|
30
|
+
@resource.params.to_h.should == { 'foo' => 'baz', 'bar' => '7' }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
data/test/match/path.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../test/helpers.rb"
|
|
2
|
+
require 'waves/foundations/compact'
|
|
3
|
+
|
|
4
|
+
describe "Matching Request URIs" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
8
|
+
Waves << Test
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
after do
|
|
12
|
+
Waves.applications.clear
|
|
13
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
feature "By default, we match an arbitrary path." do
|
|
17
|
+
Test::Resources::Map.on( :get ) {}
|
|
18
|
+
get("/foobar").status.should == 200
|
|
19
|
+
get("/foo/bar").status.should == 200
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
feature "A path of true matches an arbitrary path." do
|
|
23
|
+
Test::Resources::Map.on( :get, true ) { request.path }
|
|
24
|
+
get("/foobar").body.should == '/foobar'
|
|
25
|
+
get("/foo/bar").body.should == '/foo/bar'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
feature "An empty path matches root." do
|
|
29
|
+
Test::Resources::Map.on( :get, [] ) { request.path }
|
|
30
|
+
get("/").body.should == '/'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
feature "A string path component matches that string." do
|
|
34
|
+
Test::Resources::Map.on( :get, [ 'foo' ] ) { request.path }
|
|
35
|
+
get("/foo").body.should == '/foo'
|
|
36
|
+
get("/bar").status.should == 404
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
feature "A symbol path component captures that component using the symbol as a key." do
|
|
40
|
+
Test::Resources::Map.on( :get, [ :foo ] ) { captured[:foo] }
|
|
41
|
+
get("/foo").body.should == 'foo'
|
|
42
|
+
get("/bar").body.should == 'bar'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
feature "A regexp path component matches the any component that matches the regexp." do
|
|
46
|
+
Test::Resources::Map.on( :get, [ /\d+/ ] ) { request.path }
|
|
47
|
+
get("/1234").body.should == '/1234'
|
|
48
|
+
get("/foo").status.should == 404
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
feature "A path component of true matches the remaining path." do
|
|
52
|
+
Test::Resources::Map.on( :get, [ 'foo', true ] ) { request.path }
|
|
53
|
+
get("/foo/bar/baz").body.should == '/foo/bar/baz'
|
|
54
|
+
get("/foo").status.should == 404
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
[["one or more", 1..-1, false, true, true],
|
|
58
|
+
["zero or more", 0..-1, true, true, true],
|
|
59
|
+
["one to N (N=2)", 1..2, false, true, true, false],
|
|
60
|
+
["one to N (N=3)", 1..3, false, true, true, true, false]
|
|
61
|
+
].each do |name, range, *tests|
|
|
62
|
+
feature "A Range path component can match #{name} components" do
|
|
63
|
+
Test::Resources::Map.on(:get, ['foo', range]) { request.path }
|
|
64
|
+
tests.size.times do |i|
|
|
65
|
+
get("/foo" * ( i + 1 ) ).status.should == (tests[i] ? 200 : 404)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
feature "A path component can use a hash with a value of true to capture the remaining path." do
|
|
71
|
+
Test::Resources::Map.on( :get, [ 'foo', { :rest => true } ] ) { captured[:rest] * ' ' }
|
|
72
|
+
get("/foo/bar/baz").body.should == 'bar baz'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
[["one or more", 1..-1, false, 'foo', 'foo foo'],
|
|
76
|
+
["zero or more", 0..-1, '', 'foo', 'foo foo'],
|
|
77
|
+
["one to N (N=2)", 1..2, false, 'foo', 'foo foo', false],
|
|
78
|
+
["one to N (N=3)", 0..3, '', 'foo', 'foo foo', 'foo foo foo', false]
|
|
79
|
+
].each do |name, range, *tests|
|
|
80
|
+
feature "A Range path component can match #{name} components" do
|
|
81
|
+
Test::Resources::Map.on(:get, ['foo', { :rest => range }]) { captured.rest * ' ' }
|
|
82
|
+
tests.size.times do |i|
|
|
83
|
+
response = get("/foo" * ( i + 1 ) )
|
|
84
|
+
tests[i] ? response.body.should == tests[i] : response.status.should == 404
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
feature "A path component can use a hash with a string value to provide a default." do
|
|
90
|
+
Test::Resources::Map.on( :get, [ 'foo', { :bar => 'bar' } ] ) { captured[:bar] }
|
|
91
|
+
get("/foo/baz").body.should == 'baz'
|
|
92
|
+
get("/foo").body.should == 'bar'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
feature "A path component can use a hash with a regexp value to match and capture." do
|
|
96
|
+
Test::Resources::Map.on( :get, [ 'foo', { :bar => /\d+/ } ] ) { captured[:bar] }
|
|
97
|
+
get("/foo/123").body.should == '123'
|
|
98
|
+
get("/foo").status.should == 404
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "Path components match against unescaped values" do
|
|
102
|
+
Test::Resources::Map.on(:get, [ 'polar bear']) { 'bang' }
|
|
103
|
+
get("/polar%20bear").body.should == 'bang'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
data/test/match/query.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../test/helpers.rb"
|
|
2
|
+
require 'waves/foundations/compact'
|
|
3
|
+
|
|
4
|
+
describe "Matching Query Parameters" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
Test = Module.new { include Waves::Foundations::Compact }
|
|
8
|
+
Waves << Test
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
after do
|
|
12
|
+
Waves.applications.clear
|
|
13
|
+
Object.instance_eval { remove_const(:Test) if const_defined?(:Test) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
feature "Test for a query parameter using true" do
|
|
17
|
+
Test::Resources::Map.on(:get, ["foo"], :accept => "text/plain",
|
|
18
|
+
:query => {:bar => true}) { }
|
|
19
|
+
|
|
20
|
+
resp = get "/foo?bar=baz", "HTTP_ACCEPT" => "text/plain"
|
|
21
|
+
resp.status.should == 200
|
|
22
|
+
|
|
23
|
+
resp = get "/foo", "HTTP_ACCEPT" => "text/plain"
|
|
24
|
+
resp.status.should == 404
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
feature "Test that a query parameter matches a regexp" do
|
|
28
|
+
Test::Resources::Map.on(:get, ["foo"], :accept => "text/plain",
|
|
29
|
+
:query => {:bar => /\d+/}) { }
|
|
30
|
+
|
|
31
|
+
resp = get "/foo?bar=123", "HTTP_ACCEPT" => "text/plain"
|
|
32
|
+
resp.status.should == 200
|
|
33
|
+
|
|
34
|
+
resp = get "/foo?bar=baz", "HTTP_ACCEPT" => "text/plain"
|
|
35
|
+
resp.status.should == 404
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
feature "Test that a query parameter matches a string" do
|
|
39
|
+
Test::Resources::Map.on(:get, ["foo"], :accept => "text/plain",
|
|
40
|
+
:query => {:bar => "123"}) { }
|
|
41
|
+
|
|
42
|
+
resp = get "/foo?bar=123", "HTTP_ACCEPT" => "text/plain"
|
|
43
|
+
resp.status.should == 200
|
|
44
|
+
|
|
45
|
+
resp = get "/foo?bar=baz", "HTTP_ACCEPT" => "text/plain"
|
|
46
|
+
resp.status.should == 404
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
feature "Test that a query parameter satisfies a lambda condition" do
|
|
50
|
+
Test::Resources::Map.on(:get, ["foo"], :accept => "text/plain",
|
|
51
|
+
:query => {:bar => lambda {|x| x == "123" }}) { }
|
|
52
|
+
|
|
53
|
+
resp = get "/foo?bar=123", "HTTP_ACCEPT" => "text/plain"
|
|
54
|
+
resp.status.should == 200
|
|
55
|
+
|
|
56
|
+
resp = get "/foo?bar=baz", "HTTP_ACCEPT" => "text/plain"
|
|
57
|
+
resp.status.should == 404
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|