hydraulic_brake 0.0.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/.rbenv-version +1 -0
- data/.rvmrc +1 -0
- data/.yardopts +2 -0
- data/Gemfile +16 -0
- data/INSTALL +20 -0
- data/MIT-LICENSE +22 -0
- data/README.md +103 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/features/rake.feature +27 -0
- data/features/step_definitions/rake_steps.rb +17 -0
- data/features/support/matchers.rb +35 -0
- data/features/support/rake/Rakefile +61 -0
- data/features/support/terminal.rb +107 -0
- data/hydraulic_brake.gemspec +102 -0
- data/lib/hydraulic_brake/backtrace.rb +108 -0
- data/lib/hydraulic_brake/configuration.rb +242 -0
- data/lib/hydraulic_brake/notice.rb +321 -0
- data/lib/hydraulic_brake/sender.rb +128 -0
- data/lib/hydraulic_brake/version.rb +5 -0
- data/lib/hydraulic_brake.rb +148 -0
- data/lib/hydraulic_brake_tasks.rb +63 -0
- data/resources/README.md +34 -0
- data/resources/ca-bundle.crt +3376 -0
- data/script/integration_test.rb +36 -0
- data/test/airbrake_2_3.xsd +88 -0
- data/test/backtrace_test.rb +162 -0
- data/test/configuration_test.rb +178 -0
- data/test/helper.rb +239 -0
- data/test/logger_test.rb +79 -0
- data/test/notice_test.rb +324 -0
- data/test/notifier_test.rb +220 -0
- data/test/recursion_test.rb +10 -0
- data/test/sender_test.rb +288 -0
- metadata +259 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
RAILS_ENV = "production"
|
7
|
+
RAILS_ROOT = FileUtils.pwd
|
8
|
+
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
|
9
|
+
|
10
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
require 'hydraulic_brake'
|
12
|
+
|
13
|
+
fail "Please supply an API Key as the first argument" if ARGV.empty?
|
14
|
+
|
15
|
+
host = ARGV[1]
|
16
|
+
|
17
|
+
secure = (ARGV[2] == "secure")
|
18
|
+
|
19
|
+
exception = begin
|
20
|
+
raise "Testing hydraulic brake notifier with secure = #{secure}. If you can see this, it works."
|
21
|
+
rescue => foo
|
22
|
+
foo
|
23
|
+
end
|
24
|
+
|
25
|
+
HydraulicBrake.configure do |config|
|
26
|
+
config.secure = secure
|
27
|
+
config.host = host
|
28
|
+
config.api_key = ARGV.first
|
29
|
+
end
|
30
|
+
puts "Configuration:"
|
31
|
+
HydraulicBrake.configuration.to_hash.each do |key, value|
|
32
|
+
puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
|
33
|
+
end
|
34
|
+
puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}"
|
35
|
+
HydraulicBrake.notify(exception)
|
36
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
|
4
|
+
<xs:element name="notice">
|
5
|
+
<xs:complexType>
|
6
|
+
<xs:all>
|
7
|
+
<xs:element name="api-key" type="xs:string"/>
|
8
|
+
<xs:element name="notifier" type="notifier"/>
|
9
|
+
<xs:element name="error" type="error"/>
|
10
|
+
<xs:element name="request" type="request" minOccurs="0"/>
|
11
|
+
<xs:element name="server-environment" type="serverEnvironment"/>
|
12
|
+
<xs:element name="current-user" type="current-user" minOccurs="0"/>
|
13
|
+
</xs:all>
|
14
|
+
<xs:attribute name="version" type="xs:string" use="required"/>
|
15
|
+
</xs:complexType>
|
16
|
+
</xs:element>
|
17
|
+
|
18
|
+
<xs:complexType name="notifier">
|
19
|
+
<xs:all>
|
20
|
+
<xs:element name="name" type="xs:string"/>
|
21
|
+
<xs:element name="version" type="xs:string"/>
|
22
|
+
<xs:element name="url" type="xs:string"/>
|
23
|
+
</xs:all>
|
24
|
+
</xs:complexType>
|
25
|
+
|
26
|
+
<xs:complexType name="error">
|
27
|
+
<xs:all>
|
28
|
+
<xs:element name="class" type="xs:string"/>
|
29
|
+
<xs:element name="message" type="xs:string" minOccurs="0"/>
|
30
|
+
<xs:element name="backtrace" type="backtrace"/>
|
31
|
+
</xs:all>
|
32
|
+
</xs:complexType>
|
33
|
+
|
34
|
+
<xs:complexType name="backtrace">
|
35
|
+
<xs:sequence>
|
36
|
+
<xs:element name="line" maxOccurs="unbounded" minOccurs="0">
|
37
|
+
<xs:complexType>
|
38
|
+
<xs:attribute name="file" type="xs:string" use="required"/>
|
39
|
+
<xs:attribute name="number" type="xs:string" use="required"/>
|
40
|
+
<xs:attribute name="method" type="xs:string" use="optional"/>
|
41
|
+
</xs:complexType>
|
42
|
+
</xs:element>
|
43
|
+
</xs:sequence>
|
44
|
+
</xs:complexType>
|
45
|
+
|
46
|
+
<xs:complexType name="request">
|
47
|
+
<xs:all>
|
48
|
+
<xs:element name="url" type="xs:string"/>
|
49
|
+
<xs:element name="component" type="xs:string"/>
|
50
|
+
<xs:element name="action" type="xs:string" minOccurs="0"/>
|
51
|
+
<xs:element name="params" type="varList" minOccurs="0"/>
|
52
|
+
<xs:element name="session" type="varList" minOccurs="0"/>
|
53
|
+
<xs:element name="cgi-data" type="varList" minOccurs="0"/>
|
54
|
+
</xs:all>
|
55
|
+
</xs:complexType>
|
56
|
+
|
57
|
+
<xs:complexType name="varList">
|
58
|
+
<xs:sequence>
|
59
|
+
<xs:element name="var" type="var" maxOccurs="unbounded"/>
|
60
|
+
</xs:sequence>
|
61
|
+
</xs:complexType>
|
62
|
+
|
63
|
+
<xs:complexType name="var" mixed="true">
|
64
|
+
<xs:sequence>
|
65
|
+
<xs:element name="var" type="var" minOccurs="0" maxOccurs="unbounded"/>
|
66
|
+
</xs:sequence>
|
67
|
+
<xs:attribute name="key" type="xs:string" use="required"/>
|
68
|
+
</xs:complexType>
|
69
|
+
|
70
|
+
<xs:complexType name="serverEnvironment">
|
71
|
+
<xs:sequence>
|
72
|
+
<xs:element name="project-root" type="xs:string" minOccurs="0"/>
|
73
|
+
<xs:element name="environment-name" type="xs:string"/>
|
74
|
+
<xs:element name="app-version" type="xs:string" minOccurs="0"/>
|
75
|
+
<xs:element name="hostname" type="xs:string" minOccurs="0"/>
|
76
|
+
</xs:sequence>
|
77
|
+
</xs:complexType>
|
78
|
+
|
79
|
+
<xs:complexType name="current-user">
|
80
|
+
<xs:all>
|
81
|
+
<xs:element name="id" type="xs:string"/>
|
82
|
+
<xs:element name="name" type="xs:string" minOccurs="0"/>
|
83
|
+
<xs:element name="email" type="xs:string" minOccurs="0"/>
|
84
|
+
<xs:element name="username" type="xs:string" minOccurs="0"/>
|
85
|
+
</xs:all>
|
86
|
+
</xs:complexType>
|
87
|
+
|
88
|
+
</xs:schema>
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class BacktraceTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "parse a backtrace into lines" do
|
6
|
+
array = [
|
7
|
+
"app/models/user.rb:13:in `magic'",
|
8
|
+
"app/controllers/users_controller.rb:8:in `index'"
|
9
|
+
]
|
10
|
+
|
11
|
+
backtrace = HydraulicBrake::Backtrace.parse(array)
|
12
|
+
|
13
|
+
line = backtrace.lines.first
|
14
|
+
assert_equal '13', line.number
|
15
|
+
assert_equal 'app/models/user.rb', line.file
|
16
|
+
assert_equal 'magic', line.method
|
17
|
+
|
18
|
+
line = backtrace.lines.last
|
19
|
+
assert_equal '8', line.number
|
20
|
+
assert_equal 'app/controllers/users_controller.rb', line.file
|
21
|
+
assert_equal 'index', line.method
|
22
|
+
end
|
23
|
+
|
24
|
+
should "parse a windows backtrace into lines" do
|
25
|
+
array = [
|
26
|
+
"C:/Program Files/Server/app/models/user.rb:13:in `magic'",
|
27
|
+
"C:/Program Files/Server/app/controllers/users_controller.rb:8:in `index'"
|
28
|
+
]
|
29
|
+
|
30
|
+
backtrace = HydraulicBrake::Backtrace.parse(array)
|
31
|
+
|
32
|
+
line = backtrace.lines.first
|
33
|
+
assert_equal '13', line.number
|
34
|
+
assert_equal 'C:/Program Files/Server/app/models/user.rb', line.file
|
35
|
+
assert_equal 'magic', line.method
|
36
|
+
|
37
|
+
line = backtrace.lines.last
|
38
|
+
assert_equal '8', line.number
|
39
|
+
assert_equal 'C:/Program Files/Server/app/controllers/users_controller.rb', line.file
|
40
|
+
assert_equal 'index', line.method
|
41
|
+
end
|
42
|
+
|
43
|
+
should "be equal with equal lines" do
|
44
|
+
one = build_backtrace_array
|
45
|
+
two = one.dup
|
46
|
+
|
47
|
+
assert_equal HydraulicBrake::Backtrace.parse(one), HydraulicBrake::Backtrace.parse(two)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "parse massive one-line exceptions into multiple lines" do
|
51
|
+
original_backtrace = HydraulicBrake::Backtrace.
|
52
|
+
parse(["one:1:in `one'\n two:2:in `two'\n three:3:in `three`"])
|
53
|
+
expected_backtrace = HydraulicBrake::Backtrace.
|
54
|
+
parse(["one:1:in `one'", "two:2:in `two'", "three:3:in `three`"])
|
55
|
+
|
56
|
+
assert_equal expected_backtrace, original_backtrace
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with a project root" do
|
60
|
+
setup do
|
61
|
+
@project_root = '/some/path'
|
62
|
+
HydraulicBrake.configure {|config| config.project_root = @project_root }
|
63
|
+
end
|
64
|
+
|
65
|
+
teardown do
|
66
|
+
reset_config
|
67
|
+
end
|
68
|
+
|
69
|
+
should "filter out the project root" do
|
70
|
+
backtrace_with_root = HydraulicBrake::Backtrace.parse(
|
71
|
+
["#{@project_root}/app/models/user.rb:7:in `latest'",
|
72
|
+
"#{@project_root}/app/controllers/users_controller.rb:13:in `index'",
|
73
|
+
"/lib/something.rb:41:in `open'"],
|
74
|
+
:filters => default_filters)
|
75
|
+
backtrace_without_root = HydraulicBrake::Backtrace.parse(
|
76
|
+
["[PROJECT_ROOT]/app/models/user.rb:7:in `latest'",
|
77
|
+
"[PROJECT_ROOT]/app/controllers/users_controller.rb:13:in `index'",
|
78
|
+
"/lib/something.rb:41:in `open'"])
|
79
|
+
|
80
|
+
assert_equal backtrace_without_root, backtrace_with_root
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with a project root equals to a part of file name" do
|
85
|
+
setup do
|
86
|
+
# Heroku-like
|
87
|
+
@project_root = '/app'
|
88
|
+
HydraulicBrake.configure {|config| config.project_root = @project_root }
|
89
|
+
end
|
90
|
+
|
91
|
+
teardown do
|
92
|
+
reset_config
|
93
|
+
end
|
94
|
+
|
95
|
+
should "filter out the project root" do
|
96
|
+
backtrace_with_root = HydraulicBrake::Backtrace.parse(
|
97
|
+
["#{@project_root}/app/models/user.rb:7:in `latest'",
|
98
|
+
"#{@project_root}/app/controllers/users_controller.rb:13:in `index'",
|
99
|
+
"/lib/something.rb:41:in `open'"],
|
100
|
+
:filters => default_filters)
|
101
|
+
backtrace_without_root = HydraulicBrake::Backtrace.parse(
|
102
|
+
["[PROJECT_ROOT]/app/models/user.rb:7:in `latest'",
|
103
|
+
"[PROJECT_ROOT]/app/controllers/users_controller.rb:13:in `index'",
|
104
|
+
"/lib/something.rb:41:in `open'"])
|
105
|
+
|
106
|
+
assert_equal backtrace_without_root, backtrace_with_root
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "with a blank project root" do
|
111
|
+
setup do
|
112
|
+
HydraulicBrake.configure {|config| config.project_root = '' }
|
113
|
+
end
|
114
|
+
|
115
|
+
teardown do
|
116
|
+
reset_config
|
117
|
+
end
|
118
|
+
|
119
|
+
should "not filter line numbers with respect to any project root" do
|
120
|
+
backtrace = ["/app/models/user.rb:7:in `latest'",
|
121
|
+
"/app/controllers/users_controller.rb:13:in `index'",
|
122
|
+
"/lib/something.rb:41:in `open'"]
|
123
|
+
|
124
|
+
backtrace_with_root =
|
125
|
+
HydraulicBrake::Backtrace.parse(backtrace, :filters => default_filters)
|
126
|
+
|
127
|
+
backtrace_without_root =
|
128
|
+
HydraulicBrake::Backtrace.parse(backtrace)
|
129
|
+
|
130
|
+
assert_equal backtrace_without_root, backtrace_with_root
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
should "remove notifier trace" do
|
135
|
+
inside_notifier = ['lib/hydraulic_brake.rb:13:in `voodoo`']
|
136
|
+
outside_notifier = ['users_controller:8:in `index`']
|
137
|
+
|
138
|
+
without_inside = HydraulicBrake::Backtrace.parse(outside_notifier)
|
139
|
+
with_inside = HydraulicBrake::Backtrace.parse(inside_notifier + outside_notifier,
|
140
|
+
:filters => default_filters)
|
141
|
+
|
142
|
+
assert_equal without_inside, with_inside
|
143
|
+
end
|
144
|
+
|
145
|
+
should "run filters on the backtrace" do
|
146
|
+
filters = [lambda { |line| line.sub('foo', 'bar') }]
|
147
|
+
input = HydraulicBrake::Backtrace.parse(["foo:13:in `one'", "baz:14:in `two'"],
|
148
|
+
:filters => filters)
|
149
|
+
expected = HydraulicBrake::Backtrace.parse(["bar:13:in `one'", "baz:14:in `two'"])
|
150
|
+
assert_equal expected, input
|
151
|
+
end
|
152
|
+
|
153
|
+
def build_backtrace_array
|
154
|
+
["app/models/user.rb:13:in `magic'",
|
155
|
+
"app/controllers/users_controller.rb:8:in `index'"]
|
156
|
+
end
|
157
|
+
|
158
|
+
def default_filters
|
159
|
+
HydraulicBrake::Configuration::DEFAULT_BACKTRACE_FILTERS
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class ConfigurationTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include DefinesConstants
|
6
|
+
|
7
|
+
should "provide default values" do
|
8
|
+
assert_config_default :proxy_host, nil
|
9
|
+
assert_config_default :proxy_port, nil
|
10
|
+
assert_config_default :proxy_user, nil
|
11
|
+
assert_config_default :proxy_pass, nil
|
12
|
+
assert_config_default :project_root, nil
|
13
|
+
assert_config_default :environment_name, nil
|
14
|
+
assert_config_default :logger, nil
|
15
|
+
assert_config_default :notifier_version, HydraulicBrake::VERSION
|
16
|
+
assert_config_default :notifier_name, 'HydraulicBrake Notifier'
|
17
|
+
assert_config_default :notifier_url, 'https://github.com/stevecrozz/hydraulic_brake'
|
18
|
+
assert_config_default :secure, false
|
19
|
+
assert_config_default :host, 'api.airbrake.io'
|
20
|
+
assert_config_default :http_open_timeout, 2
|
21
|
+
assert_config_default :http_read_timeout, 5
|
22
|
+
assert_config_default :params_filters,
|
23
|
+
HydraulicBrake::Configuration::DEFAULT_PARAMS_FILTERS
|
24
|
+
assert_config_default :backtrace_filters,
|
25
|
+
HydraulicBrake::Configuration::DEFAULT_BACKTRACE_FILTERS
|
26
|
+
assert_config_default :rake_environment_filters, []
|
27
|
+
assert_config_default :development_lookup, true
|
28
|
+
assert_config_default :framework, 'Standalone'
|
29
|
+
end
|
30
|
+
|
31
|
+
should "provide default values for secure connections" do
|
32
|
+
config = HydraulicBrake::Configuration.new
|
33
|
+
config.secure = true
|
34
|
+
assert_equal 443, config.port
|
35
|
+
assert_equal 'https', config.protocol
|
36
|
+
end
|
37
|
+
|
38
|
+
should "provide default values for insecure connections" do
|
39
|
+
config = HydraulicBrake::Configuration.new
|
40
|
+
config.secure = false
|
41
|
+
assert_equal 80, config.port
|
42
|
+
assert_equal 'http', config.protocol
|
43
|
+
end
|
44
|
+
|
45
|
+
should "not cache inferred ports" do
|
46
|
+
config = HydraulicBrake::Configuration.new
|
47
|
+
config.secure = false
|
48
|
+
config.port
|
49
|
+
config.secure = true
|
50
|
+
assert_equal 443, config.port
|
51
|
+
end
|
52
|
+
|
53
|
+
should "allow values to be overwritten" do
|
54
|
+
assert_config_overridable :proxy_host
|
55
|
+
assert_config_overridable :proxy_port
|
56
|
+
assert_config_overridable :proxy_user
|
57
|
+
assert_config_overridable :proxy_pass
|
58
|
+
assert_config_overridable :secure
|
59
|
+
assert_config_overridable :host
|
60
|
+
assert_config_overridable :port
|
61
|
+
assert_config_overridable :http_open_timeout
|
62
|
+
assert_config_overridable :http_read_timeout
|
63
|
+
assert_config_overridable :project_root
|
64
|
+
assert_config_overridable :notifier_version
|
65
|
+
assert_config_overridable :notifier_name
|
66
|
+
assert_config_overridable :notifier_url
|
67
|
+
assert_config_overridable :environment_name
|
68
|
+
assert_config_overridable :development_lookup
|
69
|
+
assert_config_overridable :logger
|
70
|
+
end
|
71
|
+
|
72
|
+
should "have an api key" do
|
73
|
+
assert_config_overridable :api_key
|
74
|
+
end
|
75
|
+
|
76
|
+
should "act like a hash" do
|
77
|
+
config = HydraulicBrake::Configuration.new
|
78
|
+
hash = config.to_hash
|
79
|
+
[:api_key, :backtrace_filters, :development_environments,
|
80
|
+
:environment_name, :host, :http_open_timeout,
|
81
|
+
:http_read_timeout,
|
82
|
+
:notifier_name, :notifier_url, :notifier_version, :params_filters,
|
83
|
+
:project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
|
84
|
+
:proxy_user, :secure, :development_lookup].each do |option|
|
85
|
+
assert_equal config[option], hash[option], "Wrong value for #{option}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
should "be mergable" do
|
90
|
+
config = HydraulicBrake::Configuration.new
|
91
|
+
hash = config.to_hash
|
92
|
+
assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value')
|
93
|
+
end
|
94
|
+
|
95
|
+
should "allow param filters to be appended" do
|
96
|
+
assert_appends_value :params_filters
|
97
|
+
end
|
98
|
+
|
99
|
+
should "allow rake environment filters to be appended" do
|
100
|
+
assert_appends_value :rake_environment_filters
|
101
|
+
end
|
102
|
+
|
103
|
+
should "allow backtrace filters to be appended" do
|
104
|
+
assert_appends_value(:backtrace_filters) do |config|
|
105
|
+
new_filter = lambda {}
|
106
|
+
config.filter_backtrace(&new_filter)
|
107
|
+
new_filter
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
should "use development and test as development environments by default" do
|
112
|
+
config = HydraulicBrake::Configuration.new
|
113
|
+
assert_same_elements %w(development test cucumber), config.development_environments
|
114
|
+
end
|
115
|
+
|
116
|
+
should "be public in a public environment" do
|
117
|
+
config = HydraulicBrake::Configuration.new
|
118
|
+
config.development_environments = %w(development)
|
119
|
+
config.environment_name = 'production'
|
120
|
+
assert config.public?
|
121
|
+
end
|
122
|
+
|
123
|
+
should "not be public in a development environment" do
|
124
|
+
config = HydraulicBrake::Configuration.new
|
125
|
+
config.development_environments = %w(staging)
|
126
|
+
config.environment_name = 'staging'
|
127
|
+
assert !config.public?
|
128
|
+
end
|
129
|
+
|
130
|
+
should "be public without an environment name" do
|
131
|
+
config = HydraulicBrake::Configuration.new
|
132
|
+
assert config.public?
|
133
|
+
end
|
134
|
+
|
135
|
+
should "use the assigned logger if set" do
|
136
|
+
config = HydraulicBrake::Configuration.new
|
137
|
+
config.logger = "CUSTOM LOGGER"
|
138
|
+
assert_equal "CUSTOM LOGGER", config.logger
|
139
|
+
end
|
140
|
+
|
141
|
+
should 'give a new instance if non defined' do
|
142
|
+
HydraulicBrake.configuration = nil
|
143
|
+
assert_kind_of HydraulicBrake::Configuration, HydraulicBrake.configuration
|
144
|
+
end
|
145
|
+
|
146
|
+
def assert_config_default(option, default_value, config = nil)
|
147
|
+
config ||= HydraulicBrake::Configuration.new
|
148
|
+
assert_equal default_value, config.send(option)
|
149
|
+
end
|
150
|
+
|
151
|
+
def assert_config_overridable(option, value = 'a value')
|
152
|
+
config = HydraulicBrake::Configuration.new
|
153
|
+
config.send(:"#{option}=", value)
|
154
|
+
assert_equal value, config.send(option)
|
155
|
+
end
|
156
|
+
|
157
|
+
def assert_appends_value(option, &block)
|
158
|
+
config = HydraulicBrake::Configuration.new
|
159
|
+
original_values = config.send(option).dup
|
160
|
+
block ||= lambda do |config|
|
161
|
+
new_value = 'hello'
|
162
|
+
config.send(option) << new_value
|
163
|
+
new_value
|
164
|
+
end
|
165
|
+
new_value = block.call(config)
|
166
|
+
assert_same_elements original_values + [new_value], config.send(option)
|
167
|
+
end
|
168
|
+
|
169
|
+
def assert_replaces(option, setter)
|
170
|
+
config = HydraulicBrake::Configuration.new
|
171
|
+
new_value = 'hello'
|
172
|
+
config.send(setter, [new_value])
|
173
|
+
assert_equal [new_value], config.send(option)
|
174
|
+
config.send(setter, new_value)
|
175
|
+
assert_equal [new_value], config.send(option)
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
7
|
+
|
8
|
+
require 'shoulda'
|
9
|
+
require 'nokogiri'
|
10
|
+
require 'bourne'
|
11
|
+
require "hydraulic_brake"
|
12
|
+
|
13
|
+
begin require 'redgreen'; rescue LoadError; end
|
14
|
+
|
15
|
+
module TestMethods
|
16
|
+
def rescue_action e
|
17
|
+
raise e
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_raise
|
21
|
+
raise "HydraulicBrake"
|
22
|
+
end
|
23
|
+
|
24
|
+
def do_not_raise
|
25
|
+
render :text => "Success"
|
26
|
+
end
|
27
|
+
|
28
|
+
def manual_notify
|
29
|
+
notify_airbrake(Exception.new)
|
30
|
+
render :text => "Success"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Test::Unit::TestCase
|
35
|
+
def request(action = nil, method = :get, user_agent = nil, params = {})
|
36
|
+
@request = ActionController::TestRequest.new
|
37
|
+
@request.action = action ? action.to_s : ""
|
38
|
+
|
39
|
+
if user_agent
|
40
|
+
if @request.respond_to?(:user_agent=)
|
41
|
+
@request.user_agent = user_agent
|
42
|
+
else
|
43
|
+
@request.env["HTTP_USER_AGENT"] = user_agent
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@request.query_parameters = @request.query_parameters.merge(params)
|
47
|
+
@response = ActionController::TestResponse.new
|
48
|
+
@controller.process(@request, @response)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Borrowed from ActiveSupport 2.3.2
|
52
|
+
def assert_difference(expression, difference = 1, message = nil, &block)
|
53
|
+
b = block.send(:binding)
|
54
|
+
exps = AsArray.wrap(expression)
|
55
|
+
before = exps.map { |e| eval(e, b) }
|
56
|
+
|
57
|
+
yield
|
58
|
+
|
59
|
+
exps.each_with_index do |e, i|
|
60
|
+
error = "#{e.inspect} didn't change by #{difference}"
|
61
|
+
error = "#{message}.\n#{error}" if message
|
62
|
+
assert_equal(before[i] + difference, eval(e, b), error)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def assert_no_difference(expression, message = nil, &block)
|
67
|
+
assert_difference expression, 0, message, &block
|
68
|
+
end
|
69
|
+
|
70
|
+
def stub_sender
|
71
|
+
stub('sender', :send_to_airbrake => nil)
|
72
|
+
end
|
73
|
+
|
74
|
+
def stub_sender!
|
75
|
+
HydraulicBrake.sender = stub_sender
|
76
|
+
end
|
77
|
+
|
78
|
+
def stub_notice
|
79
|
+
stub('notice', :to_xml => 'some yaml')
|
80
|
+
end
|
81
|
+
|
82
|
+
def stub_notice!
|
83
|
+
stub_notice.tap do |notice|
|
84
|
+
HydraulicBrake::Notice.stubs(:new => notice)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_dummy
|
89
|
+
HydraulicBrake::DummySender.new
|
90
|
+
end
|
91
|
+
|
92
|
+
def reset_config
|
93
|
+
HydraulicBrake.configuration = nil
|
94
|
+
HydraulicBrake.configure do |config|
|
95
|
+
config.api_key = 'abc123'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def clear_backtrace_filters
|
100
|
+
HydraulicBrake.configuration.backtrace_filters.clear
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_exception(opts = {})
|
104
|
+
backtrace = ["hydraulic_brake/test/helper.rb:132:in `build_exception'",
|
105
|
+
"hydraulic_brake/test/backtrace.rb:4:in `build_notice_data'",
|
106
|
+
"/var/lib/gems/1.8/gems/hydraulic_brake-2.4.5/rails/init.rb:2:in `send_exception'"]
|
107
|
+
opts = {:backtrace => backtrace}.merge(opts)
|
108
|
+
BacktracedException.new(opts)
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_notice_data(exception = nil)
|
112
|
+
exception ||= build_exception
|
113
|
+
{
|
114
|
+
:api_key => 'abc123',
|
115
|
+
:error_class => exception.class.name,
|
116
|
+
:error_message => "#{exception.class.name}: #{exception.message}",
|
117
|
+
:backtrace => exception.backtrace,
|
118
|
+
:environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
|
119
|
+
:request => {
|
120
|
+
:params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
|
121
|
+
:rails_root => '/path/to/application',
|
122
|
+
:url => "http://test.host/users/1"
|
123
|
+
},
|
124
|
+
:session => {
|
125
|
+
:key => '123abc',
|
126
|
+
:data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
|
127
|
+
}
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
def assert_caught_and_sent
|
132
|
+
assert !HydraulicBrake.sender.collected.empty?
|
133
|
+
end
|
134
|
+
|
135
|
+
def assert_caught_and_not_sent
|
136
|
+
assert HydraulicBrake.sender.collected.empty?
|
137
|
+
end
|
138
|
+
|
139
|
+
def assert_array_starts_with(expected, actual)
|
140
|
+
assert_respond_to actual, :to_ary
|
141
|
+
array = actual.to_ary.reverse
|
142
|
+
expected.reverse.each_with_index do |value, i|
|
143
|
+
assert_equal value, array[i]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def assert_valid_node(document, xpath, content)
|
148
|
+
nodes = document.xpath(xpath)
|
149
|
+
assert nodes.any?{|node| node.content == content },
|
150
|
+
"Expected xpath #{xpath} to have content #{content}, " +
|
151
|
+
"but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
|
152
|
+
"Document:\n#{document.to_s}"
|
153
|
+
end
|
154
|
+
|
155
|
+
def assert_logged(expected)
|
156
|
+
assert_received(HydraulicBrake, :write_verbose_log) do |expect|
|
157
|
+
expect.with {|actual| actual =~ expected }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def assert_not_logged(expected)
|
162
|
+
assert_received(HydraulicBrake, :write_verbose_log) do |expect|
|
163
|
+
expect.with {|actual| actual =~ expected }.never
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
module DefinesConstants
|
171
|
+
def setup
|
172
|
+
@defined_constants = []
|
173
|
+
end
|
174
|
+
|
175
|
+
def teardown
|
176
|
+
@defined_constants.each do |constant|
|
177
|
+
Object.__send__(:remove_const, constant)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def define_constant(name, value)
|
182
|
+
Object.const_set(name, value)
|
183
|
+
@defined_constants << name
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Also stolen from AS 2.3.2
|
188
|
+
class AsArray
|
189
|
+
# Wraps the object in an Array unless it's an Array. Converts the
|
190
|
+
# object to an Array using #to_ary if it implements that.
|
191
|
+
def self.wrap(object)
|
192
|
+
case object
|
193
|
+
when nil
|
194
|
+
[]
|
195
|
+
when self
|
196
|
+
object
|
197
|
+
else
|
198
|
+
if object.respond_to?(:to_ary)
|
199
|
+
object.to_ary
|
200
|
+
else
|
201
|
+
[object]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
class CollectingSender
|
209
|
+
attr_reader :collected
|
210
|
+
|
211
|
+
def initialize
|
212
|
+
@collected = []
|
213
|
+
end
|
214
|
+
|
215
|
+
def send_to_airbrake(data)
|
216
|
+
@collected << data
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
class FakeLogger
|
221
|
+
def info(*args); end
|
222
|
+
def debug(*args); end
|
223
|
+
def warn(*args); end
|
224
|
+
def error(*args); end
|
225
|
+
def fatal(*args); end
|
226
|
+
end
|
227
|
+
|
228
|
+
class BacktracedException < Exception
|
229
|
+
attr_accessor :backtrace
|
230
|
+
def initialize(opts)
|
231
|
+
@backtrace = opts[:backtrace]
|
232
|
+
end
|
233
|
+
def set_backtrace(bt)
|
234
|
+
@backtrace = bt
|
235
|
+
end
|
236
|
+
def message
|
237
|
+
"Something went wrong. Did you press the red button?"
|
238
|
+
end
|
239
|
+
end
|