0
|
1 |
"{ Package: 'stx:goodies/sunit' }"
|
|
2 |
|
|
3 |
ApplicationModel subclass:#TestRunner
|
|
4 |
instanceVariableNames:'result lastPass defect allDefects defectMenu details mode
|
|
5 |
scriptModel script'
|
|
6 |
classVariableNames:''
|
|
7 |
poolDictionaries:''
|
|
8 |
category:'SUnitUI'
|
|
9 |
!
|
|
10 |
|
|
11 |
!TestRunner class methodsFor:'interface specs'!
|
|
12 |
|
|
13 |
windowSpec
|
|
14 |
"This resource specification was automatically generated
|
|
15 |
by the UIPainter of ST/X."
|
|
16 |
|
|
17 |
"Do not manually edit this!! If it is corrupted,
|
|
18 |
the UIPainter may not be able to read the specification."
|
|
19 |
|
|
20 |
"
|
|
21 |
UIPainter new openOnClass:TestRunner andSelector:#windowSpec
|
|
22 |
TestRunner new openInterface:#windowSpec
|
|
23 |
TestRunner open
|
|
24 |
"
|
|
25 |
|
|
26 |
<resource: #canvas>
|
|
27 |
|
|
28 |
^
|
|
29 |
#(#FullSpec
|
|
30 |
#name: #windowSpec
|
|
31 |
#window:
|
|
32 |
#(#WindowSpec
|
|
33 |
#label: 'SUnit Camp Smalltalk 2.7 TestRunner'
|
|
34 |
#name: 'SUnit Camp Smalltalk 2.7 TestRunner'
|
|
35 |
#min: #(#Point 362 122)
|
|
36 |
#bounds: #(#Rectangle 16 46 509 221)
|
|
37 |
)
|
|
38 |
#component:
|
|
39 |
#(#SpecCollection
|
|
40 |
#collection: #(
|
|
41 |
#(#ActionButtonSpec
|
|
42 |
#label: 'Refresh'
|
|
43 |
#name: 'Button3'
|
|
44 |
#layout: #(#LayoutFrame 0 0 0 0 75 0 24 0)
|
|
45 |
#model: #refreshSuites
|
|
46 |
)
|
|
47 |
#(#MenuButtonSpec
|
|
48 |
#label: 'ExampleSetTest'
|
|
49 |
#name: #tests
|
|
50 |
#layout: #(#LayoutFrame 76 0 0 0 -146 1 24 0)
|
|
51 |
#model: #script
|
|
52 |
#menu: #scriptModel
|
|
53 |
#useIndex: true
|
|
54 |
)
|
|
55 |
#(#ActionButtonSpec
|
|
56 |
#label: 'Run'
|
|
57 |
#name: 'Button1'
|
|
58 |
#layout: #(#LayoutFrame -145 1 0 0 -77 1 24 0)
|
|
59 |
#model: #runTests
|
|
60 |
#enableChannel: #enableRunButton
|
|
61 |
)
|
|
62 |
#(#ActionButtonSpec
|
|
63 |
#label: 'RunAll'
|
|
64 |
#name: 'Button2'
|
|
65 |
#layout: #(#LayoutFrame -76 1 0 0 0 1 24 0)
|
|
66 |
#model: #runAllTests
|
|
67 |
)
|
|
68 |
#(#LabelSpec
|
|
69 |
#label: 'N/A'
|
|
70 |
#name: 'mode'
|
|
71 |
#layout: #(#LayoutFrame 0 0 25 0 0 1 0 0.5)
|
|
72 |
#style: #(#FontDescription #Arial #bold #roman 14)
|
|
73 |
#labelChannel: #mode
|
|
74 |
)
|
|
75 |
#(#LabelSpec
|
|
76 |
#label: '...'
|
|
77 |
#name: 'details'
|
|
78 |
#layout: #(#LayoutFrame 0 0 0 0.5 0 1 -24 1)
|
|
79 |
#labelChannel: #details
|
|
80 |
)
|
|
81 |
#(#MenuButtonSpec
|
|
82 |
#name: #defects
|
|
83 |
#layout: #(#LayoutFrame 0 0 -24 1 -75 1 0 1)
|
|
84 |
#isOpaque: true
|
|
85 |
#flags: 40
|
|
86 |
#model: #selectionHolder
|
|
87 |
#initiallyDisabled: true
|
|
88 |
#enableChannel: #enableDefectsList
|
|
89 |
#menu: #defectMenu
|
|
90 |
)
|
|
91 |
#(#ActionButtonSpec
|
|
92 |
#label: 'Debug'
|
|
93 |
#name: 'Button4'
|
|
94 |
#layout: #(#LayoutFrame -75 1 -24 1 0 1 0 1)
|
|
95 |
#model: #debugSelectedFailure
|
|
96 |
#initiallyDisabled: true
|
|
97 |
#enableChannel: #enableDebugButton
|
|
98 |
)
|
|
99 |
)
|
|
100 |
|
|
101 |
)
|
|
102 |
)
|
|
103 |
! !
|
|
104 |
|
|
105 |
!TestRunner class methodsFor:'opening'!
|
|
106 |
|
|
107 |
open
|
|
108 |
|
5
|
109 |
^super open!
|
|
110 |
|
|
111 |
openOnTestCase:aTestCaseSubclass
|
|
112 |
|runner idx|
|
|
113 |
|
|
114 |
runner := self new.
|
|
115 |
runner open.
|
|
116 |
runner window waitUntilVisible.
|
|
117 |
idx := runner scriptModel value indexOf:aTestCaseSubclass name.
|
|
118 |
runner script value:idx.
|
|
119 |
|
|
120 |
"
|
|
121 |
self openOnTestCase:CompilerTest
|
|
122 |
"
|
|
123 |
! !
|
0
|
124 |
|
|
125 |
!TestRunner class methodsFor:'plugIn spec'!
|
|
126 |
|
|
127 |
aspectSelectors
|
|
128 |
"This resource specification was automatically generated
|
|
129 |
by the UIPainter of ST/X."
|
|
130 |
|
|
131 |
"Do not manually edit this. If it is corrupted,
|
|
132 |
the UIPainter may not be able to read the specification."
|
|
133 |
|
|
134 |
"Return a description of exported aspects;
|
|
135 |
these can be connected to aspects of an embedding application
|
|
136 |
(if this app is embedded in a subCanvas)."
|
|
137 |
|
|
138 |
^ #(
|
|
139 |
#script
|
|
140 |
).
|
|
141 |
|
|
142 |
! !
|
|
143 |
|
|
144 |
!TestRunner methodsFor:'Accessing'!
|
|
145 |
|
|
146 |
defectMenu
|
|
147 |
"automatically generated by UIPainter ..."
|
|
148 |
|
|
149 |
"*** the code below creates a default model when invoked."
|
|
150 |
"*** (which may not be the one you wanted)"
|
|
151 |
"*** Please change as required and accept it in the browser."
|
|
152 |
|
|
153 |
^defectMenu isNil
|
|
154 |
ifTrue: [defectMenu := OrderedCollection new asValue]
|
|
155 |
ifFalse: [defectMenu]
|
|
156 |
|
|
157 |
"Modified: / 4.4.2000 / 20:00:31 / Sames"
|
|
158 |
!
|
|
159 |
|
|
160 |
defects
|
|
161 |
|
|
162 |
^self builder componentAt: #defects
|
|
163 |
|
|
164 |
"Created: / 21.6.2000 / 12:19:29 / Sames"
|
|
165 |
!
|
|
166 |
|
|
167 |
details
|
|
168 |
"This method was generated by UIDefiner. Any edits made here
|
|
169 |
may be lost whenever methods are automatically defined. The
|
|
170 |
initialization provided below may have been preempted by an
|
|
171 |
initialize method."
|
|
172 |
|
|
173 |
^details isNil
|
|
174 |
ifTrue:
|
|
175 |
[details := '...' asValue]
|
|
176 |
ifFalse:
|
|
177 |
[details]!
|
|
178 |
|
|
179 |
mode
|
|
180 |
"This method was generated by UIDefiner. Any edits made here
|
|
181 |
may be lost whenever methods are automatically defined. The
|
|
182 |
initialization provided below may have been preempted by an
|
|
183 |
initialize method."
|
|
184 |
|
|
185 |
^mode isNil
|
|
186 |
ifTrue:
|
|
187 |
[mode := 'N/A' asValue]
|
|
188 |
ifFalse:
|
|
189 |
[mode]!
|
|
190 |
|
|
191 |
script
|
|
192 |
"automatically generated by UIPainter ..."
|
|
193 |
|
|
194 |
"*** the code below creates a default model when invoked."
|
|
195 |
"*** (which may not be the one you wanted)"
|
|
196 |
"*** Please change as required and accept it in the browser."
|
|
197 |
|
|
198 |
|holder|
|
|
199 |
|
|
200 |
(holder := builder bindingAt:#script) isNil ifTrue:[
|
|
201 |
holder := ValueHolder new.
|
|
202 |
builder aspectAt:#script put:holder.
|
|
203 |
"/ holder addDependent:self.
|
|
204 |
].
|
|
205 |
^ holder.
|
|
206 |
|
|
207 |
"Created: / 21.6.2000 / 12:04:36 / Sames"
|
|
208 |
!
|
|
209 |
|
|
210 |
script:something
|
|
211 |
"automatically generated by UIPainter ..."
|
|
212 |
|
|
213 |
"This method is used when I am embedded as subApplication,"
|
|
214 |
"and the mainApp wants to connect its aspects to mine."
|
|
215 |
|
|
216 |
"/ |holder|
|
|
217 |
|
|
218 |
"/ (holder := builder bindingAt:#script) notNil ifTrue:[
|
|
219 |
"/ holder removeDependent:self.
|
|
220 |
"/ ].
|
|
221 |
builder aspectAt:#script put:something.
|
|
222 |
"/ something notNil ifTrue:[
|
|
223 |
"/ something addDependent:self.
|
|
224 |
"/ ].
|
|
225 |
^ self.
|
|
226 |
|
|
227 |
"Created: / 21.6.2000 / 12:04:36 / Sames"
|
|
228 |
!
|
|
229 |
|
|
230 |
scriptModel
|
|
231 |
"This method was generated by UIDefiner. Any edits made here
|
|
232 |
may be lost whenever methods are automatically defined. The
|
|
233 |
initialization provided below may have been preempted by an
|
|
234 |
initialize method."
|
|
235 |
|
|
236 |
^scriptModel isNil
|
|
237 |
ifTrue: [scriptModel := (TestCase allSubclasses collect: [:each | each name]) asValue]
|
|
238 |
ifFalse: [scriptModel]
|
|
239 |
|
|
240 |
"Modified: / 2.4.2000 / 14:37:51 / Sames"
|
|
241 |
!
|
|
242 |
|
|
243 |
selection
|
|
244 |
|
|
245 |
^defect
|
|
246 |
|
|
247 |
"Created: / 4.4.2000 / 18:50:55 / Sames"
|
|
248 |
!
|
|
249 |
|
|
250 |
selectionHolder
|
|
251 |
"automatically generated by UIPainter ..."
|
|
252 |
|
|
253 |
"*** the code below creates a default model when invoked."
|
|
254 |
"*** (which may not be the one you wanted)"
|
|
255 |
"*** Please change as required and accept it in the browser."
|
|
256 |
|
|
257 |
|holder|
|
|
258 |
|
|
259 |
(holder := builder bindingAt:#selectionHolder) isNil ifTrue:[
|
|
260 |
holder := AspectAdaptor new subject:self; forAspect:#selection.
|
|
261 |
builder aspectAt:#selectionHolder put:holder.
|
|
262 |
"/ holder addDependent:self.
|
|
263 |
].
|
|
264 |
^ holder.
|
|
265 |
|
|
266 |
"Created: / 4.4.2000 / 18:46:08 / Sames"
|
|
267 |
"Modified: / 4.4.2000 / 18:47:31 / Sames"
|
|
268 |
!
|
|
269 |
|
|
270 |
tests
|
|
271 |
|
|
272 |
^self builder componentAt: #tests
|
|
273 |
|
|
274 |
"Created: / 4.4.2000 / 19:57:37 / Sames"
|
|
275 |
! !
|
|
276 |
|
|
277 |
!TestRunner methodsFor:'Actions'!
|
|
278 |
|
|
279 |
debugSelectedFailure
|
|
280 |
self debugTest: self selection
|
|
281 |
|
|
282 |
"Created: / 21.6.2000 / 10:58:58 / Sames"
|
|
283 |
"Modified: / 21.6.2000 / 12:21:05 / Sames"
|
|
284 |
!
|
|
285 |
|
|
286 |
debugTest: aTestCaseName
|
|
287 |
| testCase |
|
|
288 |
defect := aTestCaseName.
|
|
289 |
testCase := allDefects at: aTestCaseName ifAbsent: [nil].
|
|
290 |
testCase isNil ifTrue: [^self enableDebugButton value: false].
|
|
291 |
self enableDebugButton value: true.
|
|
292 |
self displayMode: 'Debugging'.
|
|
293 |
(result isFailure: testCase)
|
|
294 |
ifTrue: [testCase debugAsFailure]
|
|
295 |
ifFalse: [testCase debug]
|
|
296 |
|
|
297 |
"Modified: / 21.6.2000 / 12:12:09 / Sames"
|
|
298 |
!
|
|
299 |
|
|
300 |
enableDebugButton
|
|
301 |
"automatically generated by UIPainter ..."
|
|
302 |
"*** the code below creates a default model when invoked."
|
|
303 |
"*** (which may not be the one you wanted)"
|
|
304 |
"*** Please change as required and accept it in the browser."
|
|
305 |
|
|
306 |
| holder |
|
|
307 |
(holder := builder bindingAt: #enableDebugButton) isNil
|
|
308 |
ifTrue:
|
|
309 |
[holder := true asValue.
|
|
310 |
builder aspectAt: #enableDebugButton put: holder
|
|
311 |
" holder addDependent:self."].
|
|
312 |
^holder
|
|
313 |
|
|
314 |
"Created: / 21.6.2000 / 10:47:34 / Sames"
|
|
315 |
"Modified: / 21.6.2000 / 10:51:07 / Sames"
|
|
316 |
!
|
|
317 |
|
|
318 |
enableDefectsList
|
|
319 |
"automatically generated by UIPainter ..."
|
|
320 |
|
|
321 |
"*** the code below creates a default model when invoked."
|
|
322 |
"*** (which may not be the one you wanted)"
|
|
323 |
"*** Please change as required and accept it in the browser."
|
|
324 |
|
|
325 |
|holder|
|
|
326 |
|
|
327 |
(holder := builder bindingAt:#enableDefectsList) isNil ifTrue:[
|
|
328 |
holder := true asValue.
|
|
329 |
builder aspectAt:#enableDefectsList put:holder.
|
|
330 |
"/ holder addDependent:self.
|
|
331 |
].
|
|
332 |
^ holder.
|
|
333 |
|
|
334 |
"Created: / 21.6.2000 / 10:47:34 / Sames"
|
|
335 |
!
|
|
336 |
|
|
337 |
enableRunButton
|
|
338 |
"automatically generated by UIPainter ..."
|
|
339 |
|
|
340 |
"*** the code below creates a default model when invoked."
|
|
341 |
"*** (which may not be the one you wanted)"
|
|
342 |
"*** Please change as required and accept it in the browser."
|
|
343 |
|
|
344 |
|holder|
|
|
345 |
|
|
346 |
(holder := builder bindingAt:#enableRunButton) isNil ifTrue:[
|
|
347 |
holder := true asValue.
|
|
348 |
builder aspectAt:#enableRunButton put:holder.
|
|
349 |
"/ holder addDependent:self.
|
|
350 |
].
|
|
351 |
^ holder.
|
|
352 |
|
|
353 |
"Created: / 21.6.2000 / 10:47:34 / Sames"
|
|
354 |
!
|
|
355 |
|
|
356 |
refreshSuites
|
|
357 |
self scriptModel value: (TestCase allSubclasses collect: [:each | each name]).
|
|
358 |
self tests selection: 0.
|
|
359 |
self defects selection: 0.
|
|
360 |
result := TestResult new.
|
|
361 |
self displayRefresh
|
|
362 |
|
|
363 |
"Created: / 21.6.2000 / 10:58:34 / Sames"
|
|
364 |
"Modified: / 21.6.2000 / 12:19:54 / Sames"
|
|
365 |
!
|
|
366 |
|
|
367 |
runAllTests
|
|
368 |
self runSuite: self allTestSuite!
|
|
369 |
|
|
370 |
runSuite: aTestSuite
|
|
371 |
Cursor wait
|
|
372 |
showWhile:
|
|
373 |
[self displayRunning.
|
|
374 |
aTestSuite addDependentToHierachy: self.
|
|
375 |
[result := aTestSuite run]
|
|
376 |
ensure: [aTestSuite removeDependentFromHierachy: self].
|
|
377 |
self updateWindow]!
|
|
378 |
|
|
379 |
runTests
|
|
380 |
| testSuite |
|
|
381 |
(testSuite := self freshTestSuite) notNil ifTrue:
|
|
382 |
[self runSuite: testSuite]
|
|
383 |
|
|
384 |
"Modified: / 2.4.2000 / 14:16:10 / Sames"
|
|
385 |
!
|
|
386 |
|
|
387 |
selection: aValue
|
|
388 |
|
|
389 |
self debugTest: aValue
|
|
390 |
|
|
391 |
"Created: / 4.4.2000 / 18:54:09 / Sames"
|
|
392 |
"Modified: / 4.4.2000 / 19:01:33 / Sames"
|
|
393 |
!
|
|
394 |
|
|
395 |
suiteSelectionChanged
|
|
396 |
self enableRunButton value: self freshTestSuite notNil
|
|
397 |
|
|
398 |
"Created: / 21.6.2000 / 11:31:25 / Sames"
|
|
399 |
"Modified: / 21.6.2000 / 11:32:54 / Sames"
|
|
400 |
! !
|
|
401 |
|
|
402 |
!TestRunner methodsFor:'Private'!
|
|
403 |
|
|
404 |
allTestSuite
|
|
405 |
| tokens stream |
|
|
406 |
tokens := (TestCase subclasses collect: [:each | each name , '* '])
|
|
407 |
copyWithout: 'SUnitTest* '.
|
|
408 |
stream := WriteStream on: String new.
|
|
409 |
tokens do: [:each | stream nextPutAll: each].
|
|
410 |
^TestSuitesScripter run: stream contents!
|
|
411 |
|
|
412 |
formatTime: aTime
|
|
413 |
aTime hours > 0 ifTrue: [^aTime hours printString , 'h'].
|
|
414 |
aTime minutes > 0 ifTrue: [^aTime minutes printString , 'min'].
|
|
415 |
^aTime seconds printString , ' sec'!
|
|
416 |
|
|
417 |
freshTestSuite
|
|
418 |
|
|
419 |
^TestSuitesScripter run: self tests contents
|
|
420 |
|
|
421 |
"Modified: / 4.4.2000 / 20:13:41 / Sames"
|
|
422 |
!
|
|
423 |
|
|
424 |
postOpenWith: aBuilder
|
|
425 |
"automatically generated by UIPainter ..."
|
|
426 |
|
|
427 |
super postOpenWith: aBuilder.
|
|
428 |
self tests defaultLabel: ''.
|
|
429 |
self tests selection: 'ExampleSetTest'.
|
|
430 |
self enableDebugButton value: false.
|
|
431 |
self enableDefectsList value: false.
|
|
432 |
self script onChangeSend: #suiteSelectionChanged to: self
|
|
433 |
|
|
434 |
"Created: / 2.4.2000 / 14:44:32 / Sames"
|
|
435 |
"Modified: / 21.6.2000 / 12:06:30 / Sames"
|
|
436 |
!
|
|
437 |
|
|
438 |
timeSinceLastPassAsString
|
|
439 |
lastPass isNil ifTrue: [^''].
|
|
440 |
^', ' , (self formatTime: (Time now subtractTime: lastPass getSeconds)) , ' since last Pass'
|
|
441 |
|
|
442 |
"Modified: / 3.4.2000 / 19:17:11 / Sames"
|
|
443 |
! !
|
|
444 |
|
|
445 |
!TestRunner methodsFor:'Updating'!
|
|
446 |
|
|
447 |
displayColor: aColorValue
|
|
448 |
|
|
449 |
(builder componentAt: #mode) widget insideColor: aColorValue.
|
|
450 |
(builder componentAt: #details) widget insideColor: aColorValue.
|
|
451 |
|
|
452 |
"Modified: / 2.4.2000 / 14:21:42 / Sames"
|
|
453 |
!
|
|
454 |
|
|
455 |
displayDefault
|
|
456 |
self displayColor: self tests backgroundColor
|
|
457 |
|
|
458 |
"Created: / 21.6.2000 / 12:28:06 / Sames"
|
|
459 |
"Modified: / 21.6.2000 / 12:35:09 / Sames"
|
|
460 |
!
|
|
461 |
|
|
462 |
displayDefects: aCollection
|
|
463 |
| menuButton |
|
|
464 |
menuButton := self builder componentAt: #defects.
|
|
465 |
aCollection isEmpty ifTrue: [^menuButton disable].
|
|
466 |
allDefects := Dictionary new.
|
|
467 |
aCollection do: [:each | allDefects at: each printString put: each].
|
|
468 |
self defectMenu value: allDefects keys asOrderedCollection.
|
|
469 |
menuButton enable
|
|
470 |
|
|
471 |
"Modified: / 4.4.2000 / 20:11:06 / Sames"
|
|
472 |
!
|
|
473 |
|
|
474 |
displayDetails: aString
|
|
475 |
self details value: aString.
|
|
476 |
|
|
477 |
"Modified: / 21.6.2000 / 11:10:14 / Sames"
|
|
478 |
!
|
|
479 |
|
|
480 |
displayFail
|
|
481 |
self displayRed.
|
|
482 |
self displayMode: 'Fail'.
|
|
483 |
self displayDetails: result printString.!
|
|
484 |
|
|
485 |
displayGreen
|
|
486 |
self displayColor: ColorValue green!
|
|
487 |
|
|
488 |
displayMode: aString
|
|
489 |
self mode value: aString
|
|
490 |
|
|
491 |
"Modified: / 21.6.2000 / 11:14:19 / Sames"
|
|
492 |
!
|
|
493 |
|
|
494 |
displayPass
|
|
495 |
self displayMode: 'Pass'.
|
|
496 |
self displayDetails: result runCount printString , ' run' , self timeSinceLastPassAsString.
|
|
497 |
self displayGreen.
|
|
498 |
lastPass := Time now
|
|
499 |
|
|
500 |
"Modified: / 21.6.2000 / 12:14:52 / Sames"
|
|
501 |
!
|
|
502 |
|
|
503 |
displayRed
|
|
504 |
self displayColor: ColorValue red.!
|
|
505 |
|
|
506 |
displayRefresh
|
|
507 |
self displayMode: 'N/A'.
|
|
508 |
self displayDetails:'...'.
|
|
509 |
self updateDefects.
|
|
510 |
self enableRunButton value: false.
|
|
511 |
self enableDebugButton value: false.
|
|
512 |
self displayDefault
|
|
513 |
|
|
514 |
"Created: / 21.6.2000 / 12:14:11 / Sames"
|
|
515 |
"Modified: / 21.6.2000 / 12:28:24 / Sames"
|
|
516 |
!
|
|
517 |
|
|
518 |
displayRunning
|
|
519 |
self displayYellow.
|
|
520 |
self displayMode: 'running'.
|
|
521 |
self displayDetails: '...'.!
|
|
522 |
|
|
523 |
displayYellow
|
|
524 |
self displayColor: ColorValue yellow!
|
|
525 |
|
|
526 |
update: anObject
|
|
527 |
(anObject isKindOf: TestCase)
|
|
528 |
ifTrue: [self displayDetails: anObject printString]
|
|
529 |
ifFalse: [super update: anObject]!
|
|
530 |
|
|
531 |
updateDefects
|
|
532 |
self displayDefects: result defects!
|
|
533 |
|
|
534 |
updateWindow
|
|
535 |
result hasPassed
|
|
536 |
ifTrue: [self displayPass]
|
|
537 |
ifFalse: [self displayFail].
|
|
538 |
self updateDefects! !
|
|
539 |
|