Skip to content

Commit

Permalink
Add HtmlReportPath and PassThru parameters to Invoke-PSCodeHealth
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuBuisson committed Jul 1, 2017
1 parent cfbd78a commit 4492050
Show file tree
Hide file tree
Showing 9 changed files with 578 additions and 56 deletions.
2 changes: 1 addition & 1 deletion Examples/HtmlReport.html
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ <h2 class="panel-title"> Per Function Information</h2>
fontSize -= 1;
break;
}
} while (true)
} while (true);
ctx.restore();

// save properties
Expand Down
4 changes: 2 additions & 2 deletions PSCodeHealth/Assets/HealthReport.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
header > .row {
header > .row {
margin-bottom: 22px;
}
.left-header {
Expand Down Expand Up @@ -151,4 +151,4 @@
}
th.narrowColum {
width: 21%;
}
}
419 changes: 419 additions & 0 deletions PSCodeHealth/Assets/HealthReport.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion PSCodeHealth/Assets/HealthReport.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Chart.pluginService.register({
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.center) {
var helpers = Chart.helpers;
Expand Down
47 changes: 0 additions & 47 deletions PSCodeHealth/Assets/HealthReportTemplate.html

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ Function Set-PSCodeHealthPlaceholdersValue {

Foreach ( $Placeholder in $PlaceholdersData.GetEnumerator() ) {
$PlaceholderPattern = '{{{0}}}' -f $Placeholder.Key
$TemplateContent = $TemplateContent.ForEach('Replace', $PlaceholderPattern, $Placeholder.Value)

# Handling values containing a collection
$PlaceholderValue = If ( $($Placeholder.Value).Count -gt 1 ) { $Placeholder.Value | Out-String } Else { $Placeholder.Value }
$TemplateContent = $TemplateContent.ForEach('Replace', $PlaceholderPattern, $PlaceholderValue)
}
$TemplateContent
}
81 changes: 77 additions & 4 deletions PSCodeHealth/Public/Invoke-PSCodeHealth.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ Function Invoke-PSCodeHealth {
The value of this parameter qualifies the Path parameter.
Enter a path element or pattern, such as *example*. Wildcards are permitted.
.PARAMETER HtmlReportPath
To instruct Invoke-PSCodeHealth to generate an HTML report, and specify the path where the HTML file should be saved.
The path must include the folder path (which has to exist) and the file name.
.PARAMETER PassThru
When the parameter HtmlReportPath is used, by default, Invoke-PSCodeHealth doesn't output a [PSCodeHealth.Overall.HealthReport] object to the pipeline.
The PassThru parameter allows to instruct Invoke-PSCodeHealth to output both an HTML report file and a [PSCodeHealth.Overall.HealthReport] object.
.EXAMPLE
PS C:\> Invoke-PSCodeHealth -Path 'C:\GitRepos\MyModule' -Recurse -TestsPath 'C:\GitRepos\MyModule\Tests\Unit'
Expand All @@ -49,13 +57,19 @@ Function Invoke-PSCodeHealth {
Gets quality and maintainability metrics for code from PowerShell files in the directory C:\GitRepos\MyModule\ and any subdirectories, except for files containing "example" in their name.
This command will look for tests located in the directory C:\GitRepos\MyModule\Tests\, and any subdirectories.
.EXAMPLE
PS C:\> Invoke-PSCodeHealth -Path 'C:\GitRepos\MyModule' -TestsPath 'C:\GitRepos\MyModule\Tests' -HtmlReportPath .\Report.html -PassThru
Gets quality and maintainability metrics for code from PowerShell files in the directory C:\GitRepos\MyModule\.
This command will create an HTML report (Report.html) in the current directory and a PSCodeHealth.Overall.HealthReport object to the pipeline.
.OUTPUTS
PSCodeHealth.Overall.HealthReport
.NOTES
#>
[CmdletBinding()]
[CmdletBinding(DefaultParameterSetName = 'Default')]
[OutputType([PSCustomObject])]
Param (
[Parameter(Position=0, Mandatory=$False, ValueFromPipeline=$True)]
Expand All @@ -73,7 +87,15 @@ Function Invoke-PSCodeHealth {
[switch]$Recurse,

[Parameter(Mandatory=$False)]
[string[]]$Exclude
[string[]]$Exclude,

[Parameter(Mandatory, ParameterSetName='HtmlReport')]
[ValidateScript({ Test-Path -Path (Split-Path $_ -Parent) -PathType Container })]
[string]$HtmlReportPath,

[Parameter(Mandatory=$False, ParameterSetName='HtmlReport')]
[switch]$PassThru

)
If ( -not($PSBoundParameters.ContainsKey('Path')) ) {

Expand Down Expand Up @@ -142,9 +164,60 @@ Function Invoke-PSCodeHealth {
TestsPath = $TestsPath
}
If ( ($PSBoundParameters.ContainsKey('TestsResult')) ) {
New-PSCodeHealthReport @PSCodeHealthReportParams -TestsResult $PSBoundParameters.TestsResult
$HealthReport = New-PSCodeHealthReport @PSCodeHealthReportParams -TestsResult $PSBoundParameters.TestsResult
}
Else {
New-PSCodeHealthReport @PSCodeHealthReportParams
$HealthReport = New-PSCodeHealthReport @PSCodeHealthReportParams
}

If ( $PSCmdlet.ParameterSetName -ne 'HtmlReport' ) {
return $HealthReport
}
Else {
$JsPlaceholders = @{
NUMBER_OF_PASSED_TESTS = $HealthReport.NumberOfPassedTests
NUMBER_OF_FAILED_TESTS = $HealthReport.NumberOfFailedTests
TESTS_PASS_RATE = $HealthReport.TestsPassRate
TEST_COVERAGE = $HealthReport.TestCoverage
CODE_NOT_COVERED = 100 - $HealthReport.TestCoverage
}
$JsContent = Set-PSCodeHealthPlaceholdersValue -TemplatePath "$PSScriptRoot\..\Assets\HealthReport.js" -PlaceholdersData $JsPlaceholders

$HtmlPlaceholders = @{
REPORT_TITLE = $HealthReport.ReportTitle
CSS_CONTENT = Get-Content -Path "$PSScriptRoot\..\Assets\HealthReport.css"
ANALYZED_PATH = $HealthReport.AnalyzedPath
REPORT_DATE = $HealthReport.ReportDate
NUMBER_OF_FILES = $HealthReport.Files
NUMBER_OF_FUNCTIONS = $HealthReport.Functions
LINES_OF_CODE_TOTAL = $HealthReport.LinesOfCodeTotal
SCRIPTANALYZER_ERRORS = $HealthReport.ScriptAnalyzerErrors
SCRIPTANALYZER_WARNINGS = $HealthReport.ScriptAnalyzerWarnings
SCRIPTANALYZER_INFO = $HealthReport.ScriptAnalyzerInformation
SCRIPTANALYZER_TOTAL = $HealthReport.ScriptAnalyzerFindingsTotal
SCRIPTANALYZER_AVERAGE = $HealthReport.ScriptAnalyzerFindingsAverage
FUNCTIONS_WITHOUT_HELP = $HealthReport.FunctionsWithoutHelp
BEST_PRACTICES_TABLE_ROWS = ''
COMPLEXITY_HIGHEST = $HealthReport.ComplexityHighest
NESTING_DEPTH_HIGHEST = $HealthReport.NestingDepthHighest
LINES_OF_CODE_AVERAGE = $HealthReport.LinesOfCodeAverage
COMPLEXITY_AVERAGE = $HealthReport.ComplexityAverage
NESTING_DEPTH_AVERAGE = $HealthReport.NestingDepthAverage
MAINTAINABILITY_TABLE_ROWS = ''
NUMBER_OF_TESTS = $HealthReport.NumberOfTests
NUMBER_OF_FAILED_TESTS = $HealthReport.NumberOfFailedTests
NUMBER_OF_PASSED_TESTS = $HealthReport.NumberOfPassedTests
COMMANDS_MISSED = $HealthReport.CommandsMissedTotal
FAILED_TESTS_TABLE_ROWS = ''
COVERAGE_TABLE_ROWS = ''
JS_CONTENT = $JsContent
}
$HtmlContent = Set-PSCodeHealthPlaceholdersValue -TemplatePath "$PSScriptRoot\..\Assets\HealthReport.html" -PlaceholdersData $HtmlPlaceholders

$Null = New-Item -Path $HtmlReportPath -ItemType File -Force
Set-Content -Path $HtmlReportPath -Value $HtmlContent -Encoding UTF8
If ( $PassThru ) {
return $HealthReport
}
}
}
17 changes: 17 additions & 0 deletions Tests/Unit/Private/Set-PSCodeHealthPlaceholdersValue.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,22 @@ Describe 'Set-PSCodeHealthPlaceholdersValue' {
Should Be ' PSCodeHealth Report - StringValue1 <small class="analyzed-path"> StringValue2 - 2017-07-01 21:50:52Z</small>'
}
}
Context 'The PlaceholderData has placeholders values containing collections' {

$TestReportTitle = @('Line1','Line2','Line3','Line4')
$TestDate = @(1,2,3)
$PlaceholdersData = @{
REPORT_TITLE = $TestReportTitle
DATE = $TestDate
}
$Result = Set-PSCodeHealthPlaceholdersValue -TemplatePath $MockedFile.FullName -PlaceholdersData $PlaceholdersData

It 'Should add lines to the content for each multi-string placeholder value' {
($Result -split "`n").Count | Should Be (7 + ($TestReportTitle.Count * 2 + $TestDate.Count))
}
It 'Replaces properly a multi-string placeholder value in a line' {
$Result[0] | Should BeLike '<title>PSCodeHealth Report - Line1*Line2*Line3*Line4*</title>'
}
}
}
}
57 changes: 57 additions & 0 deletions Tests/Unit/Public/Invoke-PSCodeHealth2.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -276,5 +276,62 @@ Describe 'Invoke-PSCodeHealth (again)' {
$Result.FunctionHealthRecords.Count | Should Be 2
}
}
Context 'The HtmlReportPath parameter is specified but not PassThru' {

$PesterResult = $Mocks.'Invoke-Pester'.'NumberOfTests' | Where-Object { $_ }
$HealthReportParams = @{
Path = "$TestDrive\2PublicFunctions.psm1"
TestsResult = $PesterResult
HtmlReportPath = "$TestDrive\Report.html"
}
$Result = Invoke-PSCodeHealth @HealthReportParams

It 'Should output nothing to the pipeline' {
$Result | Should BeNullOrEmpty
}
It 'Should create the HTML file at the path specified via the HtmlReportPath parameter' {
Test-Path -Path "$TestDrive\Report.html" -PathType Leaf | Should Be $True
}
It 'Should create a HTML file bigger than the HTML template' {
(Get-Item -Path "$TestDrive\Report.html").Length | Should BeGreaterThan 23495
}
}
Context 'The HtmlReportPath and PassThru parameters are both specified' {

$PesterResult = $Mocks.'Invoke-Pester'.'NumberOfTests' | Where-Object { $_ }
$HealthReportParams = @{
Path = "$TestDrive\2PublicFunctions.psm1"
TestsResult = $PesterResult
HtmlReportPath = "$TestDrive\Report2.html"
PassThru = $True
}
$Result = Invoke-PSCodeHealth @HealthReportParams

It 'Should return an object of the type [PSCodeHealth.Overall.HealthReport]' {
$Result | Should BeOfType [PSCustomObject]
($Result | Get-Member).TypeName[0] | Should Be 'PSCodeHealth.Overall.HealthReport'
}
It 'Should create the HTML file at the path specified via the HtmlReportPath parameter' {
Test-Path -Path "$TestDrive\Report2.html" -PathType Leaf | Should Be $True
}
It 'Should create a HTML file bigger than the HTML template' {
(Get-Item -Path "$TestDrive\Report2.html").Length | Should BeGreaterThan 23495
}
}
Context 'The PassThru parameter is specified but not HtmlReportPath' {

$PesterResult = $Mocks.'Invoke-Pester'.'NumberOfTests' | Where-Object { $_ }
$HealthReportParams = @{
Path = "$TestDrive\2PublicFunctions.psm1"
TestsResult = $PesterResult
HtmlReportPath = $Null
PassThru = $True
}

It 'Should throw a "ParameterArgumentValidationError" exception' {
{ Invoke-PSCodeHealth @HealthReportParams } |
Should Throw "Cannot validate argument on parameter 'HtmlReportPath'."
}
}
}
}

0 comments on commit 4492050

Please sign in to comment.