gossip 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/LICENSE.txt +34 -0
- data/Manifest.txt +62 -0
- data/README.txt +6 -0
- data/Rakefile +137 -0
- data/examples/all-config-file-choices.yml +36 -0
- data/lib/gossip.rb +32 -0
- data/lib/gossip/command.rb +122 -0
- data/lib/gossip/cronies/campfire.rb +72 -0
- data/lib/gossip/cronies/jabber.rb +66 -0
- data/lib/gossip/cronies/smtp.rb +121 -0
- data/lib/gossip/cronies/stdout.rb +24 -0
- data/lib/gossip/cronies/trac.rb +82 -0
- data/lib/gossip/cronies/twitter.rb +50 -0
- data/lib/gossip/crony.rb +102 -0
- data/lib/gossip/multi-exceptions.rb +47 -0
- data/lib/gossip/preteen.rb +86 -0
- data/lib/gossip/site-config.rb +94 -0
- data/lib/gossip/social-universe.rb +18 -0
- data/lib/gossip/version.rb +8 -0
- data/pages/classes.html +58 -0
- data/pages/cronies.html +256 -0
- data/pages/css/LICENSE.txt +1 -0
- data/pages/css/Thumbs.db +0 -0
- data/pages/css/bg2.gif +0 -0
- data/pages/css/gossip5-header-flip.jpg +0 -0
- data/pages/css/left.gif +0 -0
- data/pages/css/left_on.gif +0 -0
- data/pages/css/main.css +242 -0
- data/pages/css/right.gif +0 -0
- data/pages/css/right_on.gif +0 -0
- data/pages/css/tvline.gif +0 -0
- data/pages/images/campfire.png +0 -0
- data/pages/images/classes.png +0 -0
- data/pages/images/deployment.png +0 -0
- data/pages/images/jabber-big.png +0 -0
- data/pages/images/jabber.png +0 -0
- data/pages/images/trac-bigger.png +0 -0
- data/pages/images/trac-detail.png +0 -0
- data/pages/images/twitter.png +0 -0
- data/pages/index.html +45 -0
- data/pages/installation.html +95 -0
- data/pages/scripts.html +166 -0
- data/pages/src/classes.graffle +0 -0
- data/pages/starting-to-use.html +200 -0
- data/pages/writing-new-scripts.html +38 -0
- data/scripts/fanout +64 -0
- data/scripts/svntell +71 -0
- data/scripts/watchdog +86 -0
- data/setup.rb +1585 -0
- data/test/script/fanout-slowtests.rb +40 -0
- data/test/script/svntell-slowtests.rb +40 -0
- data/test/script/util.rb +22 -0
- data/test/script/watchdog-slowtests.rb +56 -0
- data/test/unit/command-crony-interaction-tests.rb +116 -0
- data/test/unit/command-tests.rb +119 -0
- data/test/unit/crony-tests.rb +46 -0
- data/test/unit/multi-exception-tests.rb +70 -0
- data/test/unit/preteen-tests.rb +81 -0
- data/test/util/bff.rb +45 -0
- data/test/util/doghouse.rb +42 -0
- data/test/util/silly-little-test-program.rb +6 -0
- metadata +181 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-25.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 's4t-utils'
|
8
|
+
S4tUtils.set_test_paths(__FILE__)
|
9
|
+
|
10
|
+
require 'test/script/util'
|
11
|
+
|
12
|
+
unless S4tUtils.on_windows?
|
13
|
+
class TestFanoutCommandExecution < Test::Unit::TestCase
|
14
|
+
def test_scandal_and_details
|
15
|
+
as_script_test('.fanout.yml') do
|
16
|
+
result = `echo "some details" | ruby fanout --details arg "another arg"`
|
17
|
+
lines = result.split("\n")
|
18
|
+
assert_match(/arg another arg/, lines.first)
|
19
|
+
assert_match(/some details/, lines.last)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_scandal_alone
|
24
|
+
as_script_test('.fanout.yml') do
|
25
|
+
result = `ruby fanout --no-det arg "another arg"`
|
26
|
+
lines = result.split("\n")
|
27
|
+
assert_equal(1, lines.length)
|
28
|
+
assert_match(/arg another arg/, lines.first)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_details_are_default
|
33
|
+
as_script_test('.fanout.yml') do
|
34
|
+
results = `echo sloop | ruby fanout arg "another arg"`
|
35
|
+
assert_match(/sloop/, results)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-27.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
#!/usr/bin/env ruby
|
7
|
+
#
|
8
|
+
# Created by Brian Marick on 2007-09-25.
|
9
|
+
# Copyright (c) 2007. All rights reserved.
|
10
|
+
|
11
|
+
require 'test/unit'
|
12
|
+
require 's4t-utils'
|
13
|
+
S4tUtils.set_test_paths(__FILE__)
|
14
|
+
|
15
|
+
require 'test/script/util'
|
16
|
+
|
17
|
+
unless S4tUtils.on_windows?
|
18
|
+
class TestFanoutCommandExecution < Test::Unit::TestCase
|
19
|
+
def test_revision_is_required
|
20
|
+
as_script_test('.svntell.yml') do
|
21
|
+
result = `ruby svntell --repository /svn 2>&1`
|
22
|
+
assert_match(/must choose a revision/, result)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_repository_is_required
|
27
|
+
as_script_test('.svntell.yml') do
|
28
|
+
result = `ruby svntell --revision 5 foo 2>&1`
|
29
|
+
assert_match(/must choose a repository/, result)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_svnlook_must_exist
|
34
|
+
as_script_test('.svntell.yml') do
|
35
|
+
result = `ruby svntell --svnlook /foo/bar --repository /svn --revision 5 foo 2>&1`
|
36
|
+
assert_match(%r{svnlook path '/foo/bar' does not exist.}, result)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/test/script/util.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-25.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
class Test::Unit::TestCase
|
8
|
+
include S4tUtils
|
9
|
+
|
10
|
+
def as_script_test(config_name)
|
11
|
+
yaml = %q{
|
12
|
+
standard-output: true
|
13
|
+
}
|
14
|
+
|
15
|
+
Dir.chdir(PACKAGE_ROOT + "/scripts") do
|
16
|
+
with_local_config_file(config_name, yaml) do
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's4t-utils'
|
3
|
+
include S4tUtils
|
4
|
+
set_test_paths(__FILE__)
|
5
|
+
|
6
|
+
require 'test/script/util'
|
7
|
+
load "#{PACKAGE_ROOT}/scripts/watchdog"
|
8
|
+
|
9
|
+
class TestWatchdogCommand < Test::Unit::TestCase
|
10
|
+
include Gossip
|
11
|
+
|
12
|
+
class RandomWatchdogCommand < Watchdog
|
13
|
+
# Erase behaviors of no interest
|
14
|
+
def initialize; end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def test_command_name_ignores_ruby
|
19
|
+
dog = RandomWatchdogCommand.new
|
20
|
+
assert_equal('echo', dog.command_name(['echo', 'foo']))
|
21
|
+
assert_equal('echo.rb', dog.command_name(['ruby', 'echo.rb', 'foo']))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_command_name_is_just_basename
|
25
|
+
dog = RandomWatchdogCommand.new
|
26
|
+
assert_equal('echo.rb', dog.command_name(['ruby', '/usr/bin/echo.rb', 'foo']))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_timer
|
30
|
+
duration, result = RandomWatchdogCommand.new.time {
|
31
|
+
sleep 2
|
32
|
+
5
|
33
|
+
}
|
34
|
+
# Rough check because time is inaccurate.
|
35
|
+
assert_true(duration >= 1.5)
|
36
|
+
assert_equal(5, result)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
unless S4tUtils.on_windows?
|
43
|
+
class TestWatchdogCommandExecution < Test::Unit::TestCase
|
44
|
+
def test_command_line_only
|
45
|
+
as_script_test('.watchdog.yml') do
|
46
|
+
actual_string = `ruby watchdog ruby ../test/util/silly-little-test-program.rb 1 2`
|
47
|
+
assert_match(/Program silly-little-test-program.rb finished/, actual_string)
|
48
|
+
assert_match(/Duration: /, actual_string)
|
49
|
+
assert_match(%r{Command: ruby ../test/util/silly-little-test-program.rb 1 2}, actual_string)
|
50
|
+
|
51
|
+
assert_match(/I mostly write to standard output./, actual_string)
|
52
|
+
assert_match(/I also write to standard error./, actual_string)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-17.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 's4t-utils'
|
8
|
+
include S4tUtils
|
9
|
+
set_test_paths(__FILE__)
|
10
|
+
|
11
|
+
|
12
|
+
require 'gossip'
|
13
|
+
|
14
|
+
class ChoicesTests < Test::Unit::TestCase
|
15
|
+
include Gossip
|
16
|
+
|
17
|
+
def test_that_crony_presence_sets_switch
|
18
|
+
# Note that the cronymaker key and Crony name must be the same.
|
19
|
+
# That duplication is an artifact of trying to make the declarations
|
20
|
+
# in the scripts (like watchdog.rb) look nice.
|
21
|
+
crony_maker = { :winner => proc {@winner = Exhibitionist.named(:winner)},
|
22
|
+
:loser => proc {@loser = Exhibitionist.named(:loser)} }
|
23
|
+
|
24
|
+
sophie = Preteen.new(crony_maker, [:winner], [:loser])
|
25
|
+
cmd = SomeRandomCommand.new(sophie)
|
26
|
+
|
27
|
+
# Switch is initialized, with default value
|
28
|
+
assert_equal(true, cmd.user_choices[:winner])
|
29
|
+
assert_equal(false, cmd.user_choices[:loser])
|
30
|
+
|
31
|
+
# Shorthand for the default value
|
32
|
+
assert_true(@winner.is_bff_by_default?)
|
33
|
+
assert_false(@loser.is_bff_by_default?)
|
34
|
+
|
35
|
+
# Cronies share user choices with command.
|
36
|
+
assert_equal(@winner.user_choices, cmd.user_choices)
|
37
|
+
assert_equal(@loser.user_choices, cmd.user_choices)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_how_command_initializes_a_crony
|
41
|
+
crony_maker = { :bff => proc {Exhibitionist.named(:bff)}}
|
42
|
+
sophie = Preteen.new(crony_maker, [:bff], [])
|
43
|
+
SomeRandomCommand.new(sophie).execute
|
44
|
+
assert_equal(['command_line_description()', # This is the crony's only part in determining whether it's called by default
|
45
|
+
'add_configuration_choices()',
|
46
|
+
# Command line and config files are read here
|
47
|
+
'user_choices=()', # Give crony access to user choices
|
48
|
+
'postprocess_user_choices()',
|
49
|
+
# Can now execute.
|
50
|
+
'hear("boyfriend!", "Joshua")'
|
51
|
+
], sophie.cronies[0].logged)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
class Exhibitionist < Crony
|
56
|
+
attr_reader :logged, :user_choices, :symbol
|
57
|
+
|
58
|
+
def name; symbol.to_s; end
|
59
|
+
|
60
|
+
def self.named(sym); new(sym); end
|
61
|
+
def initialize(sym)
|
62
|
+
@symbol = sym
|
63
|
+
@logged = []
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
def user_choices=(value)
|
68
|
+
log("user_choices=")
|
69
|
+
@user_choices = value
|
70
|
+
end
|
71
|
+
|
72
|
+
def command_line_description()
|
73
|
+
log("command_line_description")
|
74
|
+
['-e', "--exhibitionist", "Defaults to #{is_bff_by_default?}."]
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_configuration_choices(builder)
|
78
|
+
log("add_configuration_choices");
|
79
|
+
end
|
80
|
+
def postprocess_user_choices;
|
81
|
+
log("postprocess_user_choices")
|
82
|
+
end
|
83
|
+
|
84
|
+
def hear(*args)
|
85
|
+
log('hear', *args)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def log(message, *args); @logged << how_called(message, *args); end
|
91
|
+
|
92
|
+
def how_called(message, *args)
|
93
|
+
args = args.collect { |a| a.inspect }
|
94
|
+
"#{message}(" + args.join(", ") + ")"
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
class SomeRandomCommand < Gossip::GossipCommand
|
101
|
+
|
102
|
+
attr_reader :user_choices
|
103
|
+
|
104
|
+
def add_sources(builder)
|
105
|
+
# There must be at least a command line.
|
106
|
+
builder.add_source(CommandLineSource, :usage,
|
107
|
+
"Usage: ruby #{$0} [options] program args...")
|
108
|
+
end
|
109
|
+
|
110
|
+
def execute
|
111
|
+
preteen.tell_bffs("boyfriend!", "Joshua")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's4t-utils'
|
3
|
+
include S4tUtils
|
4
|
+
set_test_paths(__FILE__)
|
5
|
+
|
6
|
+
require 'gossip'
|
7
|
+
|
8
|
+
class CommandTests < Test::Unit::TestCase
|
9
|
+
include Gossip
|
10
|
+
|
11
|
+
class SomeRandomCommand < GossipCommand
|
12
|
+
def script_config_file; ".localrc"; end
|
13
|
+
def gossip_config_file; ".globalrc"; end
|
14
|
+
|
15
|
+
def usage; "Usage: ruby #{$0} [options] program args..."; end
|
16
|
+
def add_sources(builder)
|
17
|
+
builder.add_source(PosixCommandLineSource, :usage, *describe_all_but_options)
|
18
|
+
builder.add_source(YamlConfigFileSource, :from_file, ".sophie.yml")
|
19
|
+
builder.add_source(XmlConfigFileSource, :from_file, ".sophie.xml")
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute
|
23
|
+
preteen.tell_bffs("boyfriend!", "Joshua")
|
24
|
+
preteen.cronies.collect { |crony| crony.value }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup
|
29
|
+
crony_maker = {
|
30
|
+
:bff => proc {
|
31
|
+
require PACKAGE_ROOT + '/test/util/bff'
|
32
|
+
OneTestCrony.new(:default_format_string => "scandal: %s, details: %s")
|
33
|
+
},
|
34
|
+
:doghouse => proc {
|
35
|
+
require PACKAGE_ROOT + '/test/util/doghouse'
|
36
|
+
AnotherTestCrony.new(:default_format_string => "%s: %s")
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
@sophie = Preteen.new(crony_maker, [:bff], [:doghouse])
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_behavior_when_not_overridden_is_as_set
|
44
|
+
SomeRandomCommand.new(@sophie).execute
|
45
|
+
result = @sophie.cronies.collect { |crony| crony.value }
|
46
|
+
assert_equal(["scandal: boyfriend!, details: Joshua", "doghouse crony was not told!"],
|
47
|
+
result)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def test_that_config_files_can_change_who_gets_told
|
52
|
+
flip = %Q{
|
53
|
+
<sophie>
|
54
|
+
<bff>false</bff>
|
55
|
+
<doghouse>true</doghouse>
|
56
|
+
</sophie>
|
57
|
+
}
|
58
|
+
with_local_config_file('.sophie.xml', flip) {
|
59
|
+
SomeRandomCommand.new(@sophie).execute
|
60
|
+
result = @sophie.cronies.collect { |crony| crony.value }
|
61
|
+
assert_equal(["bff was not told!", "boyfriend!: Joshua"],
|
62
|
+
result)
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
def test_that_both_switches_and_options_can_be_overridden
|
69
|
+
reconcile = %Q{
|
70
|
+
doghouse: true
|
71
|
+
}
|
72
|
+
|
73
|
+
with_command_args('--bff-format=%s/%s --doghouse-form %s+%s') {
|
74
|
+
with_local_config_file('.sophie.yml', reconcile) {
|
75
|
+
SomeRandomCommand.new(@sophie).execute
|
76
|
+
result = @sophie.cronies.collect { |crony| crony.value }
|
77
|
+
assert_equal(["boyfriend!/Joshua", "boyfriend!+Joshua"],
|
78
|
+
result)
|
79
|
+
}
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_typical_usage_lines
|
84
|
+
with_command_args('--help') do
|
85
|
+
output = capturing_stderr do
|
86
|
+
assert_wants_to_exit do
|
87
|
+
SomeRandomCommand.new(@sophie)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
lines = output.split("\n")
|
91
|
+
assert_equal("Usage: ruby #{$0} [options] program args...", lines[0])
|
92
|
+
assert_match(/Site-wide defaults/, lines[1])
|
93
|
+
assert_match(/Override them in the '.localrc' or '.globalrc' files in your home folder./, lines[2])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class LongerUsageCommand < SomeRandomCommand
|
98
|
+
def usage; ['line 1', 'line 2']; end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_that_usage_lines_can_be_an_array
|
102
|
+
with_command_args('--help') do
|
103
|
+
output = capturing_stderr do
|
104
|
+
assert_wants_to_exit do
|
105
|
+
LongerUsageCommand.new(@sophie).execute
|
106
|
+
end
|
107
|
+
end
|
108
|
+
lines = output.split("\n")
|
109
|
+
assert_equal("line 1", lines[0])
|
110
|
+
assert_equal("line 2", lines[1])
|
111
|
+
assert_match(/Site-wide defaults/, lines[2])
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's4t-utils'
|
3
|
+
include S4tUtils
|
4
|
+
set_test_paths(__FILE__)
|
5
|
+
|
6
|
+
require 'gossip'
|
7
|
+
|
8
|
+
# Most of the crony behavior is interaction with Command, so see
|
9
|
+
# command-tests.rb
|
10
|
+
|
11
|
+
class ChoicesTests < Test::Unit::TestCase
|
12
|
+
include Gossip
|
13
|
+
|
14
|
+
class ConcreteCrony < Crony
|
15
|
+
def name; 'non-abstract'; end
|
16
|
+
def symbol; :sym; end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_crony_checks_for_typos
|
20
|
+
crony = ConcreteCrony.new(:key => 'value')
|
21
|
+
|
22
|
+
assert_equal('value', crony.checked(:key))
|
23
|
+
assert_raises_with_matching_message(StandardError, /:ky is nil.*#{crony.name}.*typo/) do
|
24
|
+
crony.checked(:ky)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def test_crony_can_describe_defaults
|
30
|
+
crony = ConcreteCrony.new(:key => 'value')
|
31
|
+
assert_equal('Defaults to "value".', crony.df(:key))
|
32
|
+
|
33
|
+
assert_raises_with_matching_message(StandardError, /:ky is nil.*#{crony.name}.*typo/) do
|
34
|
+
crony.checked(:ky)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_crony_friendship_depends_on_user_choices
|
39
|
+
crony = ConcreteCrony.new
|
40
|
+
crony.user_choices=({:sym => true})
|
41
|
+
assert_true(crony.is_bff?)
|
42
|
+
crony.user_choices=({:sym => false})
|
43
|
+
assert_false(crony.is_bff?)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's4t-utils'
|
3
|
+
include S4tUtils
|
4
|
+
set_test_paths(__FILE__)
|
5
|
+
|
6
|
+
require 'gossip/multi-exceptions'
|
7
|
+
|
8
|
+
class QueueExtensionTests < Test::Unit::TestCase
|
9
|
+
def test_to_a
|
10
|
+
queue = Queue.new
|
11
|
+
queue << 1
|
12
|
+
assert_equal([1], queue.to_a)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class MultiExceptionTests < Test::Unit::TestCase
|
17
|
+
include Gossip
|
18
|
+
|
19
|
+
def two_exceptions
|
20
|
+
retval = []
|
21
|
+
[IndexError.new("index error"),
|
22
|
+
RuntimeError.new("runtime error")].each do | ex |
|
23
|
+
begin
|
24
|
+
raise ex # You have to raise to get a backtrace.
|
25
|
+
rescue Exception => caught
|
26
|
+
retval << caught
|
27
|
+
end
|
28
|
+
end
|
29
|
+
retval
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup
|
33
|
+
@ex = MultiException.new(two_exceptions)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_multi_exception_aggregates_messages
|
38
|
+
messages = @ex.message.split("\n")
|
39
|
+
assert_match(/index error/, messages[0])
|
40
|
+
assert_match(/runtime error/, messages[1])
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_multi_exception_includes_exception_classes_in_messages
|
44
|
+
messages = @ex.message.split("\n")
|
45
|
+
assert_match(/IndexError/, messages[0])
|
46
|
+
assert_match(/RuntimeError/, messages[1])
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_multi_exception_aggregates_backtraces_in_traces_field
|
50
|
+
assert_equal(2, @ex.traces.length)
|
51
|
+
assert_equal(1, @ex.traces[0].grep(/setup/).length)
|
52
|
+
assert_equal(1, @ex.traces[1].grep(/setup/).length)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_combined_trace
|
56
|
+
begin
|
57
|
+
MultiException.reraise_with_combined_backtrace do
|
58
|
+
raise @ex
|
59
|
+
end
|
60
|
+
rescue MultiException => ex
|
61
|
+
assert_equal(1, ex.backtrace.grep(/Trace number 0:/).length)
|
62
|
+
assert_equal(1, ex.backtrace.grep(/Trace number 1:/).length)
|
63
|
+
# The raise in this method is wiped out.
|
64
|
+
assert_equal(0, ex.backtrace.grep(/test_combined_trace/).length)
|
65
|
+
# The raises in setup are preserved.
|
66
|
+
assert_equal(2, ex.backtrace.grep(/setup/).length)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|