thin 1.2.3-x86-mswin32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of thin might be problematic. Click here for more details.
- data/CHANGELOG +263 -0
- data/COPYING +18 -0
- data/README +69 -0
- data/Rakefile +36 -0
- data/benchmark/abc +51 -0
- data/benchmark/benchmarker.rb +80 -0
- data/benchmark/runner +82 -0
- data/bin/thin +6 -0
- data/example/adapter.rb +32 -0
- data/example/async_app.ru +126 -0
- data/example/async_chat.ru +247 -0
- data/example/async_tailer.ru +100 -0
- data/example/config.ru +22 -0
- data/example/monit_sockets +20 -0
- data/example/monit_unixsock +20 -0
- data/example/myapp.rb +1 -0
- data/example/ramaze.ru +12 -0
- data/example/thin.god +80 -0
- data/example/thin_solaris_smf.erb +36 -0
- data/example/thin_solaris_smf.readme.txt +150 -0
- data/example/vlad.rake +64 -0
- data/ext/thin_parser/common.rl +55 -0
- data/ext/thin_parser/ext_help.h +14 -0
- data/ext/thin_parser/extconf.rb +6 -0
- data/ext/thin_parser/parser.c +452 -0
- data/ext/thin_parser/parser.h +49 -0
- data/ext/thin_parser/parser.rl +157 -0
- data/ext/thin_parser/thin.c +433 -0
- data/lib/rack/adapter/loader.rb +79 -0
- data/lib/rack/adapter/rails.rb +181 -0
- data/lib/thin.rb +46 -0
- data/lib/thin/backends/base.rb +141 -0
- data/lib/thin/backends/swiftiply_client.rb +56 -0
- data/lib/thin/backends/tcp_server.rb +29 -0
- data/lib/thin/backends/unix_server.rb +51 -0
- data/lib/thin/command.rb +53 -0
- data/lib/thin/connection.rb +222 -0
- data/lib/thin/controllers/cluster.rb +127 -0
- data/lib/thin/controllers/controller.rb +183 -0
- data/lib/thin/controllers/service.rb +75 -0
- data/lib/thin/controllers/service.sh.erb +39 -0
- data/lib/thin/daemonizing.rb +174 -0
- data/lib/thin/headers.rb +39 -0
- data/lib/thin/logging.rb +54 -0
- data/lib/thin/request.rb +153 -0
- data/lib/thin/response.rb +101 -0
- data/lib/thin/runner.rb +209 -0
- data/lib/thin/server.rb +247 -0
- data/lib/thin/stats.html.erb +216 -0
- data/lib/thin/stats.rb +52 -0
- data/lib/thin/statuses.rb +43 -0
- data/lib/thin/version.rb +32 -0
- data/lib/thin_parser.so +0 -0
- data/spec/backends/swiftiply_client_spec.rb +66 -0
- data/spec/backends/tcp_server_spec.rb +33 -0
- data/spec/backends/unix_server_spec.rb +37 -0
- data/spec/command_spec.rb +25 -0
- data/spec/configs/cluster.yml +9 -0
- data/spec/configs/single.yml +9 -0
- data/spec/connection_spec.rb +106 -0
- data/spec/controllers/cluster_spec.rb +235 -0
- data/spec/controllers/controller_spec.rb +129 -0
- data/spec/controllers/service_spec.rb +50 -0
- data/spec/daemonizing_spec.rb +192 -0
- data/spec/headers_spec.rb +40 -0
- data/spec/logging_spec.rb +46 -0
- data/spec/perf/request_perf_spec.rb +50 -0
- data/spec/perf/response_perf_spec.rb +19 -0
- data/spec/perf/server_perf_spec.rb +39 -0
- data/spec/rack/loader_spec.rb +29 -0
- data/spec/rack/rails_adapter_spec.rb +106 -0
- data/spec/rails_app/app/controllers/application.rb +10 -0
- data/spec/rails_app/app/controllers/simple_controller.rb +19 -0
- data/spec/rails_app/app/helpers/application_helper.rb +3 -0
- data/spec/rails_app/app/views/simple/index.html.erb +15 -0
- data/spec/rails_app/config/boot.rb +109 -0
- data/spec/rails_app/config/environment.rb +64 -0
- data/spec/rails_app/config/environments/development.rb +18 -0
- data/spec/rails_app/config/environments/production.rb +19 -0
- data/spec/rails_app/config/environments/test.rb +22 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/routes.rb +35 -0
- data/spec/rails_app/public/404.html +30 -0
- data/spec/rails_app/public/422.html +30 -0
- data/spec/rails_app/public/500.html +30 -0
- data/spec/rails_app/public/dispatch.cgi +10 -0
- data/spec/rails_app/public/dispatch.fcgi +24 -0
- data/spec/rails_app/public/dispatch.rb +10 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/index.html +277 -0
- data/spec/rails_app/public/javascripts/application.js +2 -0
- data/spec/rails_app/public/javascripts/controls.js +963 -0
- data/spec/rails_app/public/javascripts/dragdrop.js +972 -0
- data/spec/rails_app/public/javascripts/effects.js +1120 -0
- data/spec/rails_app/public/javascripts/prototype.js +4225 -0
- data/spec/rails_app/public/robots.txt +5 -0
- data/spec/rails_app/script/about +3 -0
- data/spec/rails_app/script/console +3 -0
- data/spec/rails_app/script/destroy +3 -0
- data/spec/rails_app/script/generate +3 -0
- data/spec/rails_app/script/performance/benchmarker +3 -0
- data/spec/rails_app/script/performance/profiler +3 -0
- data/spec/rails_app/script/performance/request +3 -0
- data/spec/rails_app/script/plugin +3 -0
- data/spec/rails_app/script/process/inspector +3 -0
- data/spec/rails_app/script/process/reaper +3 -0
- data/spec/rails_app/script/process/spawner +3 -0
- data/spec/rails_app/script/runner +3 -0
- data/spec/rails_app/script/server +3 -0
- data/spec/request/mongrel_spec.rb +39 -0
- data/spec/request/parser_spec.rb +215 -0
- data/spec/request/persistent_spec.rb +35 -0
- data/spec/request/processing_spec.rb +45 -0
- data/spec/response_spec.rb +91 -0
- data/spec/runner_spec.rb +168 -0
- data/spec/server/builder_spec.rb +44 -0
- data/spec/server/pipelining_spec.rb +110 -0
- data/spec/server/robustness_spec.rb +34 -0
- data/spec/server/stopping_spec.rb +55 -0
- data/spec/server/swiftiply.yml +6 -0
- data/spec/server/swiftiply_spec.rb +32 -0
- data/spec/server/tcp_spec.rb +57 -0
- data/spec/server/threaded_spec.rb +27 -0
- data/spec/server/unix_socket_spec.rb +26 -0
- data/spec/server_spec.rb +96 -0
- data/spec/spec_helper.rb +219 -0
- data/tasks/announce.rake +22 -0
- data/tasks/deploy.rake +13 -0
- data/tasks/email.erb +30 -0
- data/tasks/gem.rake +74 -0
- data/tasks/rdoc.rake +25 -0
- data/tasks/site.rake +15 -0
- data/tasks/spec.rake +49 -0
- data/tasks/stats.rake +28 -0
- metadata +246 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
include Controllers
|
4
|
+
|
5
|
+
describe Controller, 'start' do
|
6
|
+
before do
|
7
|
+
@controller = Controller.new(:address => '0.0.0.0',
|
8
|
+
:port => 3000,
|
9
|
+
:pid => 'thin.pid',
|
10
|
+
:log => 'thin.log',
|
11
|
+
:timeout => 60,
|
12
|
+
:max_conns => 2000,
|
13
|
+
:max_persistent_conns => 1000,
|
14
|
+
:adapter => 'rails')
|
15
|
+
|
16
|
+
@server = OpenStruct.new
|
17
|
+
@adapter = OpenStruct.new
|
18
|
+
|
19
|
+
Server.should_receive(:new).with('0.0.0.0', 3000, @controller.options).and_return(@server)
|
20
|
+
@server.should_receive(:config)
|
21
|
+
Rack::Adapter::Rails.stub!(:new).and_return(@adapter)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should configure server" do
|
25
|
+
@controller.start
|
26
|
+
|
27
|
+
@server.app.should == @adapter
|
28
|
+
@server.pid_file.should == 'thin.pid'
|
29
|
+
@server.log_file.should == 'thin.log'
|
30
|
+
@server.maximum_connections.should == 2000
|
31
|
+
@server.maximum_persistent_connections.should == 1000
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should start as daemon" do
|
35
|
+
@controller.options[:daemonize] = true
|
36
|
+
@controller.options[:user] = true
|
37
|
+
@controller.options[:group] = true
|
38
|
+
|
39
|
+
@server.should_receive(:daemonize)
|
40
|
+
@server.should_receive(:change_privilege)
|
41
|
+
|
42
|
+
@controller.start
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should configure Rails adapter" do
|
46
|
+
Rack::Adapter::Rails.should_receive(:new).with(@controller.options.merge(:root => nil))
|
47
|
+
|
48
|
+
@controller.start
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should mount app under :prefix" do
|
52
|
+
@controller.options[:prefix] = '/app'
|
53
|
+
@controller.start
|
54
|
+
|
55
|
+
@server.app.class.should == Rack::URLMap
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should mount Stats adapter under :stats" do
|
59
|
+
@controller.options[:stats] = '/stats'
|
60
|
+
@controller.start
|
61
|
+
|
62
|
+
@server.app.class.should == Stats::Adapter
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should load app from Rack config" do
|
66
|
+
@controller.options[:rackup] = File.dirname(__FILE__) + '/../../example/config.ru'
|
67
|
+
@controller.start
|
68
|
+
|
69
|
+
@server.app.class.should == Proc
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should load app from ruby file" do
|
73
|
+
@controller.options[:rackup] = File.dirname(__FILE__) + '/../../example/myapp.rb'
|
74
|
+
@controller.start
|
75
|
+
|
76
|
+
@server.app.should == Myapp
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should throwup if rackup is not a .ru or .rb file" do
|
80
|
+
proc do
|
81
|
+
@controller.options[:rackup] = File.dirname(__FILE__) + '/../../example/myapp.foo'
|
82
|
+
@controller.start
|
83
|
+
end.should raise_error(RuntimeError, /please/)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set server as threaded" do
|
87
|
+
@controller.options[:threaded] = true
|
88
|
+
@controller.start
|
89
|
+
|
90
|
+
@server.threaded.should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should set RACK_ENV" do
|
94
|
+
@controller.options[:rackup] = File.dirname(__FILE__) + '/../../example/config.ru'
|
95
|
+
@controller.options[:environment] = "lolcat"
|
96
|
+
@controller.start
|
97
|
+
|
98
|
+
ENV['RACK_ENV'].should == "lolcat"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
describe Controller do
|
104
|
+
before do
|
105
|
+
@controller = Controller.new(:pid => 'thin.pid', :timeout => 10)
|
106
|
+
@controller.stub!(:wait_for_file)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should stop" do
|
110
|
+
Server.should_receive(:kill).with('thin.pid', 10)
|
111
|
+
@controller.stop
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should restart" do
|
115
|
+
Server.should_receive(:restart).with('thin.pid')
|
116
|
+
@controller.restart
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should write configuration file" do
|
120
|
+
silence_stream(STDOUT) do
|
121
|
+
Controller.new(:config => 'test.yml', :port => 5000, :address => '127.0.0.1').config
|
122
|
+
end
|
123
|
+
|
124
|
+
File.read('test.yml').should include('port: 5000', 'address: 127.0.0.1')
|
125
|
+
File.read('test.yml').should_not include('config: ')
|
126
|
+
|
127
|
+
File.delete('test.yml')
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
include Controllers
|
3
|
+
|
4
|
+
describe Service do
|
5
|
+
before(:all) do
|
6
|
+
silence_stream(STDERR) do
|
7
|
+
Service::INITD_PATH = 'tmp/sandbox' + Service::INITD_PATH
|
8
|
+
Service::DEFAULT_CONFIG_PATH = 'tmp/sandbox' + Service::DEFAULT_CONFIG_PATH
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
Thin.stub!(:linux?).and_return(true)
|
14
|
+
FileUtils.mkdir_p 'tmp/sandbox'
|
15
|
+
|
16
|
+
@service = Service.new(:all => 'spec/configs')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should call command for each config file" do
|
20
|
+
Command.should_receive(:run).with(:start, :config => 'spec/configs/cluster.yml', :daemonize => true)
|
21
|
+
Command.should_receive(:run).with(:start, :config => 'spec/configs/single.yml', :daemonize => true)
|
22
|
+
|
23
|
+
@service.start
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should create /etc/init.d/thin file when calling install" do
|
27
|
+
@service.install
|
28
|
+
|
29
|
+
File.exist?(Service::INITD_PATH).should be_true
|
30
|
+
File.read(Service::INITD_PATH).should include('CONFIG_PATH=tmp/sandbox/etc/thin',
|
31
|
+
'SCRIPT_NAME=tmp/sandbox/etc/init.d/thin',
|
32
|
+
'DAEMON=' + Command.script)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should create /etc/thin dir when calling install" do
|
36
|
+
@service.install
|
37
|
+
|
38
|
+
File.directory?(Service::DEFAULT_CONFIG_PATH).should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should include specified path in /etc/init.d/thin script" do
|
42
|
+
@service.install('tmp/sandbox/usr/thin')
|
43
|
+
|
44
|
+
File.read(Service::INITD_PATH).should include('CONFIG_PATH=tmp/sandbox/usr/thin')
|
45
|
+
end
|
46
|
+
|
47
|
+
after do
|
48
|
+
FileUtils.rm_rf 'tmp/sandbox'
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class TestServer
|
4
|
+
include Logging # Daemonizable should include this?
|
5
|
+
include Daemonizable
|
6
|
+
|
7
|
+
def stop
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
'Thin test server'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'Daemonizing' do
|
16
|
+
before :all do
|
17
|
+
@logfile = File.dirname(__FILE__) + '/../log/daemonizing_test.log'
|
18
|
+
@pidfile = 'test.pid'
|
19
|
+
File.delete(@logfile) if File.exist?(@logfile)
|
20
|
+
File.delete(@pidfile) if File.exist?(@pidfile)
|
21
|
+
end
|
22
|
+
|
23
|
+
before :each do
|
24
|
+
@server = TestServer.new
|
25
|
+
@server.log_file = @logfile
|
26
|
+
@server.pid_file = @pidfile
|
27
|
+
@pid = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have a pid file' do
|
31
|
+
@server.should respond_to(:pid_file)
|
32
|
+
@server.should respond_to(:pid_file=)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should create a pid file' do
|
36
|
+
@pid = fork do
|
37
|
+
@server.daemonize
|
38
|
+
sleep 1
|
39
|
+
end
|
40
|
+
|
41
|
+
sleep 1
|
42
|
+
Process.wait(@pid)
|
43
|
+
File.exist?(@server.pid_file).should be_true
|
44
|
+
@pid = @server.pid
|
45
|
+
|
46
|
+
proc { sleep 0.1 while File.exist?(@server.pid_file) }.should take_less_then(5)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should redirect stdio to a log file' do
|
50
|
+
@pid = fork do
|
51
|
+
@server.log_file = 'daemon_test.log'
|
52
|
+
@server.daemonize
|
53
|
+
|
54
|
+
puts "simple puts"
|
55
|
+
STDERR.puts "STDERR.puts"
|
56
|
+
STDOUT.puts "STDOUT.puts"
|
57
|
+
end
|
58
|
+
Process.wait(@pid)
|
59
|
+
# Wait for the file to close and magical stuff to happen
|
60
|
+
proc { sleep 0.1 until File.exist?('daemon_test.log') }.should take_less_then(3)
|
61
|
+
sleep 0.5
|
62
|
+
|
63
|
+
@pid = @server.pid
|
64
|
+
|
65
|
+
log = File.read('daemon_test.log')
|
66
|
+
log.should include('simple puts', 'STDERR.puts', 'STDOUT.puts')
|
67
|
+
|
68
|
+
File.delete 'daemon_test.log'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should change privilege' do
|
72
|
+
@pid = fork do
|
73
|
+
@server.daemonize
|
74
|
+
@server.change_privilege('root', 'admin')
|
75
|
+
end
|
76
|
+
Process.wait(@pid)
|
77
|
+
$?.should be_a_success
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should kill process in pid file' do
|
81
|
+
@pid = fork do
|
82
|
+
@server.daemonize
|
83
|
+
loop { sleep 3 }
|
84
|
+
end
|
85
|
+
|
86
|
+
server_should_start_in_less_then 3
|
87
|
+
|
88
|
+
@pid = @server.pid
|
89
|
+
|
90
|
+
silence_stream STDOUT do
|
91
|
+
TestServer.kill(@server.pid_file, 1)
|
92
|
+
end
|
93
|
+
|
94
|
+
File.exist?(@server.pid_file).should be_false
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should force kill process in pid file' do
|
98
|
+
@pid = fork do
|
99
|
+
@server.daemonize
|
100
|
+
loop { sleep 3 }
|
101
|
+
end
|
102
|
+
|
103
|
+
server_should_start_in_less_then 3
|
104
|
+
|
105
|
+
@pid = @server.pid
|
106
|
+
|
107
|
+
silence_stream STDOUT do
|
108
|
+
TestServer.kill(@server.pid_file, 0)
|
109
|
+
end
|
110
|
+
|
111
|
+
File.exist?(@server.pid_file).should be_false
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should send kill signal if timeout' do
|
115
|
+
@pid = fork do
|
116
|
+
@server.should_receive(:stop) # pretend we cannot handle the INT signal
|
117
|
+
@server.daemonize
|
118
|
+
sleep 5
|
119
|
+
end
|
120
|
+
|
121
|
+
server_should_start_in_less_then 10
|
122
|
+
|
123
|
+
@pid = @server.pid
|
124
|
+
|
125
|
+
silence_stream STDOUT do
|
126
|
+
TestServer.kill(@server.pid_file, 1)
|
127
|
+
end
|
128
|
+
|
129
|
+
sleep 1
|
130
|
+
|
131
|
+
File.exist?(@server.pid_file).should be_false
|
132
|
+
Process.running?(@pid).should be_false
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should restart" do
|
136
|
+
@pid = fork do
|
137
|
+
@server.on_restart {}
|
138
|
+
@server.daemonize
|
139
|
+
sleep 5
|
140
|
+
end
|
141
|
+
|
142
|
+
server_should_start_in_less_then 10
|
143
|
+
|
144
|
+
@pid = @server.pid
|
145
|
+
|
146
|
+
silence_stream STDOUT do
|
147
|
+
TestServer.restart(@server.pid_file)
|
148
|
+
end
|
149
|
+
|
150
|
+
proc { sleep 0.1 while File.exist?(@server.pid_file) }.should take_less_then(10)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should not restart when not running" do
|
154
|
+
silence_stream STDOUT do
|
155
|
+
TestServer.restart(@server.pid_file)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should exit and raise if pid file already exist" do
|
160
|
+
@pid = fork do
|
161
|
+
@server.daemonize
|
162
|
+
sleep 5
|
163
|
+
end
|
164
|
+
server_should_start_in_less_then 10
|
165
|
+
|
166
|
+
@pid = @server.pid
|
167
|
+
|
168
|
+
proc { @server.daemonize }.should raise_error(PidFileExist)
|
169
|
+
|
170
|
+
File.exist?(@server.pid_file).should be_true
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should should delete pid file if stale" do
|
174
|
+
# Create a file w/ a PID that does not exist
|
175
|
+
File.open(@server.pid_file, 'w') { |f| f << 999999999 }
|
176
|
+
|
177
|
+
@server.send(:remove_stale_pid_file)
|
178
|
+
|
179
|
+
File.exist?(@server.pid_file).should be_false
|
180
|
+
end
|
181
|
+
|
182
|
+
after do
|
183
|
+
Process.kill(9, @pid.to_i) if @pid && Process.running?(@pid.to_i)
|
184
|
+
Process.kill(9, @server.pid) if @server.pid && Process.running?(@server.pid)
|
185
|
+
File.delete(@server.pid_file) rescue nil
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
def server_should_start_in_less_then(sec=10)
|
190
|
+
proc { sleep 0.1 until File.exist?(@server.pid_file) }.should take_less_then(10)
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Headers do
|
4
|
+
before do
|
5
|
+
@headers = Headers.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should allow duplicate on some fields' do
|
9
|
+
@headers['Set-Cookie'] = 'twice'
|
10
|
+
@headers['Set-Cookie'] = 'is cooler the once'
|
11
|
+
|
12
|
+
@headers.to_s.should == "Set-Cookie: twice\r\nSet-Cookie: is cooler the once\r\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should overwrite value on non duplicate fields' do
|
16
|
+
@headers['Host'] = 'this is unique'
|
17
|
+
@headers['Host'] = 'so is this'
|
18
|
+
|
19
|
+
@headers.to_s.should == "Host: this is unique\r\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should output to string' do
|
23
|
+
@headers['Host'] = 'localhost:3000'
|
24
|
+
@headers['Set-Cookie'] = 'twice'
|
25
|
+
@headers['Set-Cookie'] = 'is cooler the once'
|
26
|
+
|
27
|
+
@headers.to_s.should == "Host: localhost:3000\r\nSet-Cookie: twice\r\nSet-Cookie: is cooler the once\r\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should ignore nil values' do
|
31
|
+
@headers['Something'] = nil
|
32
|
+
@headers.to_s.should_not include('Something: ')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should format Time values correctly' do
|
36
|
+
time = Time.now
|
37
|
+
@headers['Modified-At'] = time
|
38
|
+
@headers.to_s.should include("Modified-At: #{time.httpdate}")
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class TestLogging
|
4
|
+
include Logging
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Logging do
|
8
|
+
before do
|
9
|
+
Logging.silent = false
|
10
|
+
@object = TestLogging.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should output debug when set to true" do
|
14
|
+
Logging.debug = true
|
15
|
+
@object.should_receive(:puts)
|
16
|
+
@object.debug 'hi'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should output trace when set to true" do
|
20
|
+
Logging.trace = true
|
21
|
+
@object.should_receive(:puts)
|
22
|
+
@object.trace 'hi'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not output when silenced" do
|
26
|
+
Logging.silent = true
|
27
|
+
@object.should_not_receive(:puts)
|
28
|
+
@object.log 'hi'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not output when silenced as instance method" do
|
32
|
+
@object.silent = true
|
33
|
+
|
34
|
+
@object.should_not_receive(:puts)
|
35
|
+
@object.log 'hi'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be usable as module functions" do
|
39
|
+
Logging.silent = true
|
40
|
+
Logging.log "hi"
|
41
|
+
end
|
42
|
+
|
43
|
+
after do
|
44
|
+
Logging.silent = true
|
45
|
+
end
|
46
|
+
end
|