tests/unit/Private/Filter-KlippyItemByWildcard.Tests.ps1

#Requires -Modules Pester

BeforeAll {
    $modulePath = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
    Import-Module "$modulePath/KlippyCLI.psd1" -Force
}

Describe "Filter-KlippyItemByWildcard" -Tag Unit {
    Context "Wildcard Matching" {
        It "Should match files with asterisk wildcard" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "benchy.gcode" }
                    [PSCustomObject]@{ Path = "benchy_v2.gcode" }
                    [PSCustomObject]@{ Path = "test.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "benchy*"
            }

            @($result).Count | Should -Be 2
        }

        It "Should match files with question mark wildcard" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "test.gcode" }
                    [PSCustomObject]@{ Path = "tests.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "tes?.gcode"
            }

            @($result).Count | Should -Be 1
            $result.Path | Should -Be "test.gcode"
        }

        It "Should be case-insensitive" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "UPPERCASE.GCODE" }
                    [PSCustomObject]@{ Path = "lowercase.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "uppercase*"
            }

            @($result).Count | Should -Be 1
        }

        It "Should match by leaf name for nested paths" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "folder/nested.gcode" }
                    [PSCustomObject]@{ Path = "other.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "nested*"
            }

            @($result).Count | Should -Be 1
            $result.Path | Should -Be "folder/nested.gcode"
        }
    }

    Context "Exact Matching" {
        It "Should match exact filename without wildcards" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "test.gcode" }
                    [PSCustomObject]@{ Path = "test2.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "test.gcode"
            }

            @($result).Count | Should -Be 1
            $result.Path | Should -Be "test.gcode"
        }
    }

    Context "No Matches" {
        It "Should return empty when no matches" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "file.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "nonexistent*"
            }

            $result | Should -BeNullOrEmpty
        }
    }

    Context "RequireSingle Parameter" {
        It "Should throw when no items match with RequireSingle" {
            {
                & (Get-Module KlippyCLI) {
                    $testItems = @([PSCustomObject]@{ Path = "file.gcode" })
                    $testItems | Filter-KlippyItemByWildcard -Pattern "nonexistent" -RequireSingle
                }
            } | Should -Throw "*No items matching*"
        }

        It "Should throw when multiple items match with RequireSingle" {
            {
                & (Get-Module KlippyCLI) {
                    $testItems = @(
                        [PSCustomObject]@{ Path = "benchy.gcode" }
                        [PSCustomObject]@{ Path = "benchy_v2.gcode" }
                    )
                    $testItems | Filter-KlippyItemByWildcard -Pattern "benchy*" -RequireSingle
                }
            } | Should -Throw "*Multiple items match*"
        }

        It "Should return single item when exactly one matches" {
            $result = & (Get-Module KlippyCLI) {
                $testItems = @(
                    [PSCustomObject]@{ Path = "test.gcode" }
                    [PSCustomObject]@{ Path = "other.gcode" }
                )
                $testItems | Filter-KlippyItemByWildcard -Pattern "test.gcode" -RequireSingle
            }

            $result | Should -Not -BeNullOrEmpty
            $result.Path | Should -Be "test.gcode"
        }
    }
}