graffle 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|