gossip 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.
- 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
|