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