Skip to content

Commit

Permalink
Add FunctionName parameter to New-PSCodeHealthComplianceResult to get…
Browse files Browse the repository at this point in the history
… compliance results for a specific function
  • Loading branch information
MathieuBuisson committed Jul 5, 2017
1 parent a4a9392 commit 1099279
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 20 deletions.
30 changes: 25 additions & 5 deletions PSCodeHealth/Private/New-PSCodeHealthComplianceResult.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@ Function New-PSCodeHealthComplianceResult {
.PARAMETER Result
The compliance result, based on the compliance rule and the actual value from the health report.
.PARAMETER FunctionName
To get compliance results for a specific function.
If this parameter is specified, this creates a PSCodeHealth.Compliance.FunctionResult object, instead of PSCodeHealth.Compliance.Result.
.EXAMPLE
PS C:\> New-PSCodeHealthComplianceResult -ComplianceRule $Rule -Value 81.26 -Result Warning
Returns new custom object of the type PSCodeHealth.Compliance.Result.
.EXAMPLE
PS C:\> New-PSCodeHealthComplianceResult -ComplianceRule $Rule -Value 81.26 -Result Warning -FunctionName 'Get-Something'
Returns new custom object of the type PSCodeHealth.Compliance.FunctionResult for the function 'Get-Something'.
.OUTPUTS
PSCodeHealth.Compliance.Result
PSCodeHealth.Compliance.Result, PSCodeHealth.Compliance.FunctionResult
#>
[CmdletBinding()]
[OutputType([PSCustomObject])]
Expand All @@ -35,10 +44,13 @@ Function New-PSCodeHealthComplianceResult {

[Parameter(Mandatory, Position=2)]
[ValidateSet('Fail','Warning','Pass')]
[string]$Result
[string]$Result,

[Parameter(Mandatory=$False, Position=3)]
[string]$FunctionName
)

$ObjectProperties = [ordered]@{
$PropsDictionary = [ordered]@{
'SettingsGroup' = $ComplianceRule.SettingsGroup
'MetricName' = $ComplianceRule.MetricName
'WarningThreshold' = $ComplianceRule.WarningThreshold
Expand All @@ -48,7 +60,15 @@ Function New-PSCodeHealthComplianceResult {
'Result' = $Result
}

$CustomObject = New-Object -TypeName PSObject -Property $ObjectProperties
$CustomObject.psobject.TypeNames.Insert(0, 'PSCodeHealth.Compliance.Result')
If ( $PSBoundParameters.ContainsKey('FunctionName') ) {
$PropsDictionary.Insert(0, 'FunctionName', $FunctionName)

$CustomObject = New-Object -TypeName PSObject -Property $PropsDictionary
$CustomObject.psobject.TypeNames.Insert(0, 'PSCodeHealth.Compliance.FunctionResult')
}
Else {
$CustomObject = New-Object -TypeName PSObject -Property $PropsDictionary
$CustomObject.psobject.TypeNames.Insert(0, 'PSCodeHealth.Compliance.Result')
}
return $CustomObject
}
48 changes: 35 additions & 13 deletions PSCodeHealth/Public/Test-PSCodeHealthCompliance.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Function Test-PSCodeHealthCompliance {
There is a large number of metrics, so for convenience, all the possible values are available via tab completion.
If not specified, compliance is evaluated for all metrics.
.PARAMETER Function
.PARAMETER FunctionName
To get compliance results for a specific function.
This is a dynamic parameter which is available when the specified HealthReport contains at least 1 FunctionHealthRecords.
Expand Down Expand Up @@ -68,10 +68,10 @@ Function Test-PSCodeHealthCompliance {
In the case of TestCoverage, this metric exists in both PerFunctionMetrics and OverallMetrics, so this evaluates the compliance result for the TestCoverage metric from both groups.
.EXAMPLE
PS C:\> Test-PSCodeHealthCompliance -HealthReport $MyProjectHealthReport -Function 'Get-Something'
PS C:\> Test-PSCodeHealthCompliance -HealthReport $MyProjectHealthReport -FunctionName 'Get-Something'
Evaluates the compliance results specifically for the function Get-Something. Because this is the compliance of a specific function, only the per function metrics are evaluated.
If the value of the Function parameter doesn't match any function name in the HealthReport the parameter validation will fail and state the set of possible values.
If the value of the FunctionName parameter doesn't match any function name in the HealthReport the parameter validation will fail and state the set of possible values.
.EXAMPLE
PS C:\> Invoke-PSCodeHealth | Test-PSCodeHealthCompliance -Summary
Expand All @@ -81,7 +81,7 @@ Function Test-PSCodeHealthCompliance {
.OUTPUTS
PSCodeHealth.Compliance.Result, System.String
PSCodeHealth.Compliance.Result, PSCodeHealth.Compliance.FunctionResult, System.String
#>
[CmdletBinding()]
[OutputType([PSCustomObject[]], [string])]
Expand Down Expand Up @@ -110,10 +110,10 @@ Function Test-PSCodeHealthCompliance {
)

DynamicParam {
# The Function parameter is dynamic because the set of possible values depends on the FunctionHealthRecords contained in the specified HealthReport.
# The FunctionName parameter is dynamic because the set of possible values depends on the FunctionHealthRecords contained in the specified HealthReport.
If ( $HealthReport.FunctionHealthRecords.Count -gt 0 ) {

$ParameterName = 'Function'
$ParameterName = 'FunctionName'
# Creating a parameter dictionary
$RuntimeParameterDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary

Expand All @@ -133,21 +133,21 @@ Function Test-PSCodeHealthCompliance {
}

Begin {
If ( $RuntimeParameterDictionary ) { $Function = $RuntimeParameterDictionary[$ParameterName].Value }
If ( $RuntimeParameterDictionary ) { $FunctionName = $RuntimeParameterDictionary[$ParameterName].Value }
$Null = $PSBoundParameters.Remove('HealthReport')
If ( $PSBoundParameters.ContainsKey('Summary') ) {
$Null = $PSBoundParameters.Remove('Summary')
}
If ( $PSBoundParameters.ContainsKey('Function') ) {
$Null = $PSBoundParameters.Remove('Function')
If ( $PSBoundParameters.ContainsKey('FunctionName') ) {
$Null = $PSBoundParameters.Remove('FunctionName')
}
[System.Collections.ArrayList]$ComplianceResults = @()
$ComplianceRules = Get-PSCodeHealthComplianceRule @PSBoundParameters
Write-VerboseOutput "Evaluating the specified health report against $($ComplianceRules.Count) compliance rules."
}

Process {
$FunctionHealthRecords = If ($Function) {$HealthReport.FunctionHealthRecords | Where-Object FunctionName -eq $Function} Else {$HealthReport.FunctionHealthRecords}
$FunctionHealthRecords = If ($FunctionName) {$HealthReport.FunctionHealthRecords | Where-Object FunctionName -eq $FunctionName} Else {$HealthReport.FunctionHealthRecords}

Foreach ( $ComplianceRule in $ComplianceRules ) {
If ( $ComplianceRule.SettingsGroup -eq 'PerFunctionMetrics' ) {
Expand All @@ -164,7 +164,18 @@ Function Test-PSCodeHealthCompliance {
{ $_ -lt $ComplianceRule.WarningThreshold } { $ComplianceResult = 'Warning'; break}
Default { $ComplianceResult = 'Pass' }
}
$ComplianceResultObj = New-PSCodeHealthComplianceResult -ComplianceRule $ComplianceRule -Value $RetainedValue -Result $ComplianceResult

$ResultParams = @{
ComplianceRule = $ComplianceRule
Value = $RetainedValue
Result = $ComplianceResult
}
If ( $FunctionName ) {
$ComplianceResultObj = New-PSCodeHealthComplianceResult @ResultParams -FunctionName $FunctionName
}
Else {
$ComplianceResultObj = New-PSCodeHealthComplianceResult @ResultParams
}
$Null = $ComplianceResults.Add($ComplianceResultObj)
}
Else {
Expand All @@ -177,12 +188,23 @@ Function Test-PSCodeHealthCompliance {
{ $_ -gt $ComplianceRule.WarningThreshold } { $ComplianceResult = 'Warning'; break}
Default { $ComplianceResult = 'Pass' }
}
$ComplianceResultObj = New-PSCodeHealthComplianceResult -ComplianceRule $ComplianceRule -Value $RetainedValue -Result $ComplianceResult

$ResultParams = @{
ComplianceRule = $ComplianceRule
Value = $RetainedValue
Result = $ComplianceResult
}
If ( $FunctionName ) {
$ComplianceResultObj = New-PSCodeHealthComplianceResult @ResultParams -FunctionName $FunctionName
}
Else {
$ComplianceResultObj = New-PSCodeHealthComplianceResult @ResultParams
}
$Null = $ComplianceResults.Add($ComplianceResultObj)
}
}
}
ElseIf ( $ComplianceRule.SettingsGroup -eq 'OverallMetrics' -and -not($Function) ) {
ElseIf ( $ComplianceRule.SettingsGroup -eq 'OverallMetrics' -and -not($FunctionName) ) {
$MetricFromReport = $HealthReport.$($ComplianceRule.MetricName)
If ( $MetricFromReport -or $MetricFromReport -eq 0 ) {
If ( $ComplianceRule.HigherIsBetter ) {
Expand Down
33 changes: 33 additions & 0 deletions Tests/Unit/Private/New-PSCodeHealthComplianceResult.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,39 @@ Describe 'New-PSCodeHealthComplianceResult' {
$Result.Result | Should Be 'Pass'
}
}
Context 'The specified value is an [int32] and the FunctionName parameter is specified' {

$Result = New-PSCodeHealthComplianceResult -ComplianceRule $ComplianceRule -Value (10 -as [int32]) -Result 'Pass' -FunctionName 'Any'

It 'Should return an object of the type [PSCodeHealth.Compliance.FunctionResult]' {
$Result | Should BeOfType [PSCustomObject]
($Result | Get-Member).TypeName[0] | Should Be 'PSCodeHealth.Compliance.FunctionResult'
}
It 'Should return an object with the expected property "FunctionName"' {
$Result.FunctionName | Should Be 'any'
}
It 'Should return an object with the expected property "SettingsGroup"' {
$Result.SettingsGroup | Should Be 'PerFunctionMetrics'
}
It 'Should return an object with the expected property "MetricName"' {
$Result.MetricName | Should Be 'Complexity'
}
It 'Should return an object with the expected property "WarningThreshold"' {
$Result.WarningThreshold | Should Be 15
}
It 'Should return an object with the expected property "FailThreshold"' {
$Result.FailThreshold | Should Be 30
}
It 'Should return an object with the expected property "HigherIsBetter"' {
$Result.HigherIsBetter | Should Be $False
}
It 'Should return an object with the expected property "Value"' {
$Result.Value | Should Be 10
}
It 'Should return an object with the expected property "Result"' {
$Result.Result | Should Be 'Pass'
}
}
Context 'The specified value is an [double]' {

$Result = New-PSCodeHealthComplianceResult -ComplianceRule $ComplianceRule -Value (89.17 -as [double]) -Result 'Fail'
Expand Down
9 changes: 7 additions & 2 deletions Tests/Unit/Public/Test-PSCodeHealthCompliance.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,20 @@ Describe 'Test-PSCodeHealthCompliance' {
$HealthReport.psobject.TypeNames.Insert(0, 'PSCodeHealth.Overall.HealthReport')
$Results = Test-PSCodeHealthCompliance -HealthReport $HealthReport -Function 'Add-CoverageInfo'

It 'Should return object of the type [PSCodeHealth.Compliance.Result]' {
It 'Should return object of the type [PSCodeHealth.Compliance.FunctionResult]' {
Foreach ( $Result in $Results ) {
$Result | Should BeOfType [PSCustomObject]
($Result | Get-Member).TypeName[0] | Should Be 'PSCodeHealth.Compliance.Result'
($Result | Get-Member).TypeName[0] | Should Be 'PSCodeHealth.Compliance.FunctionResult'
}
}
It 'Should return 1 object per metric in group "PerFunctionMetrics"' {
$Results.Count | Should Be 6
}
It 'Should return objects with the property FunctionName "Add-CoverageInfo"' {
Foreach ( $Result in $Results ) {
$Result.FunctionName | Should Be 'Add-CoverageInfo'
}
}
It 'Resulting compliance rules are the same as the defaults for metric "LinesOfCode"' {
$LinesOfCodeResult = $Results.Where({$_.MetricName -eq 'LinesOfCode'})
$LinesOfCodeResult.WarningThreshold | Should Be 30
Expand Down

0 comments on commit 1099279

Please sign in to comment.