import { CoverageReport } from './Model/CoverageReport' ; import { DiffCoverageReport } from './Model/DiffCoverageReport' ; import { CoverageData } from './Model/CoverageData' ; import { DiffFileCoverageData } from './Model/DiffFileCoverageData' ; import { DiffCoverageData } from './Model/DiffCoverageData' ; const increasedCoverageIcon = ':green_circle:' ; const decreasedCoverageIcon = ':red_circle:' ; const newCoverageIcon = ':sparkles: :new:' ; const removedCoverageIcon = ':x:' ; export class DiffChecker { private diffCoverageReport : DiffCoverageReport = { } ; constructor ( coverageReportNew , coverageReportOld ) { const reportNewKeys = Object . keys ( coverageReportNew ) ; const reportOldKeys = Object . keys ( coverageReportOld ) ; const reportKeys = new Set ( [ ... reportNewKeys , ... reportOldKeys ] ) ; for ( const filePath of reportKeys ) { this . diffCoverageReport [ filePath ] = { branches : { newPct : this . getPercentage ( coverageReportNew [ filePath ] ?. branches ) , oldPct : this . getPercentage ( coverageReportOld [ filePath ] ?. branches ) } , statements : { newPct : this . getPercentage ( coverageReportNew [ filePath ] ?. statements ) , oldPct : this . getPercentage ( coverageReportOld [ filePath ] ?. statements ) } , lines : { newPct : this . getPercentage ( coverageReportNew [ filePath ] ?. lines ) , oldPct : this . getPercentage ( coverageReportOld [ filePath ] ?. lines ) } , functions : { newPct : this . getPercentage ( coverageReportNew [ filePath ] ?. functions ) , oldPct : this . getPercentage ( coverageReportOld [ filePath ] ?. functions ) } } ; } } getCoverageDetails ( diffOnly , currentDirectory ) { const keys = Object . keys ( this . diffCoverageReport ) ; const returnStrings = [ ] ; for ( const key of keys ) { if ( this . compareCoverageValues ( this . diffCoverageReport [ key ] ) !== 0 ) { returnStrings . push ( this . createDiffLine ( key . replace ( currentDirectory , '' ) , this . diffCoverageReport [ key ] ) ) ; } else { if ( ! diffOnly ) { returnStrings . push ( `${ key . replace ( currentDirectory , '' ) } | ${ this . diffCoverageReport [ key ] . statements . newPct } | ${ this . diffCoverageReport [ key ] . branches . newPct } | ${ this . diffCoverageReport [ key ] . functions . newPct } | ${ this . diffCoverageReport [ key ] . lines . newPct }` ) ; } } } return returnStrings ; } checkIfTestCoverageFallsBelowDelta ( delta ) { const keys = Object . keys ( this . diffCoverageReport ) ; for ( const key of keys ) { const diffCoverageData = this . diffCoverageReport [ key ] ; const keys = < ( 'lines' | 'statements' | 'branches' | 'functions' ) [ ] > Object . keys ( diffCoverageData ) ; const fileRemovedCoverage = Object . values ( diffCoverageData ) . every ( coverageData => coverageData . newPct === 0 ) ; if ( fileRemovedCoverage ) { continue ; } for ( const key of keys ) { if ( diffCoverageData [ key ] . oldPct !== diffCoverageData [ key ] . newPct ) { if ( - this . getPercentageDiff ( diffCoverageData [ key ] ) > delta ) { return true ; } } } } return false ; } private createDiffLine ( name , diffFileCoverageData ) { const fileNewCoverage = Object . values ( diffFileCoverageData ) . every ( coverageData => coverageData . oldPct === 0 ) ; const fileRemovedCoverage = Object . values ( diffFileCoverageData ) . every ( coverageData => coverageData . newPct === 0 ) ; if ( fileNewCoverage ) { return ` ${ newCoverageIcon } | **${ name }** | **${ diffFileCoverageData . statements . newPct }** | **${ diffFileCoverageData . branches . newPct }** | **${ diffFileCoverageData . functions . newPct }** | **${ diffFileCoverageData . lines . newPct }**` ; } else if ( fileRemovedCoverage ) { return ` ${ removedCoverageIcon } | ~~${ name }~~ | ~~${ diffFileCoverageData . statements . oldPct }~~ | ~~${ diffFileCoverageData . branches . oldPct }~~ | ~~${ diffFileCoverageData . functions . oldPct }~~ | ~~${ diffFileCoverageData . lines . oldPct }~~` ; } const statusIcon = this . getStatusIcon ( diffFileCoverageData ) ; return ` ${ statusIcon } | ${ name } | ${ diffFileCoverageData . statements . newPct } **(${ this . getPercentageDiff ( diffFileCoverageData . statements ) })** | ${ diffFileCoverageData . branches . newPct } **(${ this . getPercentageDiff ( diffFileCoverageData . branches ) })** | ${ diffFileCoverageData . functions . newPct } **(${ this . getPercentageDiff ( diffFileCoverageData . functions ) })** | ${ diffFileCoverageData . lines . newPct } **(${ this . getPercentageDiff ( diffFileCoverageData . lines ) })**` ; } private compareCoverageValues ( diffCoverageData ) { const keys = < ( 'lines' | 'statements' | 'branches' | 'functions' ) [ ] > Object . keys ( diffCoverageData ) ; for ( const key of keys ) { if ( diffCoverageData [ key ] . oldPct !== diffCoverageData [ key ] . newPct ) { return 1 ; } } return 0 ; } private getPercentage ( coverageData ) { return coverageData ?. pct || 0 ; } private getStatusIcon ( diffFileCoverageData ) { let overallDiff = 0 ; Object . values ( diffFileCoverageData ) . forEach ( coverageData => { overallDiff = overallDiff + this . getPercentageDiff ( coverageData ) ; } ) ; if ( overallDiff < 0 ) { return decreasedCoverageIcon ; } return increasedCoverageIcon ; } private getPercentageDiff ( diffData ) { const diff = Number ( diffData . newPct ) - Number ( diffData . oldPct ) ; return Math . round ( ( diff + Number . EPSILON ) * 100 ) / 100 ; } }