reports/Builder__CoverageReport.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Wed, 15 May 2013 20:07:36 +0200
changeset 148 50cf14e8d665
parent 68 898a31eab2db
child 166 5bf6af786b93
permissions -rw-r--r--
class: Builder::ReportRunner class definition added: #cmdlineOptionSetup #cmdlineOptionTeardown changed: #main:

"{ Package: 'stx:goodies/builder/reports' }"

"{ NameSpace: Builder }"

TestReport subclass:#CoverageReport
	instanceVariableNames:'wrappers covered'
	classVariableNames:''
	poolDictionaries:''
	category:'Builder-Reports-Unfinished'
!


!CoverageReport methodsFor:'generating'!

generate
	| coverage |
	covered := (wrappers select: [ :each | each hasRun ])
		collect: [ :each | each reference ].
	coverage := StandardFileStream 
		forceNewFileNamed: suite name , '-Coverage.xml'.
	[ self generateOn: coverage ]
		ensure: [ coverage close ]
!

generateDataOn: aStream
	| items |
	aStream tab; nextPutAll: '<data>'; nextPut: Character lf.
	aStream tab; tab; nextPutAll: '<all name="all classes">'; nextPut: Character lf.
	self
		generateType: 'class' indent: 3
		total: (items := (packages gather: [ :each | each classes ]) asSet) size
		actual: ((covered collect: [ :each | each actualClass theNonMetaClass ]) asSet
			count: [ :each | items includes: each ])
		on: aStream.
	self
		generateType: 'method' indent: 3
		total: (items := (packages gather: [ :each | each methods ]) asSet) size 
		actual: (covered count: [ :each | items includes: each ])
		on: aStream.
	packages do: [ :each | self generatePackage: each on: aStream ].
	aStream tab; tab; nextPutAll: '</all>'; nextPut: Character lf.
	aStream tab; nextPutAll: '</data>'; nextPut: Character lf
!

generateOn: aStream
	aStream nextPutAll: '<?xml version="1.0" encoding="UTF-8"?>'; nextPut: Character lf.
	aStream nextPutAll: '<report>'; nextPut: Character lf.
	self generateStatsOn: aStream.
	self generateDataOn: aStream.
	aStream nextPutAll: '</report>'; nextPut: Character lf
!

generatePackage: aPackage class: aClass on: aStream
	| items |
	aStream tab: 4; nextPutAll: '<class name="'; nextPutAll: (self encode: aClass name); nextPutAll: '">'; nextPut: Character lf.
	self
		generateType: 'class' indent: 5
		total: 1
		actual: ((covered anySatisfy: [ :each | each actualClass theNonMetaClass = aClass ])
			ifTrue: [ 1 ] ifFalse: [ 0 ])
		on: aStream.
	self
		generateType: 'method' indent: 5
		total: (items := aPackage coreMethodsForClass: aClass) size
		actual: (covered count: [ :each | items includes: each ])
		on: aStream.
	items do: [ :each | self generatePackage: each method: each on: aStream ].	
	aStream tab: 4; nextPutAll: '</class>'; nextPut: Character lf
!

generatePackage: aPackage method: aReference on: aStream
	| items |
	aStream tab: 5; nextPutAll: '<method name="'; nextPutAll: (self encode: aReference selector); nextPutAll: '">'; nextPut: Character lf.
	self
		generateType: 'method' indent: 6
		total: 1
		actual: ((covered includes: aReference) ifTrue: [ 1 ] ifFalse: [ 0 ])
		on: aStream.
	aStream tab: 5; nextPutAll: '</method>'; nextPut: Character lf
!

generatePackage: aPackage on: aStream
	| items |
	aStream tab: 3; nextPutAll: '<package name="'; nextPutAll: (self encode: (aPackage packageName copyReplaceAll: '-' with: '.')); nextPutAll: '">'; nextPut: Character lf.
	self
		generateType: 'class' indent: 4
		total: (items := aPackage classes asSet) size
		actual: ((covered collect: [ :each | each actualClass theNonMetaClass ]) asSet
			count: [ :each | items includes: each ])
		on: aStream.
	self
		generateType: 'method' indent: 4
		total: (items := aPackage methods asSet) size
		actual: (covered count: [ :each | items includes: each ])
		on: aStream.
	aPackage classes 
		do: [ :class | self generatePackage: aPackage class: class on: aStream ].
	aStream tab: 3; nextPutAll: '</package>'; nextPut: Character lf
!

generateStatsOn: aStream
	aStream tab; nextPutAll: '<stats>'; nextPut: Character lf.
	aStream tab; tab; nextPutAll: '<packages value="'; print: (packages size); nextPutAll: '"/>'; nextPut: Character lf.
	aStream tab; tab; nextPutAll: '<classes value="'; print: (packages detectSum: [ :each | each classes size ]); nextPutAll: '"/>'; nextPut: Character lf.
	aStream tab; tab; nextPutAll: '<methods value="'; print: (packages detectSum: [ :each | each methods size ]); nextPutAll: '"/>'; nextPut: Character lf.
	aStream tab; nextPutAll: '</stats>'; nextPut: Character lf.
!

generateType: aString indent: anInteger total: totalInteger actual: actualInteger on: aStream
	aStream tab: anInteger; nextPutAll: '<coverage type="'; nextPutAll: aString; nextPutAll: ', %" value="'; print: (totalInteger = 0 ifTrue: [ 0 ] ifFalse: [ (100.0 * actualInteger / totalInteger) rounded ]); nextPutAll: '% ('; print: actualInteger; nextPut: $/; print: totalInteger; nextPutAll: ')"/>'; nextPut: Character lf
! !

!CoverageReport methodsFor:'private'!

addTestsIn: aTestAsserter to: aSet
        (aTestAsserter isKindOf: TestSuite) ifTrue: [
                aTestAsserter tests
                        do: [ :each | self addTestsIn: each to: aSet ] ].
        (aTestAsserter isKindOf: TestCase) ifTrue: [
                (aTestAsserter class respondsTo: #packageNamesUnderTest) ifTrue: [
                        aTestAsserter class packageNamesUnderTest
                                do: [ :each | aSet add: (self halt:'Not ported')"(PackageInfo named: each)" ] ] ].
        ^ aSet

    "Modified: / 08-03-2011 / 22:12:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

ignoredSelectors
	^ #(packageNamesUnderTest classNamesNotUnderTest)
!

methodsIn: aPackage
	aPackage isNil ifTrue: [ ^ #() ].
	^ aPackage methods reject: [ :method | 
		(self ignoredSelectors includes: method methodSymbol)
			or: [ method compiledMethod isAbstract
			or: [ method compiledMethod refersToLiteral: #ignoreForCoverage ] ] ]
!

packagesIn: aTestAsserter
	^ self addTestsIn: aTestAsserter to: Set new
! !

!CoverageReport methodsFor:'running'!

setUp
"/        super setUp.
"/        wrappers := ((packages := self packagesIn: suite)
"/                gather: [ :package | self methodsIn: package ])
"/                collect: [ :each | HDTestCoverage on: each ].
"/        wrappers do: [ :each | each install ]

    "Modified: / 15-05-2013 / 19:01:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

tearDown
	wrappers do: [ :each | each uninstall ].
	super tearDown.
	self generate
! !

!CoverageReport class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
!

version_SVN
    ^ '$Id$'
! !