Skip to content

Commit 786ab69

Browse files
committed
Test and fix Get-ParameterValue
1 parent b47292d commit 786ab69

5 files changed

Lines changed: 183 additions & 102 deletions

File tree

‎Source/Public/Get-ParameterValue.ps1‎

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function Get-ParameterValue {
3939
PSVariable = $PSCmdlet.SessionState.PSVariable
4040
ErrorAction = "SilentlyContinue"
4141
}
42+
Write-Debug "Importing $FromFile"
4243
$FileValues = Import-Metadata $FromFile @MetadataOptions
4344
if ($CommandKey) {
4445
$FileValues = $FileValues.$CommandKey
@@ -57,9 +58,10 @@ function Get-ParameterValue {
5758
Write-Debug " Parameter: $($parameter.key)"
5859
$key = $parameter.Key
5960

61+
# Support parameter aliases in the config file by changing the alias to the parameter name
6062
# If the value is not in the file defaults AND was not set by the user ...
61-
if (-not $FileDefaults.ContainsKey($key) -and -not $BoundParameters.ContainsKey($key)) {
62-
# Support parameter aliases in the config file (by changing their names)
63+
if ($FromFile -and -not $FileDefaults.ContainsKey($key) -and -not $BoundParameters.ContainsKey($key)) {
64+
# Check if any of the aliases are in the file defaults
6365
Write-Debug " Aliases: $($parameter.Value.Aliases -join ', ')"
6466
foreach ($k in @($parameter.Value.Aliases)) {
6567
if ($null -ne $k -and $FileDefaults.ContainsKey($k)) {
@@ -71,30 +73,30 @@ function Get-ParameterValue {
7173
}
7274
}
7375

76+
# Bound parameter values > build.psd1 values > default parameters values
7477
if ($CallersInvocation) {
75-
# If it's in the defaults AND it was not already set at a higher precedence
76-
if ($FileDefaults.ContainsKey($Parameter) -and -not ($BoundParameters.ContainsKey($Parameter))) {
78+
# If it's in the file defaults (now) AND it was not already set at a higher precedence
79+
if ($FromFile -and $FileDefaults.ContainsKey($Parameter) -and -not ($BoundParameters.ContainsKey($Parameter))) {
7780
Write-Debug "Export $Parameter = $($FileDefaults[$Parameter])"
7881
$BoundParameters[$Parameter] = $FileDefaults[$Parameter]
7982
# Set the variable in the _callers_ SessionState as well as our return hashtable
8083
$PSCmdlet.SessionState.PSVariable.Set($Parameter, $FileDefaults[$Parameter])
81-
}
82-
83-
# Bound parameter values > build.psd1 values > default parameters values
84-
if (-not $FileDefaults.ContainsKey($key) -and -not $BoundParameters.ContainsKey($key)) {
84+
# If it's still NOT in the file defaults and was not already set, check if there's a default value
85+
} elseif (-not $FileDefaults.ContainsKey($key) -and -not $BoundParameters.ContainsKey($key)) {
8586
# Reading the current value of the $key variable returns either the bound parameter or the default
8687
if ($null -ne ($value = $PSCmdlet.SessionState.PSVariable.Get($key).Value)) {
88+
Write-Debug " From Default: $($BoundParameters[$key] -join ', ')"
8789
if ($value -ne ($null -as $parameter.Value.ParameterType)) {
8890
$BoundParameters[$key] = $value
8991
}
9092
}
91-
if ($BoundParameters.ContainsKey($key)) {
92-
Write-Debug " From Parameter: $($BoundParameters[$key] -join ', ')"
93-
} elseif ($BoundParameters[$key]) {
94-
Write-Debug " From Default: $($BoundParameters[$key] -join ', ')"
95-
}
93+
# Otherwise, it was set by the user, or ...
94+
} elseif ($BoundParameters[$key]) {
95+
Write-Debug " From Parameter: $($BoundParameters[$key] -join ', ')"
96+
# We'll set it from the file
9697
} elseif ($FileDefaults[$key]) {
9798
Write-Debug " From File: $($FileDefaults[$key] -join ', ')"
99+
$BoundParameters[$key] = $FileDefaults[$key]
98100
}
99101
}
100102
}

‎Specs/Configuration.Steps.ps1‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ Then "a settings file named (\S+) should exist(?:(?: in the (?<Scope>\S+) folder
768768
}
769769

770770
Given "a passthru command '(?<Command>[A-Z][a-z]+-[A-Z][a-z]+)' with (?<Parameters>.*) parameters" {
771-
param($Command, $Parameters)
771+
param($Command, $Parameters)
772772

773773
[string[]]$Parameters = $Parameters -split "\s*and\s*" | % { $_.Trim("['`"]") }
774774

@@ -787,6 +787,26 @@ Given "a passthru command '(?<Command>[A-Z][a-z]+-[A-Z][a-z]+)' with (?<Paramete
787787
Invoke-Expression $Function
788788
}
789789

790+
Given "a passthru command '(?<Command>[A-Z][a-z]+-[A-Z][a-z]+)' with (?<Parameters>.*) parameters that calls Get-ParameterValue(?<FromFile> with a file config)?" {
791+
param($Command, $Parameters, $FromFile)
792+
793+
[string[]]$Parameters = $Parameters -split "\s*and\s*"
794+
795+
$Function = "
796+
function $Command {
797+
param(
798+
`$$($Parameters -join ", `$"),
799+
[Alias('Alias')]
800+
`$ExtraParameter
801+
)
802+
`$global:DebugPreference = 'Continue'
803+
Get-ParameterValue $(if($FromFile){ "-FromFile Verb.psd1" })
804+
`$global:DebugPreference = 'SilentlyContinue'
805+
}
806+
"
807+
Invoke-Expression $Function
808+
}
809+
790810
Given "an example New-User command" {
791811
function New-User {
792812
[CmdletBinding()]

‎Specs/ConfiguredParameters.feature‎

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
Feature: Configure Command From Working Directory
2+
3+
There is a command to support loading default parameter values from the working directory
4+
5+
Background:
6+
Given the configuration module is imported with testing paths:
7+
| Enterprise | User | Machine |
8+
| TestDrive:/EnterprisePath | TestDrive:/UserPath | TestDrive:/MachinePath |
9+
10+
@Functions @Import
11+
Scenario: Loading Default Settings
12+
Given a passthru command 'Test-Verb' with UserName and Age parameters
13+
And a settings file named Verb.psd1 in the current folder
14+
"""
15+
@{
16+
UserName = 'Joel'
17+
Age = 42
18+
}
19+
"""
20+
When I call Test-Verb
21+
Then the output object's use rName should be Joel
22+
And the output object's Age should be 42
23+
24+
@Functions @Import
25+
Scenario: Overriding Default Settings
26+
Given a passthru command 'Test-Verb' with UserName and Age parameters
27+
And a settings file named Verb.psd1 in the current folder
28+
"""
29+
@{
30+
UserName = 'Joel'
31+
Age = 42
32+
}
33+
"""
34+
When I call Test-Verb Mark
35+
Then the output object's userName should be Mark
36+
And the output object's Age should be 42
37+
38+
@Functions @Import
39+
Scenario: Overriding Default Settings Works on any Parameter
40+
Given a passthru command 'Test-Verb' with UserName and Age parameters
41+
And a settings file named Verb.psd1 in the current folder
42+
"""
43+
@{
44+
UserName = 'Joel'
45+
Age = 42
46+
}
47+
"""
48+
When I call Test-Verb -Age 10
49+
Then the output object's userName should be Joel
50+
And the output object's Age should be 10
51+
52+
@Functions @Import
53+
Scenario: New-User Example
54+
Given an example New-User command
55+
And a settings file named User.psd1 in the current folder
56+
"""
57+
@{
58+
Domain = 'HuddledMasses.org'
59+
}
60+
"""
61+
When I call New-User Joel Bennett
62+
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
63+
64+
@Functions @Import
65+
Scenario: New-User Example Two (overwriting)
66+
Given an example New-User command
67+
And a settings file named User.psd1 in the current folder
68+
"""
69+
@{
70+
Permissions = @{
71+
Access = "Administrator"
72+
}
73+
}
74+
"""
75+
And a settings file named User.psd1 in the parent folder
76+
"""
77+
@{
78+
Department = "Security"
79+
Permissions = @{
80+
Access = "User"
81+
}
82+
}
83+
"""
84+
And a settings file named User.psd1
85+
"""
86+
@{
87+
Domain = "HuddledMasses.org"
88+
}
89+
"""
90+
When I call New-User Joel Bennett
91+
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
92+
And the output object's Department should be Security
93+
And the output object's Permissions should be of type [hashtable]
94+
And the output object's Permissions.Access should be Administrator
95+
96+
97+
@Functions @Import
98+
Scenario: New-User Example Three
99+
Given an example New-User command
100+
And a settings file named SecurityUser.psd1 in the current folder
101+
"""
102+
@{
103+
Domain = 'HuddledMasses.org'
104+
Permissions = @{
105+
Access = "Administrator"
106+
}
107+
}
108+
"""
109+
When I call New-User Joel Bennett -Department Security
110+
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
111+
And the output object's Permissions should be of type [hashtable]
112+
And the output object's Permissions.Access should be of type [string]
113+
And the output object's Permissions.Access should be Administrator

‎Specs/DefaultParameters.feature‎

Lines changed: 32 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,58 @@
1-
Feature: Configure Command From Working Directory
1+
Feature: Get PSBoundParameters plus default values plus a config file
22

3-
There is a command to support loading default parameter values from the working directory
3+
There is a command to support merging PSBoundParameters with parmeter default values
4+
That command supports overwriting the default values with values from a config file
45

56
Background:
6-
Given the configuration module is imported with testing paths:
7-
| Enterprise | User | Machine |
8-
| TestDrive:/EnterprisePath | TestDrive:/UserPath | TestDrive:/MachinePath |
7+
Given the configuration module is imported
98

10-
@Functions @Import
9+
@Functions @ParameterValue
1110
Scenario: Loading Default Settings
12-
Given a passthru command 'Test-Verb' with UserName and Age parameters
13-
And a settings file named Verb.psd1 in the current folder
14-
"""
15-
@{
16-
UserName = 'Joel'
17-
Age = 42
18-
}
19-
"""
20-
When I call Test-Verb
21-
Then the output object's userName should be Joel
11+
Given a passthru command 'Test-Verb' with UserName and Age=42 parameters that calls Get-ParameterValue
12+
When I call Test-Verb Joel
13+
Then the output object's UserName should be Joel
2214
And the output object's Age should be 42
2315

24-
@Functions @Import
16+
@Functions @ParameterValue
17+
Scenario: Loading Default Settings
18+
Given a passthru command 'Test-Verb' with UserName and Age=12 parameters that calls Get-ParameterValue
19+
When I call Test-Verb Joel
20+
Then the output object's UserName should be Joel
21+
And the output object's Age should be 12
22+
23+
@Functions @ParameterValue
2524
Scenario: Overriding Default Settings
26-
Given a passthru command 'Test-Verb' with UserName and Age parameters
25+
Given a passthru command 'Test-Verb' with UserName='Sarah' and Age=12 parameters that calls Get-ParameterValue
26+
When I call Test-Verb Joel 24
27+
Then the output object's UserName should be Joel
28+
And the output object's Age should be 24
29+
30+
@Functions @ParameterValue
31+
Scenario: Configuration file
32+
Given a passthru command 'Test-Verb' with UserName='Sarah' and Age=12 parameters that calls Get-ParameterValue with a file config
2733
And a settings file named Verb.psd1 in the current folder
2834
"""
2935
@{
3036
UserName = 'Joel'
3137
Age = 42
3238
}
3339
"""
34-
When I call Test-Verb Mark
35-
Then the output object's userName should be Mark
36-
And the output object's Age should be 42
40+
When I call Test-Verb -Age 10
41+
Then the output object's userName should be Joel
42+
And the output object's Age should be 10
3743

38-
@Functions @Import
39-
Scenario: Overriding Default Settings Works on any Parameter
40-
Given a passthru command 'Test-Verb' with UserName and Age parameters
44+
@Functions @ParameterValue
45+
Scenario: Configuration file with aliases
46+
Given a passthru command 'Test-Verb' with UserName='Sarah' and Age=12 parameters that calls Get-ParameterValue with a file config
4147
And a settings file named Verb.psd1 in the current folder
4248
"""
4349
@{
4450
UserName = 'Joel'
4551
Age = 42
52+
Alias = 'Supports Aliases'
4653
}
4754
"""
4855
When I call Test-Verb -Age 10
4956
Then the output object's userName should be Joel
5057
And the output object's Age should be 10
51-
52-
@Functions @Import
53-
Scenario: New-User Example
54-
Given an example New-User command
55-
And a settings file named User.psd1 in the current folder
56-
"""
57-
@{
58-
Domain = 'HuddledMasses.org'
59-
}
60-
"""
61-
When I call New-User Joel Bennett
62-
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
63-
64-
@Functions @Import
65-
Scenario: New-User Example Two (overwriting)
66-
Given an example New-User command
67-
And a settings file named User.psd1 in the current folder
68-
"""
69-
@{
70-
Permissions = @{
71-
Access = "Administrator"
72-
}
73-
}
74-
"""
75-
And a settings file named User.psd1 in the parent folder
76-
"""
77-
@{
78-
Department = "Security"
79-
Permissions = @{
80-
Access = "User"
81-
}
82-
}
83-
"""
84-
And a settings file named User.psd1
85-
"""
86-
@{
87-
Domain = "HuddledMasses.org"
88-
}
89-
"""
90-
When I call New-User Joel Bennett
91-
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
92-
And the output object's Department should be Security
93-
And the output object's Permissions should be of type [hashtable]
94-
And the output object's Permissions.Access should be Administrator
95-
96-
97-
@Functions @Import
98-
Scenario: New-User Example Three
99-
Given an example New-User command
100-
And a settings file named SecurityUser.psd1 in the current folder
101-
"""
102-
@{
103-
Domain = 'HuddledMasses.org'
104-
Permissions = @{
105-
Access = "Administrator"
106-
}
107-
}
108-
"""
109-
When I call New-User Joel Bennett -Department Security
110-
Then the output object's EMail should be Joel.Bennett@HuddledMasses.org
111-
And the output object's Permissions should be of type [hashtable]
112-
And the output object's Permissions.Access should be of type [string]
113-
And the output object's Permissions.Access should be Administrator
58+
And the output object's ExtraParameter should be Supports Aliases

‎Specs/ScriptAnalyzer.feature‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Feature: Passes Script Analyzer
55

66
Scenario: ScriptAnalyzer on the compiled module output
77
Given the configuration module is imported
8-
When we run ScriptAnalyzer on 'C:\Users\Jaykul\Projects\Modules\Configuration\1.4.5' with 'C:\Users\Jaykul\Projects\Modules\Configuration\PSScriptAnalyzerSettings.psd1'
8+
When we run ScriptAnalyzer on 'C:\Users\Jaykul\Projects\Modules\Configuration\1.5.5' with 'C:\Users\Jaykul\Projects\Modules\Configuration\PSScriptAnalyzerSettings.psd1'
99

1010
Then it passes the ScriptAnalyzer rule PSAlignAssignmentStatement
1111
Then it passes the ScriptAnalyzer rule PSAvoidUsingCmdletAliases
@@ -58,6 +58,7 @@ Feature: Passes Script Analyzer
5858
Then it passes the ScriptAnalyzer rule PSUsePSCredentialType
5959
Then it passes the ScriptAnalyzer rule PSShouldProcess
6060
Then it passes the ScriptAnalyzer rule PSUseShouldProcessForStateChangingFunctions
61+
Then it passes the ScriptAnalyzer rule PSUseSingularNouns
6162
Then it passes the ScriptAnalyzer rule PSUseSupportsShouldProcess
6263
Then it passes the ScriptAnalyzer rule PSUseToExportFieldsInManifest
6364
Then it passes the ScriptAnalyzer rule PSUseUsingScopeModifierInNewRunspaces

0 commit comments

Comments
 (0)