TestResultStX.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Sat, 09 Jul 2016 22:22:57 +0100
branchjv
changeset 658 05e8a3d70840
parent 655 a949c7616b2a
parent 622 feaff647974c
child 673 7c5c1bc3be7b
permissions -rw-r--r--
Merge

"{ Package: 'stx:goodies/sunit' }"

"{ NameSpace: Smalltalk }"

TestResult subclass:#TestResultStX
	instanceVariableNames:'endTime'
	classVariableNames:''
	poolDictionaries:''
	category:'SUnit-Smalltalk/X'
!


!TestResultStX class methodsFor:'utilities'!

sourceFilenameOfClass:aClass
    "that is ST/X specific"
    "no Smalltalk/X dialect detection needed..."

    |sourceStream testClassSourceFile|

    sourceStream := aClass sourceStream.
    sourceStream notNil ifTrue:[
        [
            sourceStream := sourceStream stream.
            sourceStream isFileStream ifTrue:[
                testClassSourceFile := sourceStream pathName asFilename pathName.
            ].
        ] ensure:[
            sourceStream close.
        ]
    ].
    ^ testClassSourceFile
! !

!TestResultStX methodsFor:'accessing'!

endTime
    ^ endTime
!

endTime:aTimestamp
    "sets the overall (suite) end time"

    endTime := aTimestamp.
!

executionTime
    "return the execution time (in seconds). If asked before or during a run, return nil"

    |t1 t2|

    (t1 := self startTime) isNil ifTrue:[^ nil].
    (t2 := self endTime) isNil ifTrue:[^ nil].
    ^ t2 secondDeltaFrom: t1

    "
     |a b|

     a := Timestamp now.
     Delay waitForMilliseconds:567.
     b := Timestamp now.
     b - a   
    "
!

startTime
    ^ timestamp
!

startTime:aTimestamp
    "sets the overall (suite) start time"

    timestamp := aTimestamp.
! !

!TestResultStX methodsFor:'outcome'!

printLineForContextForJavaCompatibleStackTrace:con on:aStream
    "why in java-backtrace format?
     Because then jenkins will be able to extract sourcefile and linenumber
     and generate links in the report page.
     I am not willing to write another plugin for this - using junit compatible format"

    |cls classSourceStream method s lineNumberOfMethod lineNumberInFile relPath methodSourcePosition|

    "/ used to be:
    "/ con printOn:aStream.

    "/ be careful: some tests generate methods on the fly, which are unbound!!
    "/ or even (javascript/other languages) may not have a method at all!!!!

    con fixAllLineNumbers.
    (method := con method) notNil ifTrue:[
        cls := method mclass.
        cls notNil ifTrue:[
            relPath := cls package copyReplaceAll:$: with:$/.
            relPath := relPath asUnixFilenameString.
            relPath := (relPath asFilename construct:cls theNonMetaclass classFilename) name.

            method isJavaMethod ifTrue:[
                lineNumberOfMethod :=  method lineNumberForPC0: 0.
            ] ifFalse:[
                methodSourcePosition := method sourcePosition.
                methodSourcePosition notNil ifTrue:[
                    classSourceStream := cls sourceStream.
                    classSourceStream notNil ifTrue:[
                        "/ sigh - we have the lineNumber within the method,
                        "/ and the characterPosition of the method's start.
                        "/ need to calculate the absolute lineNumber in the file
                        s := LineNumberReadStream on:classSourceStream "(classSourceFile asFilename readStream)".
                        [
                            [s atEnd not and:[s position < methodSourcePosition]] whileTrue:[
                                s nextLine
                            ].
                            lineNumberOfMethod := s lineNumber.
                        ] ensure:[
                            s close.
                        ].
                    ].
                ]
            ]
        ].
    ].

    "/ output something (will not generate a ref to the source file)
    con printReceiverOn:aStream.
    aStream nextPutAll:' >> '.
    con selector printOn:aStream.
    aStream nextPutAll:' ['.
    con lineNumber printOn:aStream.
    aStream nextPut:$].

    relPath notNil ifTrue:[
        lineNumberOfMethod notNil ifTrue:[
            lineNumberInFile := lineNumberOfMethod + con lineNumber - 1.
            aStream nextPutAll:(' (%1:%2)'
                                bindWith: relPath
                                with: lineNumberInFile)
        ] ifFalse:[
            aStream nextPutAll:(' (%1)'
                                bindWith: relPath)
        ].
    ].
    aStream cr.

    "Modified: / 05-08-2012 / 12:00:00 / cg"
    "Modified: / 12-11-2013 / 23:09:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

rememberEndTime
    "remembers the endTime of the current test (in outcome)"

    ^outcome endTime: Timestamp now

    "Created: / 16-08-2011 / 17:36:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

rememberException:ex
    "Called when a test fails. testCase is the failed 
     testcase, ex is platform specific object describing 
     the failure. Actually, on all platforms exept GemStone, 
     ex is an instance of an exception that caused the failure"

    ((Smalltalk respondsTo:#isSmalltalkX) and:[Smalltalk isSmalltalkX]) ifTrue:[
        "Do not remember the exception itself as it would prevent objects from
         being garbage collected. Also do not collect backtrace as most of the
         time nobody's interested in it.

         Keep in mind, that standalone test runner uses it's own testresult
         to remember stacktraces for reports. See Builder::TestRunner."
        outcome exceptionDetail:(Dictionary new
                                    at:#exception put:ex creator;
                                    at:#description put:ex description;
                                    yourself).
        ^ self.
    ].

    "add other dialect specifics here"

    "Created: / 06-08-2011 / 11:29:23 / cg"
    "Created: / 16-08-2011 / 17:32:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 12-09-2015 / 08:38:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

rememberOutput: aString
    outcome collectedOutput: aString

    "Created: / 16-08-2011 / 18:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

rememberStartTime
    "remembers the startTime of the current test (in outcome)"

    ^outcome startTime: Timestamp now

    "Created: / 16-08-2011 / 17:36:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!TestResultStX methodsFor:'running'!

performCase: aTestCase
    "while performing a testcase, any output to the Transcript is also
     collected and is attached to the test result. Nice when tests are executed
     automatically, for example by jenkins.
     Q: I think, we MUST lock this, 
        or better: acquire the lock and making collecting explicit via
                   call to 'self collectingTranscriptOutputDo:[...]' in the testcase.
        Otherwise we'll run into trouble, when executing multiple tests in parallel.
"

    |savedStdout savedTranscript collector|

    savedStdout := Stdout.
    savedTranscript := Transcript.
    collector := CharacterWriteStream new:100.
    [
        Stdout := SplittingWriteStream on:collector and: Stdout.
        Transcript := SplittingWriteStream on:collector and: Transcript.
        super performCase: aTestCase.
    ] ensure:[
        Stdout := savedStdout.
        Transcript := savedTranscript.
        self rememberOutput: collector contents.
    ].

    "Created: / 16-08-2011 / 18:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (comment): / 29-08-2013 / 11:15:36 / cg"
! !

!TestResultStX class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
!

version_HG

    ^ '$Changeset: <not expanded> $'
! !