graffle 0.1.9 → 0.2.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/Manifest.txt +15 -8
- data/Rakefile.hoe +1 -2
- data/bin/interpret-intentions.rb +51 -0
- data/examples/objects with notes.rb +1 -0
- data/examples/old-style-rails-workflow-test.expected +11 -0
- data/examples/old-style-rails-workflow-test.rb +43 -0
- data/examples/rails-workflow-test.rb +7 -6
- data/examples/sheet with key.expected +5 -0
- data/examples/sheet with key.graffle +0 -0
- data/examples/sheet with key.rb +38 -0
- data/graffle.tmproj +242 -75
- data/lib/graffle.rb +11 -2
- data/lib/graffle/nodoc/hacks.rb +1 -0
- data/lib/graffle/point.rb +1 -0
- data/lib/graffle/stereotypes.rb +34 -3
- data/lib/graffle/version.rb +3 -1
- data/lib/graphical_tests_for_rails.rb +11 -9
- data/lib/graphical_tests_for_rails/jumbled-string-canonicalizer.rb +117 -0
- data/lib/graphical_tests_for_rails/orderings.rb +1 -2
- data/lib/graphical_tests_for_rails/picture-applier.rb +257 -0
- data/lib/graphical_tests_for_rails/stereotype-extensions.rb +111 -0
- data/lib/graphical_tests_for_rails/text-appliers.rb +10 -84
- data/lib/graphical_tests_for_rails/user-intention.rb +250 -0
- data/test/abstract-graphic-tests.rb +10 -0
- data/test/container-tests.rb +29 -0
- data/test/graphical_tests_for_rails/jumbled-string-canonicalizer-tests.rb +174 -0
- data/test/graphical_tests_for_rails/new-style-picture-applier-tests.rb +286 -0
- data/test/graphical_tests_for_rails/old-style-picture-applier-tests.rb +129 -0
- data/test/graphical_tests_for_rails/user-intention-tests.rb +389 -0
- data/test/graphical_tests_for_rails/util.rb +9 -0
- data/test/sheet-tests.rb +21 -0
- data/test/text-tests.rb +6 -0
- metadata +25 -26
- data/design-notes/graphical-tests-for-rails-objects.graffle +0 -644
- data/lib/graphical_tests_for_rails/graphic-volunteers.rb +0 -75
- data/lib/graphical_tests_for_rails/picture-appliers.rb +0 -225
- data/lib/graphical_tests_for_rails/volunteer-pool.rb +0 -115
- data/test/graphical_tests_for_rails/deprecated-graphic-interpreter-tests.rb +0 -121
- data/test/graphical_tests_for_rails/graphic-volunteer-tests.rb +0 -218
- data/test/graphical_tests_for_rails/picture-applier-tests.rb +0 -215
- data/test/graphical_tests_for_rails/text-applier-tests.rb +0 -111
@@ -101,4 +101,14 @@ class TestAbstractGraphics < Test::Unit::TestCase
|
|
101
101
|
assert_true(s.find_by_id(333).note.behaves_like?(Graffle::Note))
|
102
102
|
end
|
103
103
|
|
104
|
+
def test_abstract_graphics_in_collections_can_delete_themselves
|
105
|
+
s = sheet {
|
106
|
+
with shaped_graphic { graffle_id_is 1}
|
107
|
+
}
|
108
|
+
|
109
|
+
g = s.find_by_id(1)
|
110
|
+
g.delete_yourself
|
111
|
+
assert_equal(nil, s.find_by_id(1))
|
112
|
+
end
|
113
|
+
|
104
114
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-25.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
# TODO: Some tests from sheets and groups could probably be moved here.
|
7
|
+
|
8
|
+
|
9
|
+
require "set-standalone-test-paths.rb" unless $started_from_rakefile
|
10
|
+
require 'test/unit'
|
11
|
+
require 's4t-utils'
|
12
|
+
include S4tUtils
|
13
|
+
require 'test/util'
|
14
|
+
|
15
|
+
require 'graffle'
|
16
|
+
|
17
|
+
class TestContainers < Test::Unit::TestCase
|
18
|
+
include Graffle
|
19
|
+
include Graffle::Builders
|
20
|
+
|
21
|
+
def test_deletion
|
22
|
+
s = sheet {
|
23
|
+
with line_graphic { graffle_id_is 1 }
|
24
|
+
}
|
25
|
+
g = s.find_by_id(1)
|
26
|
+
s.delete_graphic(g)
|
27
|
+
assert_nil(s.find_by_id(1))
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-29.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 's4t-utils'
|
8
|
+
include S4tUtils
|
9
|
+
|
10
|
+
require "../set-standalone-test-paths.rb" unless $started_from_rakefile
|
11
|
+
|
12
|
+
require 'extensions/string'
|
13
|
+
require 'test/graphical_tests_for_rails/util'
|
14
|
+
require 'graphical_tests_for_rails/jumbled-string-canonicalizer'
|
15
|
+
|
16
|
+
class TestJumbledStringCanonicalizer < Test::Unit::TestCase
|
17
|
+
include GraphicalTestsForRails
|
18
|
+
|
19
|
+
def test_simple_canonicalization_selects_one_string
|
20
|
+
patterns = {
|
21
|
+
[/\b(ones?)\b/] => "one",
|
22
|
+
}
|
23
|
+
|
24
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
25
|
+
canonical = izer.canonicalize(s = "they are the ones.")
|
26
|
+
assert_equal("one", canonical.value)
|
27
|
+
assert_equal(s, canonical.source)
|
28
|
+
assert_equal([['ones']], canonical.raw_reason)
|
29
|
+
assert_equal("'ones'", canonical.pretty_reason)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_canonicalization_can_have_more_than_one_regexp
|
33
|
+
patterns = {
|
34
|
+
[/\b(ones?\stwos?)\b/] => "wrong",
|
35
|
+
[/\b(ones?)\b/, /\b(twos?)\b/] => "one two",
|
36
|
+
}
|
37
|
+
|
38
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
39
|
+
canonical = izer.canonicalize(s = "two is two ones")
|
40
|
+
assert_equal("one two", canonical.value)
|
41
|
+
assert_equal(s, canonical.source)
|
42
|
+
assert_equal([['ones'], ['two']], canonical.raw_reason)
|
43
|
+
assert_equal("'ones'; and also 'two'", canonical.pretty_reason)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_raw_reasons_are_available
|
47
|
+
patterns = {
|
48
|
+
[/\b(a)\s+(cs?)\b/, /\b(d+).*?(e+).*?(f)\b/] => "success",
|
49
|
+
}
|
50
|
+
|
51
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
52
|
+
canonical = izer.canonicalize(s = "ddd a cs ee not included f")
|
53
|
+
assert_equal("success", canonical.value)
|
54
|
+
|
55
|
+
assert_equal([["a", "cs"], ["ddd", "ee", "f"]], canonical.raw_reason)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_raw_reasons_do_not_include_nil_alternatives
|
59
|
+
patterns = {
|
60
|
+
[/(a)|(b)/] => "success",
|
61
|
+
}
|
62
|
+
|
63
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
64
|
+
canonical = izer.canonicalize(s = "a") # $1 = 'a', $2 = nil
|
65
|
+
assert_equal([["a"]], canonical.raw_reason)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_reasons_can_be_produced_prettily
|
69
|
+
patterns = {
|
70
|
+
[/\b(a)\s+(cs?)\b/, /\b(d+).*?(e+).*?(f)\b/] => "success",
|
71
|
+
}
|
72
|
+
|
73
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
74
|
+
canonical = izer.canonicalize(s = "ddd a cs ee not included f")
|
75
|
+
assert_equal("success", canonical.value)
|
76
|
+
assert_equal("'a' and 'cs'; and also 'ddd', 'ee', and 'f'", canonical.pretty_reason)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_normally_no_match_is_an_error
|
80
|
+
izer = JumbledStringCanonicalizer.new
|
81
|
+
assert_raise_with_matching_message(StandardError,
|
82
|
+
/Cannot recognize.*'foo'/) {
|
83
|
+
izer.canonicalize("foo")
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_the_no_match_error_message_can_be_customized
|
88
|
+
izer = JumbledStringCanonicalizer.new {
|
89
|
+
no_match_message {|source| "Dude! What's with '#{source}'?"}
|
90
|
+
}
|
91
|
+
assert_raise_with_matching_message(StandardError, /Dude! What's with 'foo'\?/) {
|
92
|
+
izer.canonicalize("foo")
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_there_can_be_a_default_value_in_case_of_no_match
|
97
|
+
patterns = {
|
98
|
+
[/\b(ones?\stwos?)\b/] => "wrong",
|
99
|
+
[/\b(ones?)\b/, /\b(twos?)\b/] => "one two",
|
100
|
+
}
|
101
|
+
izer = JumbledStringCanonicalizer.new(patterns) {
|
102
|
+
default "default"
|
103
|
+
}
|
104
|
+
canonical = izer.canonicalize(s = "ddd a cs ee not included f")
|
105
|
+
assert_equal("default", canonical.value)
|
106
|
+
assert_equal(s, canonical.source)
|
107
|
+
assert_equal([], canonical.raw_reason)
|
108
|
+
assert_equal("no matching words", canonical.pretty_reason)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_nil_is_a_fine_default_value
|
112
|
+
izer = JumbledStringCanonicalizer.new {
|
113
|
+
default nil
|
114
|
+
}
|
115
|
+
canonical = izer.canonicalize(s = "match me!")
|
116
|
+
assert_equal(nil, canonical.value)
|
117
|
+
assert_equal(s, canonical.source)
|
118
|
+
assert_equal([], canonical.raw_reason)
|
119
|
+
assert_equal("no matching words", canonical.pretty_reason)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_normally_multiple_matches_are_an_error
|
123
|
+
patterns = {
|
124
|
+
[/(one) (two)/] => 'one',
|
125
|
+
[/(two)/] => 'two'
|
126
|
+
}
|
127
|
+
izer = JumbledStringCanonicalizer.new(patterns)
|
128
|
+
assert_raise_with_matching_message(StandardError,
|
129
|
+
/Multiple matches in 'one two'.*'one' and 'two'/m) {
|
130
|
+
# Can't check both match reasons because order is unknown.
|
131
|
+
izer.canonicalize("one two")
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_the_multiple_match_error_can_be_customized_using_pretty_reasons
|
136
|
+
patterns = {
|
137
|
+
[/(one) (two)/, /(one)/] => 'one',
|
138
|
+
[/(one) (two)/] => 'two'
|
139
|
+
}
|
140
|
+
izer = JumbledStringCanonicalizer.new(patterns) {
|
141
|
+
multiple_match_message { | source, pretty_reasons, raw_reasons |
|
142
|
+
pretty_reasons = pretty_reasons.sort_by { |r| r.length }
|
143
|
+
"Could not match '#{source}' for multiple reasons:\n" +
|
144
|
+
"One match is against these words: #{pretty_reasons[0]}\n" +
|
145
|
+
pretty_reasons[1..-1].collect { |r| "Another is against these: #{r}" }.join("\n")
|
146
|
+
}
|
147
|
+
}
|
148
|
+
assert_raise_with_matching_message(StandardError,
|
149
|
+
/not match 'one two'.*One match.*'one' and 'two'.*Another.*'one' and 'two'.*also 'one'/m) {
|
150
|
+
izer.canonicalize("one two")
|
151
|
+
}
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_multiple_matches_can_be_disambiguated
|
155
|
+
patterns = {
|
156
|
+
[/(one) (two)/] => 'one',
|
157
|
+
[/(two)|(one)|(three)/] => 'two'
|
158
|
+
}
|
159
|
+
izer = JumbledStringCanonicalizer.new(patterns) {
|
160
|
+
disambiguate { |a, b|
|
161
|
+
words = proc { | x | - x.raw_reason.flatten.compact.length }
|
162
|
+
words[a] <=> words[b]
|
163
|
+
}
|
164
|
+
}
|
165
|
+
canonical = izer.canonicalize(s = "one two")
|
166
|
+
assert_equal("one", canonical.value)
|
167
|
+
assert_equal(s, canonical.source)
|
168
|
+
assert_equal("'one' and 'two'", canonical.pretty_reason)
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-25.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 's4t-utils'
|
8
|
+
include S4tUtils
|
9
|
+
|
10
|
+
require "../set-standalone-test-paths.rb" unless $started_from_rakefile
|
11
|
+
|
12
|
+
require 'extensions/string'
|
13
|
+
require 'test/graphical_tests_for_rails/util'
|
14
|
+
require 'graffle'
|
15
|
+
require 'graphical_tests_for_rails/picture-applier'
|
16
|
+
|
17
|
+
class NewStylePictureApplierTest < Test::Unit::TestCase
|
18
|
+
include Graffle
|
19
|
+
include Graffle::Builders
|
20
|
+
include GraphicalTestsForRails
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@sheet = sheet {
|
24
|
+
with shaped_graphic {
|
25
|
+
graffle_id_is 1
|
26
|
+
with_content "just a comment"
|
27
|
+
with_note 'ignore'
|
28
|
+
}
|
29
|
+
|
30
|
+
with shaped_graphic {
|
31
|
+
graffle_id_is 11
|
32
|
+
with_content "PAGE"
|
33
|
+
}
|
34
|
+
|
35
|
+
with line_label {
|
36
|
+
for_line 22
|
37
|
+
with_content "fred tests the label text"
|
38
|
+
}
|
39
|
+
with line_graphic {
|
40
|
+
graffle_id_is 22
|
41
|
+
}
|
42
|
+
with shaped_graphic {
|
43
|
+
with_content "Key"
|
44
|
+
with_note %Q{skip graphics with an "ignore" annotation
|
45
|
+
|
46
|
+
line label contents are user actions with args in quotes
|
47
|
+
shape content names a page
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def test_from_sheet_requires_key
|
56
|
+
assert_raises_with_matching_message(StandardError, /has no key/) do
|
57
|
+
PictureApplier.from_sheet(sheet)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def test_but_defaults_can_be_used_instead_of_key
|
63
|
+
applier = PictureApplier.from_sheet(sheet,
|
64
|
+
"notes are claims with quoted args",
|
65
|
+
"contents are page names")
|
66
|
+
|
67
|
+
matches = lambda do |graphic|
|
68
|
+
ints = applier.intentions_that_apply_to(graphic)
|
69
|
+
ints.collect { |i| i.source }
|
70
|
+
end
|
71
|
+
|
72
|
+
benoted = shaped_graphic { with_note "fred" }
|
73
|
+
contented = shaped_graphic { with_content "barry" }
|
74
|
+
|
75
|
+
assert_equal(["notes are claims with quoted args"], matches[benoted])
|
76
|
+
assert_equal(["contents are page names"], matches[contented])
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def test_from_sheet_key_requires_notes
|
81
|
+
assert_raises_with_matching_message(StandardError, /supposed to have an annotation/) do
|
82
|
+
s = sheet {
|
83
|
+
with shaped_graphic {
|
84
|
+
with_content "key"
|
85
|
+
}
|
86
|
+
}
|
87
|
+
PictureApplier.from_sheet(s)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_from_sheet_key_contents_must_be_recognized
|
92
|
+
assert_raises_with_matching_message(StandardError, /does not refer to any graphic/) do
|
93
|
+
s = sheet {
|
94
|
+
with shaped_graphic {
|
95
|
+
with_content "key"
|
96
|
+
with_note "missing"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
PictureApplier.from_sheet(s)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_graphics_are_filtered_by_place
|
104
|
+
any_note = "match any note (action would be skip)"
|
105
|
+
any_shape_note = "match any shape note (action would be skip)"
|
106
|
+
kp = PictureApplier.from_written_intentions(any_note, any_shape_note)
|
107
|
+
|
108
|
+
matches = lambda do |graphic|
|
109
|
+
ints = kp.intentions_that_apply_to(graphic)
|
110
|
+
ints.collect { |i| i.source }
|
111
|
+
end
|
112
|
+
|
113
|
+
assert_equal([], matches[shaped_graphic])
|
114
|
+
assert_equal([], matches[shaped_graphic {with_content "t"}])
|
115
|
+
assert_equal([any_note],
|
116
|
+
matches[besheeted(line_graphic { with_note "hi"})])
|
117
|
+
assert_equal([any_note, any_shape_note],
|
118
|
+
matches[shaped_graphic {with_note "t"}])
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_graphics_can_be_ignored
|
122
|
+
skipper = "skip if note says 'ignore'"
|
123
|
+
kp = PictureApplier.from_written_intentions(skipper)
|
124
|
+
|
125
|
+
matches = lambda do |graphic|
|
126
|
+
ints = kp.intentions_that_apply_to(graphic)
|
127
|
+
ints.collect { |i| i.source }
|
128
|
+
end
|
129
|
+
|
130
|
+
assert_equal([], matches[shaped_graphic])
|
131
|
+
assert_equal([], matches[shaped_graphic {with_content "t"}])
|
132
|
+
assert_equal([],
|
133
|
+
matches[besheeted(line_graphic { with_note "hi"})])
|
134
|
+
assert_equal([skipper],
|
135
|
+
matches[shaped_graphic {with_note "ignore"}])
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_application_of_intentions
|
139
|
+
@applier = PictureApplier.from_sheet(@sheet)
|
140
|
+
target = CommandRecorder.new
|
141
|
+
@applier.apply(@sheet.graphics_without_labels, target)
|
142
|
+
assert_equal(['assert_on_page("page")', 'tests_the_label_text("fred")'],
|
143
|
+
target.record)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_action_must_be_recognized
|
147
|
+
assert_raises_with_matching_message(StandardError, /doesn't say what should happen/) do
|
148
|
+
s = sheet {
|
149
|
+
with shaped_graphic {
|
150
|
+
with_content "key"
|
151
|
+
with_note "note with friends dines"
|
152
|
+
}
|
153
|
+
}
|
154
|
+
PictureApplier.from_sheet(s)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_different_lines_can_cause_different_actions
|
159
|
+
s = sheet {
|
160
|
+
with shaped_graphic {
|
161
|
+
graffle_id_is 1
|
162
|
+
with_content %Q{page\njohn logs in as "john".}
|
163
|
+
}
|
164
|
+
|
165
|
+
with shaped_graphic {
|
166
|
+
with_content "Key"
|
167
|
+
with_note %Q{shape content with one word is page name
|
168
|
+
otherwise, shape content is user action with args in quotes
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
applier = PictureApplier.from_sheet(s)
|
173
|
+
target = CommandRecorder.new
|
174
|
+
applier.apply(s.graphics_without_labels, target)
|
175
|
+
assert_equal(['assert_on_page("page")', 'logs_in_as("john", "john")'],
|
176
|
+
target.record)
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_empty_graphics_are_gracefully_ignored
|
180
|
+
s = sheet {
|
181
|
+
with shaped_graphic
|
182
|
+
with line_graphic
|
183
|
+
}
|
184
|
+
|
185
|
+
applier = PictureApplier.from_written_intentions(
|
186
|
+
"notes are page names",
|
187
|
+
"contents are page names"
|
188
|
+
)
|
189
|
+
|
190
|
+
applier.apply(s.graphics_without_labels, nil)
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_non_empty_graphics_that_do_not_match_are_too
|
194
|
+
s = sheet {
|
195
|
+
with shaped_graphic { with_content "hi"}
|
196
|
+
with line_label {
|
197
|
+
for_line 1
|
198
|
+
with_content "bye"
|
199
|
+
}
|
200
|
+
with line_graphic {
|
201
|
+
graffle_id_is 1
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
applier = PictureApplier.from_written_intentions(
|
206
|
+
"notes are page names"
|
207
|
+
)
|
208
|
+
|
209
|
+
applier.apply(s.graphics_without_labels, nil)
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_lines_that_do_not_match_are_ignored
|
213
|
+
s = sheet {
|
214
|
+
with shaped_graphic { with_content "only line ignored"}
|
215
|
+
with line_label {
|
216
|
+
for_line 1
|
217
|
+
with_content "multiple lines\n\nare ignored but single are\nnot"
|
218
|
+
}
|
219
|
+
with line_graphic {
|
220
|
+
graffle_id_is 1
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
applier = PictureApplier.from_written_intentions(
|
225
|
+
"content lines with one word are page names"
|
226
|
+
)
|
227
|
+
|
228
|
+
target = CommandRecorder.new
|
229
|
+
applier.apply(s.graphics_without_labels, target)
|
230
|
+
assert_equal(['assert_on_page("not")'],
|
231
|
+
target.record)
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
def four_counting_shaped_graphics
|
237
|
+
sheet {
|
238
|
+
with shaped_graphic { with_content "first" }
|
239
|
+
with shaped_graphic { with_content "second" }
|
240
|
+
with shaped_graphic { with_content "third" }
|
241
|
+
with shaped_graphic { with_content "yikes!"}
|
242
|
+
}.graphics
|
243
|
+
end
|
244
|
+
|
245
|
+
def four_graphic_contents
|
246
|
+
four_counting_shaped_graphics.collect { |g| g.content.as_plain_text }
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
class ThriceThenDie
|
252
|
+
include Test::Unit::Assertions
|
253
|
+
|
254
|
+
def initialize
|
255
|
+
@count = 0
|
256
|
+
end
|
257
|
+
|
258
|
+
def assert_on_page(value)
|
259
|
+
@count += 1
|
260
|
+
assert_equal("right", "wrong") if @count >= 4
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
def assert_thrice_then_die_log(exc, expected_echoed)
|
267
|
+
assert_match(/right.*expected.*was.*wrong/m, exc.message)
|
268
|
+
expected = expected_echoed.collect do |w|
|
269
|
+
"assert_on_page\\(" + w.inspect + "\\)"
|
270
|
+
end.join('.*')
|
271
|
+
assert_match(/#{expected}/m, exc.message)
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_logging_prints_list_of_calls_into_target
|
275
|
+
@applier = PictureApplier.from_written_intentions(
|
276
|
+
"shape content is page name"
|
277
|
+
)
|
278
|
+
begin
|
279
|
+
@applier.apply(four_counting_shaped_graphics, ThriceThenDie.new)
|
280
|
+
flunk "never reached"
|
281
|
+
rescue Test::Unit::AssertionFailedError => e
|
282
|
+
assert_thrice_then_die_log(e, four_graphic_contents)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|