author | Claus Gittinger <cg@exept.de> |
Sun, 01 Jul 2018 12:52:19 +0200 | |
changeset 719 | 2c96860ad5cb |
parent 677 | fd06505f4d59 |
child 744 | 7f03f8bc1a15 |
permissions | -rw-r--r-- |
345 | 1 |
"{ Package: 'stx:goodies/sunit' }" |
2 |
||
597 | 3 |
"{ NameSpace: Smalltalk }" |
4 |
||
345 | 5 |
TestResult subclass:#TestResultStX |
493 | 6 |
instanceVariableNames:'endTime' |
345 | 7 |
classVariableNames:'' |
8 |
poolDictionaries:'' |
|
9 |
category:'SUnit-Smalltalk/X' |
|
10 |
! |
|
11 |
||
12 |
||
500 | 13 |
!TestResultStX class methodsFor:'utilities'! |
14 |
||
15 |
sourceFilenameOfClass:aClass |
|
16 |
"that is ST/X specific" |
|
17 |
"no Smalltalk/X dialect detection needed..." |
|
18 |
||
19 |
|sourceStream testClassSourceFile| |
|
20 |
||
21 |
sourceStream := aClass sourceStream. |
|
22 |
sourceStream notNil ifTrue:[ |
|
23 |
[ |
|
24 |
sourceStream := sourceStream stream. |
|
25 |
sourceStream isFileStream ifTrue:[ |
|
26 |
testClassSourceFile := sourceStream pathName asFilename pathName. |
|
27 |
]. |
|
28 |
] ensure:[ |
|
670 | 29 |
sourceStream notNil ifTrue:[ sourceStream close ]. |
500 | 30 |
] |
31 |
]. |
|
32 |
^ testClassSourceFile |
|
33 |
! ! |
|
34 |
||
479 | 35 |
!TestResultStX methodsFor:'accessing'! |
36 |
||
37 |
endTime |
|
38 |
^ endTime |
|
39 |
! |
|
40 |
||
41 |
endTime:aTimestamp |
|
42 |
"sets the overall (suite) end time" |
|
43 |
||
44 |
endTime := aTimestamp. |
|
45 |
! |
|
46 |
||
482 | 47 |
executionTime |
48 |
"return the execution time (in seconds). If asked before or during a run, return nil" |
|
49 |
||
493 | 50 |
|t1 t2| |
51 |
||
52 |
(t1 := self startTime) isNil ifTrue:[^ nil]. |
|
53 |
(t2 := self endTime) isNil ifTrue:[^ nil]. |
|
54 |
^ t2 secondDeltaFrom: t1 |
|
482 | 55 |
|
56 |
" |
|
57 |
|a b| |
|
58 |
||
59 |
a := Timestamp now. |
|
60 |
Delay waitForMilliseconds:567. |
|
61 |
b := Timestamp now. |
|
62 |
b - a |
|
63 |
" |
|
64 |
! |
|
65 |
||
479 | 66 |
startTime |
493 | 67 |
^ timestamp |
479 | 68 |
! |
69 |
||
70 |
startTime:aTimestamp |
|
493 | 71 |
"sets the overall (suite) start time" |
479 | 72 |
|
493 | 73 |
timestamp := aTimestamp. |
479 | 74 |
! ! |
75 |
||
345 | 76 |
!TestResultStX methodsFor:'outcome'! |
77 |
||
500 | 78 |
printLineForContextForJavaCompatibleStackTrace:con on:aStream |
79 |
"why in java-backtrace format? |
|
80 |
Because then jenkins will be able to extract sourcefile and linenumber |
|
81 |
and generate links in the report page. |
|
82 |
I am not willing to write another plugin for this - using junit compatible format" |
|
83 |
||
597 | 84 |
|cls classSourceStream method s lineNumberOfMethod lineNumberInFile relPath methodSourcePosition| |
500 | 85 |
|
86 |
"/ used to be: |
|
87 |
"/ con printOn:aStream. |
|
88 |
||
89 |
"/ be careful: some tests generate methods on the fly, which are unbound!! |
|
90 |
"/ or even (javascript/other languages) may not have a method at all!!!! |
|
91 |
||
92 |
con fixAllLineNumbers. |
|
93 |
(method := con method) notNil ifTrue:[ |
|
94 |
cls := method mclass. |
|
95 |
cls notNil ifTrue:[ |
|
96 |
relPath := cls package copyReplaceAll:$: with:$/. |
|
593 | 97 |
relPath := relPath asUnixFilenameString. |
505 | 98 |
relPath := (relPath asFilename construct:cls theNonMetaclass classFilename) name. |
500 | 99 |
|
597 | 100 |
method isJavaMethod ifTrue:[ |
101 |
lineNumberOfMethod := method lineNumberForPC0: 0. |
|
102 |
] ifFalse:[ |
|
103 |
methodSourcePosition := method sourcePosition. |
|
104 |
methodSourcePosition notNil ifTrue:[ |
|
105 |
classSourceStream := cls sourceStream. |
|
106 |
classSourceStream notNil ifTrue:[ |
|
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
107 |
"/ sigh - we have the lineNumber within the method, |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
108 |
"/ and the characterPosition of the method's start. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
109 |
"/ need to calculate the absolute lineNumber in the file |
597 | 110 |
s := LineNumberReadStream on:classSourceStream "(classSourceFile asFilename readStream)". |
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
111 |
[ |
597 | 112 |
[s atEnd not and:[s position < methodSourcePosition]] whileTrue:[ |
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
113 |
s nextLine |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
114 |
]. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
115 |
lineNumberOfMethod := s lineNumber. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
116 |
] ensure:[ |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
117 |
s close. |
500 | 118 |
]. |
597 | 119 |
]. |
500 | 120 |
] |
121 |
] |
|
122 |
]. |
|
123 |
]. |
|
124 |
||
125 |
"/ output something (will not generate a ref to the source file) |
|
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
126 |
con printReceiverOn:aStream. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
127 |
aStream nextPutAll:' >> '. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
128 |
con selector printOn:aStream. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
129 |
aStream nextPutAll:' ['. |
597 | 130 |
con lineNumber printOn:aStream. |
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
131 |
aStream nextPut:$]. |
500 | 132 |
|
526 | 133 |
relPath notNil ifTrue:[ |
500 | 134 |
lineNumberOfMethod notNil ifTrue:[ |
135 |
lineNumberInFile := lineNumberOfMethod + con lineNumber - 1. |
|
136 |
aStream nextPutAll:(' (%1:%2)' |
|
526 | 137 |
bindWith: relPath |
500 | 138 |
with: lineNumberInFile) |
139 |
] ifFalse:[ |
|
140 |
aStream nextPutAll:(' (%1)' |
|
526 | 141 |
bindWith: relPath) |
500 | 142 |
]. |
143 |
]. |
|
144 |
aStream cr. |
|
145 |
||
146 |
"Modified: / 05-08-2012 / 12:00:00 / cg" |
|
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
147 |
"Modified: / 12-11-2013 / 23:09:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
500 | 148 |
! |
149 |
||
345 | 150 |
rememberEndTime |
479 | 151 |
"remembers the endTime of the current test (in outcome)" |
345 | 152 |
|
153 |
^outcome endTime: Timestamp now |
|
154 |
||
155 |
"Created: / 16-08-2011 / 17:36:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
156 |
! |
|
157 |
||
505 | 158 |
rememberException:ex |
345 | 159 |
"common for failure and error: |
677 | 160 |
called when a test fails. testCase is the failed |
161 |
testcase, ex is platform specific object describing |
|
162 |
the failure. Actually, on all platforms except GemStone, |
|
505 | 163 |
ex is an instance of an exception that caused the failure" |
345 | 164 |
|
165 |
|backtrace| |
|
166 |
||
167 |
((Smalltalk respondsTo:#isSmalltalkX) and:[Smalltalk isSmalltalkX]) ifTrue:[ |
|
168 |
"remember the backtrace (as string, to prevent objects from being kept forwever |
|
169 |
from being garbage collected, the signal (i.e. the exception class) and the |
|
170 |
exceptions message (description). |
|
677 | 171 |
Would like to have an exceptionInfo obejct for that, but that might be hard to |
345 | 172 |
get returned back into the main stream sunit package..." |
677 | 173 |
|
345 | 174 |
backtrace := String streamContents:[:s | |
175 |
|con topReached| |
|
176 |
||
177 |
"could use printAllOn:s, but noone is interested in contexts above the |
|
178 |
testcase's runtest context" |
|
179 |
topReached := false. |
|
505 | 180 |
con := ex suspendedContext. |
677 | 181 |
[ |
345 | 182 |
con notNil and:[topReached not] |
183 |
] whileTrue:[ |
|
500 | 184 |
self printLineForContextForJavaCompatibleStackTrace:con on:s. |
597 | 185 |
topReached := ((con selector == outcome selector) or:[con selector == #runCase]) |
465 | 186 |
and:[con receiver == outcome |
187 |
or:[ con receiver == outcome testCase ]]. |
|
345 | 188 |
con := con sender. |
189 |
] |
|
190 |
]. |
|
465 | 191 |
|
345 | 192 |
outcome exceptionDetail:(Dictionary new |
571
d5a1ac6d1743
use #creator instead of #signal
Claus Gittinger <cg@exept.de>
parents:
526
diff
changeset
|
193 |
at:#exception put:ex creator; |
505 | 194 |
at:#description put:ex description; |
345 | 195 |
at:#backtrace put:backtrace; |
196 |
yourself). |
|
197 |
^ self. |
|
198 |
]. |
|
199 |
||
200 |
"add other dialect specifics here" |
|
201 |
||
202 |
"Created: / 06-08-2011 / 11:29:23 / cg" |
|
203 |
"Created: / 16-08-2011 / 17:32:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
677 | 204 |
"Modified (format): / 22-05-2017 / 18:26:41 / mawalch" |
345 | 205 |
! |
206 |
||
207 |
rememberOutput: aString |
|
208 |
outcome collectedOutput: aString |
|
209 |
||
210 |
"Created: / 16-08-2011 / 18:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
211 |
! |
|
212 |
||
213 |
rememberStartTime |
|
479 | 214 |
"remembers the startTime of the current test (in outcome)" |
345 | 215 |
|
216 |
^outcome startTime: Timestamp now |
|
217 |
||
218 |
"Created: / 16-08-2011 / 17:36:16 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
219 |
! ! |
|
220 |
||
221 |
!TestResultStX methodsFor:'running'! |
|
222 |
||
223 |
performCase: aTestCase |
|
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
224 |
"while performing a testcase, any output to the Transcript is also |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
225 |
collected and is attached to the test result. Nice when tests are executed |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
226 |
automatically, for example by jenkins. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
227 |
Q: I think, we MUST lock this, |
655 | 228 |
or better: acquire the lock and making collecting explicit via |
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
229 |
call to 'self collectingTranscriptOutputDo:[...]' in the testcase. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
230 |
Otherwise we'll run into trouble, when executing multiple tests in parallel. |
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
231 |
" |
345 | 232 |
|
608 | 233 |
|savedStdout savedTranscript collector| |
345 | 234 |
|
235 |
savedStdout := Stdout. |
|
236 |
savedTranscript := Transcript. |
|
608 | 237 |
collector := CharacterWriteStream new:100. |
345 | 238 |
[ |
239 |
Stdout := SplittingWriteStream on:collector and: Stdout. |
|
240 |
Transcript := SplittingWriteStream on:collector and: Transcript. |
|
241 |
super performCase: aTestCase. |
|
242 |
] ensure:[ |
|
243 |
Stdout := savedStdout. |
|
244 |
Transcript := savedTranscript. |
|
245 |
self rememberOutput: collector contents. |
|
246 |
]. |
|
247 |
||
248 |
"Created: / 16-08-2011 / 18:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
580
d86ef51e98ab
Fix in TestResultStX>>#printLineForContextForJavaCompatibleStackTrace:on:
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
571
diff
changeset
|
249 |
"Modified (comment): / 29-08-2013 / 11:15:36 / cg" |
345 | 250 |
! ! |
251 |
||
252 |
!TestResultStX class methodsFor:'documentation'! |
|
253 |
||
254 |
version |
|
655 | 255 |
^ '$Header$' |
345 | 256 |
! |
257 |
||
258 |
version_CVS |
|
655 | 259 |
^ '$Header$' |
345 | 260 |
! ! |
571
d5a1ac6d1743
use #creator instead of #signal
Claus Gittinger <cg@exept.de>
parents:
526
diff
changeset
|
261 |