lilypad 0.2.4 → 0.3.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.
@@ -1,6 +1,10 @@
1
+ Sinatra::Base.set :raise_errors, false
2
+
1
3
  class SinatraApp < Sinatra::Base
2
4
 
3
- use Rack::Lilypad, 'xxx'
5
+ use Rack::Lilypad, '' do
6
+ sinatra
7
+ end
4
8
  use TestExceptionMiddleware
5
9
 
6
10
  get "/nothing" do
@@ -0,0 +1,67 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../../spec_helper")
2
+
3
+ describe Lilypad::Rails do
4
+
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ ActionController::Dispatcher.new
9
+ end
10
+
11
+ describe :post do
12
+
13
+ after(:each) do
14
+ ENV['RACK_ENV'] = 'production'
15
+ end
16
+
17
+ before(:each) do
18
+ stub_net_http
19
+ end
20
+
21
+ it "should post an error to Hoptoad" do
22
+ @http.should_receive(:post)
23
+ get "/test" rescue nil
24
+ end
25
+
26
+ it "should post middleware exceptions" do
27
+ @http.should_receive(:post)
28
+ get "/nothing?test_exception=1" rescue nil
29
+ end
30
+
31
+ it "should not post anything if non-production environment" do
32
+ ENV['RACK_ENV'] = 'development'
33
+ @http.should_not_receive(:post)
34
+ get "/test" rescue nil
35
+ end
36
+ end
37
+
38
+ describe :RACK_ENV do
39
+
40
+ before(:each) do
41
+ ENV['RACK_ENV'] = nil
42
+ ENV['RAILS_ENV'] = 'production'
43
+ ActionController::Base.send :include, Lilypad::Rails
44
+ end
45
+
46
+ it "should set ENV['RACK_ENV']" do
47
+ ENV['RACK_ENV'].should == 'production'
48
+ end
49
+ end
50
+
51
+ describe :rescue_action_without_handler do
52
+
53
+ it "should set Config::Request.action" do
54
+ Lilypad::Config::Request.should_receive(:action).with('test')
55
+ get "/test" rescue nil
56
+ end
57
+
58
+ it "should set Config::Request.component" do
59
+ Lilypad::Config::Request.should_receive(:component).with('application')
60
+ get "/test" rescue nil
61
+ end
62
+
63
+ it "should re-raise the exception (ActionController::Failsafe disabled)" do
64
+ lambda { get "/test" }.should raise_error(TestError)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../../spec_helper")
2
+
3
+ describe Lilypad::Sinatra do
4
+
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ SinatraApp.new
9
+ end
10
+
11
+ describe :post do
12
+
13
+ after(:each) do
14
+ ENV['RACK_ENV'] = 'production'
15
+ end
16
+
17
+ before(:each) do
18
+ stub_net_http
19
+ end
20
+
21
+ it "should post an error to Hoptoad" do
22
+ @http.should_receive(:post)
23
+ get "/test" rescue nil
24
+ end
25
+
26
+ it "should post middleware exceptions" do
27
+ @http.should_receive(:post)
28
+ get "/nothing?test_exception=1" rescue nil
29
+ end
30
+
31
+ it "should not post anything if non-production environment" do
32
+ ENV['RACK_ENV'] = 'development'
33
+ @http.should_not_receive(:post)
34
+ get "/test" rescue nil
35
+ end
36
+ end
37
+
38
+ describe :raise_errors do
39
+
40
+ it "should set raise_errors to true" do
41
+ get "/nothing"
42
+ Sinatra::Base.raise_errors?.should == true
43
+ end
44
+
45
+ it "should re-raise the exception" do
46
+ lambda { get "/test" }.should raise_error(TestError)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../../spec_helper")
2
+
3
+ describe Lilypad::Config::Request do
4
+
5
+ before(:each) do
6
+ Lilypad::Config::Request.action 'action'
7
+ Lilypad::Config::Request.component 'component'
8
+ end
9
+
10
+ after(:each) do
11
+ Lilypad::Config::Request.class_eval do
12
+ @action = nil
13
+ @component = nil
14
+ end
15
+ end
16
+
17
+ it "should set options" do
18
+ Lilypad::Config::Request.action.should == 'action'
19
+ Lilypad::Config::Request.component.should == 'component'
20
+ end
21
+
22
+ it "should provide a method to reset all options" do
23
+ Lilypad::Config::Request.reset!
24
+ Lilypad::Config::Request.action.should == nil
25
+ Lilypad::Config::Request.component.should == nil
26
+ end
27
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../spec_helper")
2
+
3
+ describe Lilypad::Config do
4
+
5
+ before(:each) do
6
+ Lilypad::Config.api_key 'api_key'
7
+ Lilypad::Config.deploy_url 'deploy_url'
8
+ Lilypad::Config.environments 'environments'
9
+ Lilypad::Config.filters 'filters'
10
+ Lilypad::Config.log 'log'
11
+ Lilypad::Config.notify_url 'notify_url'
12
+ end
13
+
14
+ after(:each) do
15
+ Lilypad::Config.class_eval do
16
+ @api_key = nil
17
+ @deploy_url = nil
18
+ @environments = nil
19
+ @filters = nil
20
+ @log = nil
21
+ @notify_url = nil
22
+ end
23
+ end
24
+
25
+ it "should set options" do
26
+ Lilypad::Config.api_key.should == 'api_key'
27
+ Lilypad::Config.deploy_url.should == 'deploy_url'
28
+ Lilypad::Config.environments.should == 'environments'
29
+ Lilypad::Config.filters.should == 'filters'
30
+ Lilypad::Config.log.should == 'log'
31
+ Lilypad::Config.notify_url.should == 'notify_url'
32
+ end
33
+
34
+ it "should require the rails adapter when the rails method is called" do
35
+ adapter = File.expand_path "#{SPEC}/../lib/lilypad/adapters/rails"
36
+ Lilypad::Config.should_receive(:require).with(adapter)
37
+ Lilypad::Config.rails
38
+ end
39
+
40
+ it "should require the rails adapter when the sinatra method is called" do
41
+ adapter = File.expand_path "#{SPEC}/../lib/lilypad/adapters/sinatra"
42
+ Lilypad::Config.should_receive(:require).with(adapter)
43
+ Lilypad::Config.sinatra
44
+ end
45
+
46
+ describe :Methods do
47
+
48
+ include Lilypad::Config::Methods
49
+
50
+ it "should provide an api_key method" do
51
+ Lilypad::Config.api_key 'api_key'
52
+ api_key.should == 'api_key'
53
+ Lilypad::Config.api_key { |env, e| [ env, e ].join '_' }
54
+ api_key.should == 'api_key' # api string takes precedence even when block configured
55
+ Lilypad::Config.class_eval { @api_key = nil }
56
+ api_key('api_key', 'block').should == 'api_key_block' # string is nil, now use the block
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,85 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../../spec_helper")
2
+
3
+ describe Lilypad::Hoptoad::Deploy do
4
+
5
+ before(:each) do
6
+ stub_net_http
7
+ @options = {
8
+ :username => 'username',
9
+ :environment => 'environment',
10
+ :revision => 'revision',
11
+ :repository => 'repository'
12
+ }
13
+ @instance = Lilypad::Hoptoad::Deploy.new(@options)
14
+ end
15
+
16
+ describe :initialize do
17
+
18
+ after(:each) do
19
+ @instance.send(:initialize, @options)
20
+ end
21
+
22
+ it "should call the post method" do
23
+ @instance.should_receive(:post)
24
+ end
25
+
26
+ it "should log the event" do
27
+ @instance.should_receive(:log).with(:deploy, @http_ok)
28
+ end
29
+
30
+ it "should return the success status" do
31
+ @instance.should_receive(:success?)
32
+ end
33
+ end
34
+
35
+ describe :params do
36
+
37
+ before(:each) do
38
+ Lilypad { api_key '' }
39
+ end
40
+
41
+ it "should return parameters for the Hoptoad request" do
42
+ @instance.send(:params).should == {
43
+ 'api_key' => '',
44
+ 'deploy[local_username]' => @options[:username],
45
+ 'deploy[rails_env]' => @options[:environment],
46
+ 'deploy[scm_revision]' => @options[:revision],
47
+ 'deploy[scm_repository]' => @options[:repository]
48
+ }
49
+ end
50
+ end
51
+
52
+ describe :post do
53
+
54
+ before(:each) do
55
+ URI.stub!(:parse).and_return('uri')
56
+ @instance.stub!(:params).and_return('params')
57
+ end
58
+
59
+ after(:each) do
60
+ @instance.send(:post)
61
+ end
62
+
63
+ it "should parse the URI" do
64
+ URI.should_receive(:parse).with(Lilypad::Config.deploy_url)
65
+ end
66
+
67
+ it "should post the form using the URI and params method" do
68
+ @instance.should_receive(:params)
69
+ Net::HTTP.should_receive(:post_form).with('uri', 'params')
70
+ end
71
+ end
72
+
73
+ describe :success? do
74
+
75
+ it "should make sure the response's superclass equals Net::HTTPSuccess" do
76
+ Net::HTTP.stub!(:post_form).and_return(nil)
77
+ @instance.send(:initialize, @options)
78
+ @instance.send(:success?).should == false
79
+
80
+ Net::HTTP.stub!(:post_form).and_return(@http_ok)
81
+ @instance.send(:initialize, @options)
82
+ @instance.send(:success?).should == true
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path("#{File.dirname __FILE__}/../../spec_helper")
2
+
3
+ describe Lilypad::Hoptoad::Notify do
4
+
5
+ before(:each) do
6
+ uri = mock(:uri)
7
+ uri.stub!(:host)
8
+ uri.stub!(:port)
9
+ uri.stub!(:path).and_return('uri')
10
+ URI.stub!(:parse).and_return(uri)
11
+ stub_net_http
12
+ begin; raise 'Test'; rescue Exception => e; @e = e; end
13
+ @instance = Lilypad::Hoptoad::Notify.new(nil, @e)
14
+ end
15
+
16
+ describe :initialize do
17
+
18
+ before(:each) do
19
+ Lilypad::Hoptoad::XML.stub!(:build).and_return('xml')
20
+ @instance.stub!(:headers).and_return 'headers'
21
+ @instance.stub!(:parse).and_return ['parse']
22
+ end
23
+
24
+ after(:each) do
25
+ @instance.send(:initialize, nil, @e)
26
+ end
27
+
28
+ it "should build XML from parse method" do
29
+ Lilypad::Hoptoad::XML.should_receive(:build).with('parse')
30
+ end
31
+
32
+ it "should post the XML" do
33
+ @http.should_receive(:post).with('uri', 'xml', 'headers')
34
+ end
35
+
36
+ it "should log the event" do
37
+ @instance.should_receive(:log).with(:notify, @http_ok)
38
+ end
39
+
40
+ it "should reset the request config" do
41
+ Lilypad::Config::Request.should_receive(:reset!)
42
+ end
43
+
44
+ it "should return the success status" do
45
+ @instance.should_receive(:success?)
46
+ end
47
+ end
48
+
49
+ describe :backtrace do
50
+
51
+ it "should return an array of backtrace information" do
52
+ backtrace = @instance.send(:backtrace)
53
+ backtrace.first.file.should =~ /notify_spec/
54
+ backtrace.first.respond_to?(:number).should == true
55
+ backtrace.first.respond_to?(:method).should == true
56
+ backtrace.length.should > 1
57
+ end
58
+ end
59
+
60
+ describe :filter do
61
+
62
+ after(:each) do
63
+ Lilypad { filters [] }
64
+ end
65
+
66
+ it "should remove elements of a hash for keys that match an element Config.filters" do
67
+ Lilypad { filters [ 't1' ] }
68
+ filtered = @instance.send(:filter, { :t1 => 't1', :t2 => 't2' })
69
+ filtered.should == { :t1 => '[FILTERED]', :t2 => 't2' }
70
+ end
71
+ end
72
+
73
+ describe :http_start do
74
+
75
+ after(:each) do
76
+ @instance.send(:http_start) {}
77
+ end
78
+
79
+ it "should get a URI instance for the notify URL" do
80
+ URI.should_receive(:parse).with(Lilypad::Config.notify_url)
81
+ end
82
+
83
+ it "should call start on Net::HTTP" do
84
+ Net::HTTP.should_receive(:start)
85
+ end
86
+
87
+ it "should yield to the block" do
88
+ yielded = false
89
+ @instance.send(:http_start) { yielded = true }
90
+ yielded.should == true
91
+ end
92
+ end
93
+
94
+ describe :parse do
95
+
96
+ before(:each) do
97
+ @env = mock(:env)
98
+ @env.stub!(:merge).and_return('env')
99
+ ENV.stub!(:to_hash).and_return(@env)
100
+ @instance.stub!(:filter).and_return('env')
101
+ @instance.stub!(:backtrace).and_return('backtrace')
102
+ end
103
+
104
+ it "should filter the environment" do
105
+ @instance.should_receive(:filter).with('env')
106
+ ENV.should_receive(:to_hash)
107
+ @env.should_receive(:merge)
108
+ @instance.send(:parse)
109
+ end
110
+
111
+ it "should return the correct parameters without an environment" do
112
+ @instance.send(:parse).should == [ "backtrace", "env", @e, {}, "Internal" ]
113
+ end
114
+
115
+ it "should return the correct parameters with an environment" do
116
+ request = mock(:request)
117
+ request.stub!(:params)
118
+ request.stub!(:script_name).and_return 'request_'
119
+ request.stub!(:path_info).and_return 'path'
120
+ Rack::Request.stub!(:new).and_return(request)
121
+ @instance.send(:initialize, {}, @e)
122
+ @instance.send(:parse).should == ["backtrace", "env", @e, "env", "request_path"]
123
+ end
124
+ end
125
+
126
+ describe :success? do
127
+
128
+ it "should make sure the response's superclass equals Net::HTTPSuccess" do
129
+ @http.stub!(:post).and_return(nil)
130
+ @instance.send(:initialize, nil, @e)
131
+ @instance.send(:success?).should == false
132
+
133
+ @http.stub!(:post).and_return(@http_ok)
134
+ @instance.send(:initialize, nil, @e)
135
+ @instance.send(:success?).should == true
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,76 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe Rack::Lilypad do
4
+
5
+ include Rack::Test::Methods
6
+
7
+ before(:each) do
8
+ @app = lambda { |env| raise TestError, 'Test' }
9
+ @env = Rack::MockRequest.env_for("/test")
10
+ stub_net_http
11
+ end
12
+
13
+ it "should yield a configuration object to the block when created" do
14
+ Rack::Lilypad.new(@app, '') do
15
+ filters %w(T1 T2)
16
+ log 'T3'
17
+ end
18
+ Lilypad::Config.filters.include?('T1').should == true
19
+ Lilypad::Config.filters.include?('T2').should == true
20
+ Lilypad::Config.log.should == 'T3'
21
+
22
+ Lilypad::Config.filters []
23
+ Lilypad::Config.log false
24
+ end
25
+
26
+ it "should write to a log file on success and failure" do
27
+ log_path = "#{SPEC}/fixtures/hoptoad.log"
28
+ notifier = Rack::Lilypad.new(@app, '') do |app|
29
+ log log_path
30
+ end
31
+
32
+ notifier.call(@env) rescue nil
33
+
34
+ File.exists?(log_path).should == true
35
+ File.read(log_path).should =~ /Notify Success/
36
+ File.delete(log_path)
37
+
38
+ @http.stub!(:post).and_return false
39
+ notifier.call(@env) rescue nil
40
+
41
+ File.exists?(log_path).should == true
42
+ File.read(log_path).should =~ /Notify Failure/
43
+ File.delete(log_path)
44
+
45
+ Lilypad::Config.log false
46
+ end
47
+
48
+ it "should transfer valid XML to Hoptoad" do
49
+ # Test complex environment variables
50
+ @env['rack.hash_test'] = { :test => true }
51
+ @env['rack.object_test'] = Object.new
52
+
53
+ notifier = Rack::Lilypad.new(@app, '')
54
+ notifier.call(@env) rescue nil
55
+ validate_xml
56
+ end
57
+
58
+ it "should provide a notify method" do
59
+ @http.should_receive(:post)
60
+ begin
61
+ raise TestError, 'Test'
62
+ rescue Exception => e
63
+ Lilypad.notify(e)
64
+ end
65
+ end
66
+
67
+ it "should provide a deploy method" do
68
+ Net::HTTP.should_receive(:post_form)
69
+ Lilypad.deploy(
70
+ :username => 't1',
71
+ :environment => 't2',
72
+ :revision => 't3',
73
+ :repository => 't4'
74
+ )
75
+ end
76
+ end