graffle 0.1.8 → 0.1.9
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 +5 -0
- data/Manifest.txt +22 -11
- data/README.txt +2 -2
- data/Rakefile.hoe +2 -1
- data/design-notes/graphical-tests-for-rails-objects.graffle +644 -0
- data/examples/objects with notes.expected +5 -0
- data/examples/objects with notes.graffle +338 -0
- data/examples/objects with notes.rb +42 -0
- data/examples/rails-workflow-test.expected +1 -1
- data/examples/rails-workflow-test.graffle/data.plist +86 -7
- data/examples/rails-workflow-test.rb +11 -9
- data/graffle.tmproj +82 -190
- data/lib/graffle.rb +19 -2
- data/lib/graffle/point.rb +1 -2
- data/lib/graffle/stereotypes.rb +62 -16
- data/lib/graffle/version.rb +1 -1
- data/lib/graphical_tests_for_rails.rb +8 -5
- data/lib/graphical_tests_for_rails/graphic-volunteers.rb +75 -0
- data/lib/graphical_tests_for_rails/orderings.rb +90 -84
- data/lib/graphical_tests_for_rails/picture-appliers.rb +225 -0
- data/lib/graphical_tests_for_rails/text-appliers.rb +135 -0
- data/lib/graphical_tests_for_rails/volunteer-pool.rb +115 -0
- data/test/abstract-graphic-tests.rb +48 -0
- data/test/document-tests.rb +5 -5
- data/test/examples-tests.rb +42 -0
- data/test/graphical_tests_for_rails/{graphic-interpreter-tests.rb → deprecated-graphic-interpreter-tests.rb} +11 -21
- data/test/graphical_tests_for_rails/graphic-volunteer-tests.rb +218 -0
- data/test/graphical_tests_for_rails/in-workflow-order-tests.rb +1 -1
- data/test/graphical_tests_for_rails/picture-applier-tests.rb +215 -0
- data/test/graphical_tests_for_rails/{text-interpreter-tests.rb → text-applier-tests.rb} +17 -3
- data/test/graphical_tests_for_rails/util.rb +16 -0
- data/test/line-graphic-tests.rb +9 -1
- data/test/note-tests.rb +62 -0
- data/test/{graffle-file-types → sample-files}/as-a-package.graffle/data.plist +0 -0
- data/test/{graffle-file-types → sample-files}/as-a-package.graffle/image1.png +0 -0
- data/test/{graffle-file-types → sample-files}/as-a-package.graffle/image2.png +0 -0
- data/test/{graffle-file-types → sample-files}/as-a-package.graffle/image3.png +0 -0
- data/test/{graffle-file-types → sample-files}/multiple-canvases.graffle +0 -0
- data/test/{graffle-file-types → sample-files}/opening-tests.rb +9 -4
- data/test/{graffle-file-types → sample-files}/two-boxes-and-a-line.graffle +0 -0
- data/test/shaped-graphic-tests.rb +2 -3
- metadata +42 -18
- data/lib/graphical_tests_for_rails/interpreters.rb +0 -147
- data/test/tests-of-examples/workflow-slowtests.rb +0 -19
@@ -14,7 +14,7 @@ require 'graphical_tests_for_rails/orderings.rb'
|
|
14
14
|
|
15
15
|
class TestWorkflowOrder < Test::Unit::TestCase
|
16
16
|
include Graffle::Builders
|
17
|
-
include GraphicalTestsForRails
|
17
|
+
include GraphicalTestsForRails::GraphicArrayOrderings
|
18
18
|
|
19
19
|
def test_workflow_order_finds_highest_first
|
20
20
|
s = sheet {
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-20.
|
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-appliers'
|
16
|
+
|
17
|
+
class PictureApplierTest < Test::Unit::TestCase
|
18
|
+
include Graffle
|
19
|
+
include Graffle::Builders
|
20
|
+
include GraphicalTestsForRails
|
21
|
+
include GraphicalTestsForRails::TextAppliers
|
22
|
+
|
23
|
+
def setup
|
24
|
+
@sheet = sheet {
|
25
|
+
with shaped_graphic {
|
26
|
+
graffle_id_is 1
|
27
|
+
with_content 'shaped graphic text...'
|
28
|
+
}
|
29
|
+
with line_label {
|
30
|
+
for_line 22
|
31
|
+
with_content 'line label text...'
|
32
|
+
}
|
33
|
+
with line_graphic {
|
34
|
+
graffle_id_is 22
|
35
|
+
}
|
36
|
+
with shaped_graphic { # no text
|
37
|
+
graffle_id_is 333
|
38
|
+
}
|
39
|
+
with line_graphic { # no label
|
40
|
+
graffle_id_is 4444
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def shaped_graphic_with_content; @sheet.find_by_id(1); end
|
46
|
+
def shaped_graphic_without_text; @sheet.find_by_id(333); end
|
47
|
+
def line_graphic_with_label; @sheet.find_by_id(22); end
|
48
|
+
def line_graphic_without_label; @sheet.find_by_id(4444); end
|
49
|
+
|
50
|
+
|
51
|
+
def test_empty_applier_produces_eager_but_useless_volunteer
|
52
|
+
@applier = PictureApplier.new
|
53
|
+
g = shaped_graphic { with_content 'foo' }
|
54
|
+
assert_equal(EagerButUselessVolunteer, @applier.find_volunteer_for(g).class)
|
55
|
+
# Or, as shorthand:
|
56
|
+
assert_eager_but_useless_volunteer_for(g)
|
57
|
+
end
|
58
|
+
|
59
|
+
def assert_eager_but_useless_volunteer_for(graphic)
|
60
|
+
assert_equal(EagerButUselessVolunteer, @applier.find_volunteer_for(graphic).class)
|
61
|
+
end
|
62
|
+
|
63
|
+
def assert_trained_volunteer_for(graphic)
|
64
|
+
assert_not_equal(EagerButUselessVolunteer, @applier.find_volunteer_for(graphic).class)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_useless_volunteer_does_nothing
|
68
|
+
# ... so we can just test for it rather than having it do something.
|
69
|
+
@applier = PictureApplier.new
|
70
|
+
g = shaped_graphic { with_note 'foo' }
|
71
|
+
@applier.apply([g], "will blow up if used")
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# Some examples of how a PictureApplier can use the Volunteer
|
76
|
+
# mechanism to prepare volunteers trained for certain kinds
|
77
|
+
# of graphics.
|
78
|
+
def test_can_recruit_trained_volunteers_for_shaped_graphic_contents
|
79
|
+
@applier = PictureApplier.new {
|
80
|
+
given('shaped graphic content') # ... chained methods go here
|
81
|
+
}
|
82
|
+
|
83
|
+
assert_trained_volunteer_for(shaped_graphic_with_content)
|
84
|
+
assert_eager_but_useless_volunteer_for(shaped_graphic_without_text)
|
85
|
+
assert_eager_but_useless_volunteer_for(line_graphic_with_label)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_can_recruit_trained_volunteers_for_line_graphic_labels
|
89
|
+
@applier = PictureApplier.new {
|
90
|
+
given('line label content') # ... chained methods go here
|
91
|
+
}
|
92
|
+
|
93
|
+
assert_trained_volunteer_for(line_graphic_with_label)
|
94
|
+
assert_eager_but_useless_volunteer_for(line_graphic_without_label)
|
95
|
+
assert_eager_but_useless_volunteer_for(shaped_graphic_with_content)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_there_is_a_fixed_set_of_graphically_oriented_volunteers
|
99
|
+
assert_raises(StandardError) {
|
100
|
+
PictureApplier.new { given 'oopsla' }
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Examples of using the 'matching' clause to augment a
|
106
|
+
# graphically-oriented volunteer with a textually-oriented one.
|
107
|
+
|
108
|
+
def test_can_augment_a_volunteer_to_look_for_ellipses
|
109
|
+
@applier = PictureApplier.new {
|
110
|
+
given('shaped graphic content').matching('text...') # ... chained methods go here
|
111
|
+
}
|
112
|
+
|
113
|
+
assert_trained_volunteer_for(shaped_graphic { with_content "blah..." })
|
114
|
+
assert_eager_but_useless_volunteer_for(shaped_graphic { with_content "blah" })
|
115
|
+
assert_eager_but_useless_volunteer_for(shaped_graphic)
|
116
|
+
assert_eager_but_useless_volunteer_for(line_graphic_with_label)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_there_is_a_fixed_set_of_textually_oriented_volunteers
|
120
|
+
ok_so_far = PictureApplier.new { given 'shaped graphic content' }
|
121
|
+
assert_raises(StandardError) {
|
122
|
+
ok_so_far.matching('something never defined')
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
# An example of how it's all put together to send messages to targets.
|
127
|
+
|
128
|
+
class Echoer < AbstractTextApplier
|
129
|
+
def message_and_args_from(string)
|
130
|
+
[:echo, string]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_application_of_matches
|
135
|
+
@applier = PictureApplier.new {
|
136
|
+
given('note').matching('text...').skip
|
137
|
+
given('note').use(Echoer.new)
|
138
|
+
}
|
139
|
+
|
140
|
+
s = sheet {
|
141
|
+
with shaped_graphic { with_notes 'hello world' }
|
142
|
+
with line_graphic
|
143
|
+
with shaped_graphic { with_notes "waiting..."}
|
144
|
+
with line_graphic { with_notes "goodbye world" }
|
145
|
+
}
|
146
|
+
|
147
|
+
target = CommandRecorder.new
|
148
|
+
@applier.apply(s.graphics, target)
|
149
|
+
assert_equal(['echo("hello world")', 'echo("goodbye world")'],
|
150
|
+
target.record)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
class ThriceThenDie
|
155
|
+
include Test::Unit::Assertions
|
156
|
+
|
157
|
+
def initialize
|
158
|
+
@count = 0
|
159
|
+
end
|
160
|
+
|
161
|
+
def echo(value)
|
162
|
+
@count += 1
|
163
|
+
assert_equal("right", "wrong") if @count >= 4
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
def four_counting_shaped_graphics
|
169
|
+
sheet {
|
170
|
+
with shaped_graphic { with_content "first" }
|
171
|
+
with shaped_graphic { with_content "second" }
|
172
|
+
with shaped_graphic { with_content "third" }
|
173
|
+
with shaped_graphic { with_content "yikes!"}
|
174
|
+
}.graphics
|
175
|
+
end
|
176
|
+
|
177
|
+
def four_graphic_contents
|
178
|
+
four_counting_shaped_graphics.collect { |g| g.content.as_plain_text }
|
179
|
+
end
|
180
|
+
|
181
|
+
def assert_thrice_then_die_log(exc, expected_echoed)
|
182
|
+
assert_match(/right.*expected.*was.*wrong/m, exc.message)
|
183
|
+
expected = expected_echoed.collect do |w|
|
184
|
+
"echo\\(" + w.inspect + "\\)"
|
185
|
+
end.join('.*')
|
186
|
+
assert_match(/#{expected}/m, exc.message)
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_logging_prints_list_of_calls_into_target
|
190
|
+
@applier = PictureApplier.new {
|
191
|
+
given('shaped graphic content').use(Echoer.new)
|
192
|
+
}
|
193
|
+
begin
|
194
|
+
@applier.apply(four_counting_shaped_graphics, ThriceThenDie.new)
|
195
|
+
rescue Test::Unit::AssertionFailedError => e
|
196
|
+
assert_thrice_then_die_log(e, four_graphic_contents)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_log_can_be_injected
|
201
|
+
def test_logging_prints_list_of_calls_into_target
|
202
|
+
@applier = PictureApplier.new {
|
203
|
+
given('shaped graphic content').use(Echoer.new)
|
204
|
+
}
|
205
|
+
begin
|
206
|
+
@applier.apply(four_counting_shaped_graphics,
|
207
|
+
ThriceThenDie.new,
|
208
|
+
['echo("prior value of log")'])
|
209
|
+
rescue Test::Unit::AssertionFailedError => e
|
210
|
+
assert_thrice_then_die_log(e, ["prior value of log"] + four_graphic_contents)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
@@ -17,7 +17,7 @@ class TestProductionOfMessages < Test::Unit::TestCase
|
|
17
17
|
include GraphicalTestsForRails
|
18
18
|
|
19
19
|
def assert_translation(expected, original)
|
20
|
-
actual = @interpreter.
|
20
|
+
actual = @interpreter.message_and_args_from(original)
|
21
21
|
assert_equal(expected, actual)
|
22
22
|
end
|
23
23
|
|
@@ -75,9 +75,23 @@ class TestProductionOfMessages < Test::Unit::TestCase
|
|
75
75
|
assert_translation(["capitals_are_lowercased_throughout"],
|
76
76
|
%q{Capitals are lowercased THROUGHOUT})
|
77
77
|
end
|
78
|
+
|
79
|
+
def test_messages_created_from_prefix_name_and_quoted_args
|
80
|
+
@interpreter = PrefixNameAndArgsFromQuotedText.new
|
81
|
+
|
82
|
+
assert_translation(["runs", "nathan"],
|
83
|
+
%q{Nathan runs})
|
84
|
+
|
85
|
+
assert_translation(["runs_to", "nathan", "Tacoma"],
|
86
|
+
%q{Nathan runs to "Tacoma"})
|
87
|
+
|
88
|
+
assert_raises_with_matching_message(StandardError, /'runs' cannot be split into a name and an action./) {
|
89
|
+
@interpreter.message_and_args_from('runs')
|
90
|
+
}
|
91
|
+
end
|
78
92
|
|
79
93
|
def test_messages_created_from_page_names
|
80
|
-
@interpreter =
|
94
|
+
@interpreter = TextAsNameOfPage.new('assert_on_page')
|
81
95
|
assert_translation(['assert_on_page', "markup"],
|
82
96
|
"MARKUP")
|
83
97
|
|
@@ -91,7 +105,7 @@ class TestProductionOfMessages < Test::Unit::TestCase
|
|
91
105
|
|
92
106
|
|
93
107
|
def test_ineffectual_interpreters_produce_messages_that_do_nothing
|
94
|
-
@interpreter =
|
108
|
+
@interpreter = TextApplierThatDoesNothing.new
|
95
109
|
assert_translation([:object_id], "MARKUP")
|
96
110
|
end
|
97
111
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-20.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
class CommandRecorder
|
8
|
+
attr_reader :record
|
9
|
+
def initialize
|
10
|
+
@record = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(message, *args)
|
14
|
+
@record << "#{message}(" + args.collect { | a | a.inspect }.join(", ") + ')'
|
15
|
+
end
|
16
|
+
end
|
data/test/line-graphic-tests.rb
CHANGED
@@ -130,12 +130,15 @@ class TestLineGraphics < Test::Unit::TestCase
|
|
130
130
|
sheet {
|
131
131
|
with line_label { # Line labels are graphics at same level as lines.
|
132
132
|
for_line 1
|
133
|
-
|
133
|
+
with_content LINE_LABEL_TEXT
|
134
134
|
graffle_id_is 3
|
135
135
|
}
|
136
136
|
with line_graphic {
|
137
137
|
graffle_id_is 1
|
138
138
|
}
|
139
|
+
with line_graphic {
|
140
|
+
graffle_id_is 883 # No label.
|
141
|
+
}
|
139
142
|
}
|
140
143
|
end
|
141
144
|
|
@@ -150,6 +153,11 @@ class TestLineGraphics < Test::Unit::TestCase
|
|
150
153
|
assert_equal(1, label_graphic.line.graffle_id)
|
151
154
|
end
|
152
155
|
|
156
|
+
def test_lines_can_be_asked_if_they_have_labels
|
157
|
+
assert_true(line_label_sheet.find_by_id(1).has_label?)
|
158
|
+
assert_false(line_label_sheet.find_by_id(883).has_label?)
|
159
|
+
end
|
160
|
+
|
153
161
|
def test_labels_can_nevertheless_be_treated_as_attached_to_line
|
154
162
|
line = line_label_sheet.find_by_id(1)
|
155
163
|
assert_equal(3, line.label.graffle_id)
|
data/test/note-tests.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-07-19.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require "set-standalone-test-paths.rb" unless $started_from_rakefile
|
7
|
+
require 'test/unit'
|
8
|
+
require 's4t-utils'
|
9
|
+
include S4tUtils
|
10
|
+
|
11
|
+
require 'graffle'
|
12
|
+
require 'extensions/string'
|
13
|
+
|
14
|
+
# Notes need to have the same interface as Text, even though they
|
15
|
+
# have a different structure.
|
16
|
+
|
17
|
+
class TestNotes < Test::Unit::TestCase
|
18
|
+
include Graffle
|
19
|
+
include Graffle::Builders
|
20
|
+
|
21
|
+
def test_creation
|
22
|
+
assert_true(annotation("hello").behaves_like?(Note))
|
23
|
+
assert_equal("hello", annotation("hello"))
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
RTF = %Q{
|
28
|
+
| {\\rtf1\\mac\\ansicpg10000\\cocoartf824\\cocoasubrtf420
|
29
|
+
| {\\fonttbl\\f0\\fswiss\\fcharset77 Helvetica;}
|
30
|
+
| {\\colortbl;\\red255\\green255\\blue255;}
|
31
|
+
| \\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\qc\\pardirnatural
|
32
|
+
|
|
33
|
+
| \\f0\\fs24 \\cf0 John follows "sign up" link\\
|
34
|
+
| hi}}.trim('|')
|
35
|
+
|
36
|
+
|
37
|
+
def test_as_rtf_just_reproduces_input
|
38
|
+
assert_equal(RTF, annotation(RTF).as_rtf)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_as_plain_text_removes_rtf
|
42
|
+
assert_equal("John follows \"sign up\" link\nhi", annotation(RTF).as_plain_text)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_as_lines
|
46
|
+
assert_equal(["John follows \"sign up\" link", "hi"],
|
47
|
+
annotation(RTF).as_lines)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_plain_text_is_more_convenient_for_testing_so_allow_it
|
51
|
+
unrtf = %Q{John follows "sign up" link}
|
52
|
+
assert_equal(['John follows "sign up" link'],
|
53
|
+
annotation(unrtf).as_lines)
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def test_null_text_just_returns_empty_lines
|
58
|
+
assert_equal([], Note::Null.new.as_lines)
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -15,17 +15,17 @@ class TestOpeningOfDocuments < Test::Unit::TestCase
|
|
15
15
|
include Graffle
|
16
16
|
|
17
17
|
def test_reading_of_plain_file
|
18
|
-
document = Graffle.
|
18
|
+
document = Graffle.parse_file(relative("multiple-canvases.graffle"))
|
19
19
|
assert_equal(3, document.sheets.length)
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_reading_of_package
|
23
|
-
document = Graffle.
|
23
|
+
document = Graffle.parse_file(relative("as-a-package.graffle"))
|
24
24
|
assert_equal(1, document.sheets.length)
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_reading_of_file_with_lines
|
28
|
-
document = Graffle.
|
28
|
+
document = Graffle.parse_file(relative("two-boxes-and-a-line.graffle"))
|
29
29
|
assert_equal(1, document.sheets.length)
|
30
30
|
line = document.first_sheet.first_line
|
31
31
|
assert_equal("the line has a label", line.label_rtf.as_plain_text)
|
@@ -35,10 +35,15 @@ class TestOpeningOfDocuments < Test::Unit::TestCase
|
|
35
35
|
assert_equal('FilledArrow', line['Style']['stroke']['HeadArrow'])
|
36
36
|
end
|
37
37
|
|
38
|
+
def test_nonexistent_file_raises_exception
|
39
|
+
assert_raises(Errno::ENOENT) do
|
40
|
+
Graffle.parse_file("/no such file")
|
41
|
+
end
|
42
|
+
end
|
38
43
|
|
39
44
|
private
|
40
45
|
|
41
46
|
def relative(file)
|
42
|
-
File.join(PACKAGE_ROOT, 'test', '
|
47
|
+
File.join(PACKAGE_ROOT, 'test', 'sample-files', file)
|
43
48
|
end
|
44
49
|
end
|
File without changes
|
@@ -55,7 +55,7 @@ class TestShapedGraphics < Test::Unit::TestCase
|
|
55
55
|
| \\f0\\fs24 \\cf0 John follows "sign up" link}}.trim('|')
|
56
56
|
|
57
57
|
g = shaped_graphic {
|
58
|
-
|
58
|
+
with_content rtf
|
59
59
|
}
|
60
60
|
|
61
61
|
assert_true(g.has_content?)
|
@@ -77,12 +77,11 @@ class TestShapedGraphics < Test::Unit::TestCase
|
|
77
77
|
assert_equal([], shaped_graphic.content.as_lines)
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
80
|
def test_shaped_graphics_stereotypes_its_content
|
82
81
|
s = sheet {
|
83
82
|
with shaped_graphic {
|
84
83
|
graffle_id_is 333
|
85
|
-
|
84
|
+
with_content "foo"
|
86
85
|
}
|
87
86
|
with shaped_graphic { graffle_id_is 44 } # Check that this doesn't blow up
|
88
87
|
}
|