Skip to content

Assert-BoundParameter: Add parameters AtLeastOneList and IfEqualParameterList#162

Merged
johlju merged 13 commits intodsccommunity:mainfrom
johlju:fix/issue#161
Aug 26, 2025
Merged

Assert-BoundParameter: Add parameters AtLeastOneList and IfEqualParameterList#162
johlju merged 13 commits intodsccommunity:mainfrom
johlju:fix/issue#161

Conversation

@johlju
Copy link
Copy Markdown
Member

@johlju johlju commented Aug 26, 2025

Pull Request (PR) description

  • Assert-BoundParameter
    • Added parameter set AtLeastOne with parameter AtLeastOneList to
      validate that at least one parameter from a specified list is bound
      #161.
    • Added parameter IfEqualParameterList to conditionally perform assertions
      only when specified parameters have exact values #160.

This Pull Request (PR) fixes the following issues

Task list

  • Added an entry to the change log under the Unreleased section of the
    file CHANGELOG.md. Entry should say what was changed and how that
    affects users (if applicable), and reference the issue being resolved
    (if applicable).
  • Documentation added/updated in README.md.
  • Comment-based help added/updated for all new/changed functions.
  • Localization strings added/updated in all localization files as appropriate.
  • Examples appropriately added/updated.
  • Unit tests added/updated. See DSC Community Testing Guidelines.
  • Integration tests added/updated (where possible). See
    DSC Community Testing Guidelines.
  • New/changed code adheres to DSC Community Style Guidelines.

This change is Reviewable

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Aug 26, 2025

Walkthrough

Adds IfEqualParameterList and a new AtLeastOne parameter set to Assert-BoundParameter with localization and extensive unit/integration tests. Also changes several validation error throws to New-ArgumentException and updates editor/task configs and CHANGELOG entries.

Changes

Cohort / File(s) Summary
Editor configuration
\.vscode/settings.json, \.vscode/tasks.json
Adds cSpell words and expands VS Code tasks with additional args, presentation settings, and PowerShell problem matchers for build/test/HQRMTest.
Public: Assert-BoundParameter logic
source/Public/Assert-BoundParameter.ps1
Adds AtLeastOne parameter set with -AtLeastOneList, adds -IfEqualParameterList gating across parameter sets, implements early-exit when gating not met, adjusts error handling, and updates help/examples.
Localization strings
source/en-US/DscResource.Common.strings.psd1
Adds Assert_BoundParameter_AtLeastOneParameterMustBeSet message for AtLeastOne validation (DRC0052).
Exception type alignment
source/Public/Assert-IPAddress.ps1, source/Public/Compare-DscParameterState.ps1, source/Public/Find-Certificate.ps1
Replace New-InvalidArgumentException with New-ArgumentException in specific validation branches; message/argument unchanged.
Tests: Unit
tests/Unit/Public/Assert-BoundParameter.Tests.ps1
Updates expected parameter-set signatures and adds tests for AtLeastOne and IfEqualParameterList interactions across parameter sets.
Tests: Integration
tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1
Adds integration suite covering MutuallyExclusive, Required, AtLeastOne, IfParameterPresent, IfEqualParameterList, and complex real-world scenarios.
Documentation
CHANGELOG.md
Updates/records added commands and parameter changes across versions and Unreleased section notes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant ABP as Assert-BoundParameter
  participant BP as BoundParameterList

  Caller->>ABP: Invoke with BoundParameterList, [IfEqualParameterList], [AtLeastOneList], other params
  ABP->>BP: Inspect bound parameters/values

  alt IfEqualParameterList provided
    ABP->>ABP: Compare BP values against IfEqualParameterList
    opt Condition not met
      note right of ABP #ffeead: Gating not satisfied — return without assertions
      ABP-->>Caller: Return
    end
  end

  alt AtLeastOne parameter set
    ABP->>ABP: Check any(BP contains AtLeastOneList)
    alt None present
      ABP-->>Caller: throw New-ArgumentException (DRC0052)
    else At least one present
      ABP-->>Caller: Return (success)
    end
  else RequiredParameter set
    ABP->>ABP: Evaluate required parameters per RequiredBehavior
    alt Requirement violated
      ABP-->>Caller: throw (RequiredParameter error)
    else OK
      ABP-->>Caller: Return
    end
  else MutuallyExclusiveParameters set
    ABP->>ABP: Validate mutual exclusion lists
    alt Violation
      ABP-->>Caller: throw New-ArgumentException
    else OK
      ABP-->>Caller: Return
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Assessment against linked issues

Objective Addressed Explanation
Assert-BoundParameters: Allow parameter IfEqualParameterList (#160)
Assert-BoundParameters: Add parameter AtLeastOneList via new AtLeastOne parameter set (#161)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Replace New-InvalidArgumentException → New-ArgumentException (input/address validation) (source/Public/Assert-IPAddress.ps1) Change is unrelated to the Assert-BoundParameter feature; it's a separate error-type normalization.
Replace New-InvalidArgumentException → New-ArgumentException (type/coverage validations) (source/Public/Compare-DscParameterState.ps1) Not mentioned in linked issues; unrelated validation/exception alignment.
Replace New-InvalidArgumentException → New-ArgumentException (certificate path error) (source/Public/Find-Certificate.ps1) Outside objectives from #160/#161; unrelated exception-type change.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@johlju johlju changed the title Fix/issue#161 Assert-BoundParameter: Add parameters AtLeastOneList and IfEqualParameterList Aug 26, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
source/Public/Assert-BoundParameter.ps1 (1)

192-197: Remove backticks; never use them for line continuation.

Guidelines forbid backticks in production. Use parentheses for grouping instead.

-                $errorMessage = `
-                    $script:localizedData.ParameterUsageWrong `
-                    -f ($MutuallyExclusiveList1 -join "','"), ($MutuallyExclusiveList2 -join "','")
+                $errorMessage = $script:localizedData.ParameterUsageWrong -f (
+                    $MutuallyExclusiveList1 -join "','",
+                    $MutuallyExclusiveList2 -join "','"
+                )
🧹 Nitpick comments (8)
source/Public/Find-Certificate.ps1 (1)

127-131: Tiny nit: spelling in comment

“Certificte” → “Certificate” in the inline comment (Line 127).

-        # The Certificte Path is not valid
+        # The Certificate Path is not valid
source/Public/Compare-DscParameterState.ps1 (1)

224-227: Quote the argument name for consistency

Other usages pass a quoted string to -ArgumentName. Quote Properties here for consistency and readability.

-            -ArgumentName Properties
+            -ArgumentName 'Properties'
.vscode/tasks.json (1)

41-44: Prefer ${workspaceFolder} over ${cwd} for reliability.

VS Code resolves ${workspaceFolder} more consistently across multi-root workspaces. Consider this small tweak.

-            "command": "&${cwd}/build.ps1",
+            "command": "&${workspaceFolder}/build.ps1",
CHANGELOG.md (1)

440-442: Tighten phrasing.

Another small grammar fix.

-  'ValuesToCheck' was renamed to 'Properties' but an alias
-  was added so it is not a braking change. The parameter 'ExcludeProperties'
-  was added.
+  'ValuesToCheck' was renamed to 'Properties', with an alias added so it is not a breaking change.
+  The parameter 'ExcludeProperties' was added.
tests/Unit/Public/Assert-BoundParameter.Tests.ps1 (1)

87-149: Avoid ‘Should -Not -Throw’ where possible.

Repo guidelines recommend avoiding “Should -Not -Throw”. Prefer invoking the command directly (optionally piping to Out-Null) and asserting observable effects (e.g., Should -Invoke, output, state), or asserting the presence/absence of specific errors when negative paths are tested. This reduces tautological tests and keeps assertions meaningful.

Also applies to: 158-193, 231-258, 309-314, 345-361, 373-399, 431-449, 476-499, 527-542, 546-577

tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1 (1)

35-86: Consider reducing ‘Should -Not -Throw’ usage in integration tests.

Same note as unit tests: prefer asserting outcomes/state over “not throwing” to keep tests purposeful. Keep as follow-up; not blocking.

Also applies to: 127-173, 229-288, 294-347, 392-520, 525-971

source/Public/Assert-BoundParameter.ps1 (2)

132-139: Add OutputType attribute for no-output functions.

Per guidelines, include [OutputType()] even when nothing is returned.

 function Assert-BoundParameter
 {
-    [CmdletBinding()]
+    [CmdletBinding()]
+    [OutputType()]

160-168: Optional: validate non-empty lists.

Consider adding [ValidateNotNullOrEmpty()] on list parameters to fail-fast on empty arrays that can’t satisfy assertions.

-        [System.Collections.Hashtable]
+        [System.Collections.Hashtable]
         $IfEqualParameterList,
 
-        [Parameter(ParameterSetName = 'AtLeastOne', Mandatory = $true)]
-        [System.String[]]
+        [Parameter(ParameterSetName = 'AtLeastOne', Mandatory = $true)]
+        [ValidateNotNullOrEmpty()]
+        [System.String[]]
         $AtLeastOneList
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7d78ed9 and 1e59185.

📒 Files selected for processing (10)
  • .vscode/settings.json (1 hunks)
  • .vscode/tasks.json (2 hunks)
  • CHANGELOG.md (7 hunks)
  • source/Public/Assert-BoundParameter.ps1 (7 hunks)
  • source/Public/Assert-IPAddress.ps1 (3 hunks)
  • source/Public/Compare-DscParameterState.ps1 (1 hunks)
  • source/Public/Find-Certificate.ps1 (1 hunks)
  • source/en-US/DscResource.Common.strings.psd1 (1 hunks)
  • tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1 (1 hunks)
  • tests/Unit/Public/Assert-BoundParameter.Tests.ps1 (4 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Public/Find-Certificate.ps1
  • source/Public/Assert-IPAddress.ps1
  • source/Public/Compare-DscParameterState.ps1
  • tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1
  • source/en-US/DscResource.Common.strings.psd1
  • tests/Unit/Public/Assert-BoundParameter.Tests.ps1
  • source/Public/Assert-BoundParameter.ps1
  • CHANGELOG.md
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Public/Find-Certificate.ps1
  • source/Public/Assert-IPAddress.ps1
  • source/Public/Compare-DscParameterState.ps1
  • tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1
  • source/en-US/DscResource.Common.strings.psd1
  • tests/Unit/Public/Assert-BoundParameter.Tests.ps1
  • source/Public/Assert-BoundParameter.ps1
source/**/*.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Public/Find-Certificate.ps1
  • source/Public/Assert-IPAddress.ps1
  • source/Public/Compare-DscParameterState.ps1
  • source/Public/Assert-BoundParameter.ps1
**/*.[Tt]ests.ps1

⚙️ CodeRabbit configuration file

**/*.[Tt]ests.ps1: # Tests Guidelines

Core Requirements

  • All public commands, private functions and classes must have unit tests
  • All public commands and class-based resources must have integration tests
  • Use Pester v5 syntax only
  • One Describe block per file matching the tested entity name
  • Test code only inside Describe blocks
  • Assertions only in It blocks
  • Never test verbose messages, debug messages or parameter binding behavior
  • Pass all mandatory parameters to avoid prompts

Structure & Scope

  • Public commands: Never use InModuleScope (unless retrieving localized strings)
  • Private functions/class resources: Always use InModuleScope
  • Each scenario = separate Context block
  • Use nested Context blocks for complex scenarios
  • Mocking in BeforeAll (BeforeEach only when required)
  • Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach close to usage

Syntax Rules

  • PascalCase: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
  • Context descriptions start with 'When'
  • It descriptions start with 'Should', must not contain 'when'
  • Mock variables prefix: 'mock'
  • Prefer -BeTrue/-BeFalse over -Be $true/-Be $false
  • No Should -Not -Throw - invoke commands directly
  • Never add an empty -MockWith block
  • Omit -MockWith when returning $null
  • Set $PSDefaultParameterValues for Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName
  • Omit -ModuleName parameter on Pester commands

File Organization

  • Class resources: tests/Unit/Classes/{Name}.Tests.ps1
  • Public commands: tests/Unit/Public/{Name}.Tests.ps1
  • Private functions: tests/Unit/Private/{Name}.Tests.ps1

Data-Driven Tests

  • Define variables in separate BeforeDiscovery for -ForEach (close to usage)
  • -ForEach allowed on Context and It blocks
  • Keep scope close to usage context

Best Practices

  • Inside It blocks, assign unused return objects to $null (unless part of ...

Files:

  • tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1
  • tests/Unit/Public/Assert-BoundParameter.Tests.ps1
tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1

⚙️ CodeRabbit configuration file

tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1: # Integration Tests Guidelines

Requirements

  • Location Commands: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1
  • Location Resources: tests/Integration/Resources/{ResourceName}.Integration.Tests.ps1
  • No mocking - real environment only
  • Cover all scenarios and code paths
  • Use Get-ComputerName for computer names in CI
  • Avoid ExpectedMessage for Should -Throw assertions
  • Only run integration tests in CI unless explicitly instructed.
  • Call commands with -Force parameter where applicable (avoids prompting).
  • Use -ErrorAction Stop on commands so failures surface immediately

Required Setup Block

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
param ()

BeforeDiscovery {
    try
    {
        if (-not (Get-Module -Name 'DscResource.Test'))
        {
            # Assumes dependencies have been resolved, so if this module is not available, run 'noop' task.
            if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
            {
                # Redirect all streams to $null, except the error stream (stream 2)
                & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 3>&1 4>&1 5>&1 6>&1 > $null
            }

            # If the dependencies have not been resolved, this will throw an error.
            Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
        }
    }
    catch [System.IO.FileNotFoundException]
    {
        throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
    }
}

BeforeAll {
    $script:dscModuleName = 'SqlServerDsc'

    Import-Module -Name $script:dscModuleName -Force -ErrorAction 'Stop'
}

Files:

  • tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: # Markdown Style Guidelines

  • Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
  • Use 2 spaces for indentation
  • Use '1.' for all items in ordered lists (1/1/1 numbering style)
  • Disable MD013 rule by adding a comment for tables/code blocks exceeding 80 characters
  • Empty lines required before/after code blocks and headings (except before line 1)
  • Escape backslashes in file paths only (not in code blocks)
  • Code blocks must specify language identifiers

Text Formatting

  • Parameters: bold
  • Values/literals: inline code
  • Resource/module/product names: italic
  • Commands/files/paths: inline code

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: # Changelog Guidelines

  • Always update the Unreleased section in CHANGELOG.md
  • Use Keep a Changelog format
  • Describe notable changes briefly, ≤2 items per change type
  • Reference issues using format #<issue_number>
  • No empty lines between list items in same section
  • Do not add item if there are already an existing item for the same change

Files:

  • CHANGELOG.md
🪛 LanguageTool
CHANGELOG.md

[grammar] ~413-~413: There might be a mistake here.
Context: ...se to add ExpectedValue and ActualValue. - Added pester test to test the PSCredenti...

(QB_NEW_EN)


[grammar] ~442-~442: There might be a mistake here.
Context: ...rameter 'ExcludeProperties' was added. - Added a new test for the alias 'ValuesTo...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: dsccommunity.DscResource.Common (Build Package Module)
🔇 Additional comments (23)
source/Public/Assert-IPAddress.ps1 (2)

56-59: Good move: standardized on New-ArgumentException

Switching to New-ArgumentException for address-parse failure aligns error handling with the rest of the module and the PR’s intent.


69-72: Consistent argument classification

Using -ArgumentName 'AddressFamily' for family mismatches and 'Address' for parse failure is appropriate and consistent. No action needed.

Also applies to: 79-82

.vscode/settings.json (1)

35-39: Dictionary additions look good

Adding “hashtables”, “HQRM”, and “LCID” to cSpell avoids noise during doc/help and code work. JSON syntax remains valid after the trailing comma adjustment.

source/Public/Find-Certificate.ps1 (1)

128-131: Standardized to New-ArgumentException

Replacing New-InvalidArgumentException with New-ArgumentException for invalid Store path keeps error handling consistent across commands. Message and -ArgumentName remain correct.

source/Public/Compare-DscParameterState.ps1 (1)

209-212: Consistent argument exceptions across validation branches

Converging on New-ArgumentException for invalid DesiredValues, CurrentValues, and missing Properties (when DesiredValues is CimInstance) is aligned with the PR direction. Messages and argument names look correct.

Also applies to: 216-219, 224-227

source/en-US/DscResource.Common.strings.psd1 (2)

43-45: New AtLeastOne message key added correctly

Assert_BoundParameter_AtLeastOneParameterMustBeSet (DRC0052) reads well and fits the existing key/ID scheme. No issues spotted.


43-45: Assert-BoundParameter key verification complete

All checks passed for the new Assert_BoundParameter_AtLeastOneParameterMustBeSet entry:

  • The key is actively referenced in both production and test code:
    • source/Public/Assert-BoundParameter.ps1 (line 225)
    • tests/Unit/Public/Assert-BoundParameter.Tests.ps1 (lines 283 & 506)
  • No hard-coded occurrences of the message remain outside the .psd1 file.
  • The DRC0052 identifier appears only once, confirming it’s unique.
  • There are no orphaned or duplicate Assert_BoundParameter_ keys in source/en-US/DscResource.Common.strings.psd1.

No further action required.

.vscode/tasks.json (3)

44-44: Build task args are explicit and consistent.

Good call adding -AutoRestore and -UseModuleFast; this mirrors how the test/HQRM tasks are invoked and reduces local setup friction.


97-131: Nice: dedicated terminal, matcher, and explicit Pester paths.

The dedicated panel and problemMatcher improve DX; scoping Pester paths avoids accidental discovery. Looks good.


145-180: HQRM test task parity is solid.

Consistent presentation/problemMatcher and explicit args (-CodeCoverageThreshold 0) are 👍.

CHANGELOG.md (1)

12-17: Changelog entry correctly reflects the new parameter set and gating parameter.

Issue references and scope are clear and follow the Keep a Changelog style.

tests/Unit/Public/Assert-BoundParameter.Tests.ps1 (6)

53-64: Parameter set surface checks look correct.

Expected parameter strings for MutuallyExclusiveParameters, RequiredParameter, and AtLeastOne align with the implementation (including IfEqualParameterList).


195-228: Positive coverage for AtLeastOne is thorough.

Good scenarios for “one” and “many” bound parameters.


280-299: Negative AtLeastOne path validates the new localized message.

This ensures the correct string key is wired.


317-452: Gating via IfEqualParameterList for MutuallyExclusiveParameters is well covered.

You’ve tested met/not-met, missing key, and multi-condition cases — great.


454-501: RequiredParameter + IfEqualParameterList interaction is validated, including invocation count.

Verifying Assert-RequiredCommandParameter invocation count removes ambiguity.


502-579: AtLeastOne + IfEqualParameterList gating behaves as intended.

Met vs. not-met and missing-key conditions are appropriately asserted.

tests/Integration/Commands/Assert-BoundParameter.Integration.Tests.ps1 (5)

32-123: Solid baseline for MutuallyExclusiveParameters (no-conflict and conflict cases).

Covers single and multiple parameter overlaps with -ErrorAction Stop, which is appropriate in integration runs.


125-288: RequiredParameter integration coverage is comprehensive.

You exercise default/All/Any behaviors and IfParameterPresent gating. Good real-world parity.


291-389: AtLeastOne integration: good breadth (one, many, none, unrelated).

Nicely mirrors likely consumer scenarios.


392-520: Realistic DSC-like scenarios increase confidence.

SQL connection and SSL/cert examples validate intended ergonomics.


524-971: IfEqualParameterList across all parameter sets is well tested.

Met vs not-met, missing keys, and combined conditions are represented.

source/Public/Assert-BoundParameter.ps1 (1)

171-181: Gating logic matches the requirement.

Early return when IfEqualParameterList is present and not matched is clean and avoids downstream evaluation.

Comment thread CHANGELOG.md Outdated
Comment thread source/Public/Assert-BoundParameter.ps1
Comment thread source/Public/Assert-BoundParameter.ps1 Outdated
Comment thread source/Public/Assert-IPAddress.ps1
@johlju
Copy link
Copy Markdown
Member Author

johlju commented Aug 26, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Aug 26, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Member Author

@johlju johlju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@johlju reviewed 10 of 12 files at r1, 2 of 2 files at r2, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @johlju)

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
source/Public/Assert-BoundParameter.ps1 (1)

90-93: Incorrect example description for RequiredBehavior 'Any'.

The description contradicts the behavior. When RequiredBehavior is set to 'Any', the function throws an exception if none of the parameters are present, not if "any" are not present.

Apply this diff to fix the description:

-        Throws an exception if any of the two parameters are not present.
+        Throws an exception if neither of the two parameters is specified.
🧹 Nitpick comments (2)
source/Public/Assert-BoundParameter.ps1 (1)

210-213: Consider documenting the removal of IfEqualParameterList.

The removal of IfEqualParameterList from $PSBoundParameters before calling Assert-RequiredCommandParameter prevents unintended re-evaluation. This is correct but subtle - consider adding a comment explaining why this removal is necessary.

 if ($PSBoundParameters.ContainsKey('IfEqualParameterList'))
 {
+    # Remove to prevent passing unknown parameter to Assert-RequiredCommandParameter
     $PSBoundParameters.Remove('IfEqualParameterList')
 }
CHANGELOG.md (1)

331-334: Consider more conventional formatting for multi-line CHANGELOG entries.

While the current formatting is acceptable, consider using consistent indentation without the hanging indent on the last line for better readability in markdown.

-- DscResource.Common
-  - updating the Get-LocalizedData to bypass Import-LocalizedData when in
-    Globalization-Invariant mode.
-    The command throws when running on an Invariant culture on Linux in
-    the latest PS versions.
+- DscResource.Common
+  - Updated the Get-LocalizedData to bypass Import-LocalizedData when in
+    Globalization-Invariant mode. The command throws when running on an 
+    Invariant culture on Linux in the latest PS versions.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1e59185 and 3aa298b.

📒 Files selected for processing (2)
  • CHANGELOG.md (7 hunks)
  • source/Public/Assert-BoundParameter.ps1 (7 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Public/Assert-BoundParameter.ps1
  • CHANGELOG.md
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Public/Assert-BoundParameter.ps1
source/**/*.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Public/Assert-BoundParameter.ps1
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: # Markdown Style Guidelines

  • Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
  • Use 2 spaces for indentation
  • Use '1.' for all items in ordered lists (1/1/1 numbering style)
  • Disable MD013 rule by adding a comment for tables/code blocks exceeding 80 characters
  • Empty lines required before/after code blocks and headings (except before line 1)
  • Escape backslashes in file paths only (not in code blocks)
  • Code blocks must specify language identifiers

Text Formatting

  • Parameters: bold
  • Values/literals: inline code
  • Resource/module/product names: italic
  • Commands/files/paths: inline code

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: # Changelog Guidelines

  • Always update the Unreleased section in CHANGELOG.md
  • Use Keep a Changelog format
  • Describe notable changes briefly, ≤2 items per change type
  • Reference issues using format #<issue_number>
  • No empty lines between list items in same section
  • Do not add item if there are already an existing item for the same change

Files:

  • CHANGELOG.md
🪛 LanguageTool
CHANGELOG.md

[grammar] ~413-~413: There might be a mistake here.
Context: ...ed to add ExpectedValue and ActualValue. - Added pester test to test the PSCredenti...

(QB_NEW_EN)


[grammar] ~442-~442: There might be a mistake here.
Context: ...rameter 'ExcludeProperties' was added. - Added a new test for the alias 'ValuesTo...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: dsccommunity.DscResource.Common (Test Publish Code Coverage)
  • GitHub Check: dsccommunity.DscResource.Common (Test Windows (Windows PowerShell))
  • GitHub Check: dsccommunity.DscResource.Common (Test Windows (PowerShell Core))
  • GitHub Check: dsccommunity.DscResource.Common (Test Linux)
  • GitHub Check: dsccommunity.DscResource.Common (Test macOS)
  • GitHub Check: dsccommunity.DscResource.Common (Test HQRM)
  • GitHub Check: dsccommunity.DscResource.Common (Build Package Module)
🔇 Additional comments (7)
source/Public/Assert-BoundParameter.ps1 (6)

177-186: Clean implementation of IfEqualParameterList early return logic.

The logic correctly checks if all specified parameters match their expected values before proceeding with the assertion. This provides a clean conditional gating mechanism.


197-200: Well-implemented error message construction without backticks.

The multi-line error message formatting using parentheses is clean and follows PowerShell best practices.


224-236: Good implementation of AtLeastOne parameter set.

The implementation correctly validates that at least one parameter from AtLeastOneList is bound and constructs the error message appropriately.


105-122: Clear and comprehensive examples for new features.

The examples effectively demonstrate the use of IfEqualParameterList with both MutuallyExclusiveParameters and the broader conditional assertion pattern.


8-29: Documentation accurately reflects three parameter sets.

The comment has been correctly updated from "two" to "three" parameter sets, and the new AtLeastOne parameter set is properly documented.


230-231: Localized string resource exists

  • Verified that the key Assert_BoundParameter_AtLeastOneParameterMustBeSet is present in source/en-US/DscResource.Common.strings.psd1 at line 44.

No further action required.

CHANGELOG.md (1)

12-17: CHANGELOG entries correctly document the new features.

The additions properly reference the resolved issues and clearly describe both the AtLeastOne parameter set and IfEqualParameterList functionality.

@johlju johlju merged commit 29c44b2 into dsccommunity:main Aug 26, 2025
10 checks passed
@johlju johlju deleted the fix/issue#161 branch August 26, 2025 18:32
@johlju johlju restored the fix/issue#161 branch August 26, 2025 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assert-BoundParameters: Add parameter AtLeastOneList Assert-BoundParameters: Allow parameter IfEqualParameterList <Hashtable>

1 participant