From 5c61a7fba16f7e2675b5419a8bb9ee0ad434e059 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 12:09:02 +0100 Subject: [PATCH 01/10] Remove obsolete tests and add casing style conversion functions --- .../private/Split-StringByCasingStyle.ps1 | 101 ++++++++++++++++++ .../public/ConvertTo-CasingStyle.ps1 | 71 ++++++++++++ src/functions/public/Get-CasingStyle.ps1 | 99 +++++++++++++++++ src/functions/public/Set-PSModuleTest.ps1 | 22 ---- src/variables/private/Cases.ps1 | 10 ++ tests/Casing.Tests.ps1 | 101 ++++++++++++++++++ tests/PSModuleTest.Tests.ps1 | 5 - 7 files changed, 382 insertions(+), 27 deletions(-) create mode 100644 src/functions/private/Split-StringByCasingStyle.ps1 create mode 100644 src/functions/public/ConvertTo-CasingStyle.ps1 create mode 100644 src/functions/public/Get-CasingStyle.ps1 delete mode 100644 src/functions/public/Set-PSModuleTest.ps1 create mode 100644 src/variables/private/Cases.ps1 create mode 100644 tests/Casing.Tests.ps1 delete mode 100644 tests/PSModuleTest.Tests.ps1 diff --git a/src/functions/private/Split-StringByCasingStyle.ps1 b/src/functions/private/Split-StringByCasingStyle.ps1 new file mode 100644 index 0000000..a3cd8d7 --- /dev/null +++ b/src/functions/private/Split-StringByCasingStyle.ps1 @@ -0,0 +1,101 @@ +filter Split-StringByCasingStyle { + <# + .SYNOPSIS + Splits a kebab-case string into an array of words + + .DESCRIPTION + This function splits a kebab-case string into an array of words. + + .EXAMPLE + Split-StringByCasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case + + this + is + a + kebab + case + string + + .EXAMPLE + Split-StringByCasingStyle -Text 'this_is_a_kebab_case_string' -By 'snake_case' + + this + is + a + kebab + case + string + + .EXAMPLE + Split-StringByCasingStyle -Text 'ThisIsAPascalCaseString' -By 'PascalCase' + + This + Is + A + Pascal + Case + String + + .EXAMPLE + Split-StringByCasingStyle -Text 'thisIsACamelCaseString' -By 'camelCase' + + this + Is + A + Camel + Case + String + + .EXAMPLE + Split-StringByCasingStyle -Text 'this_is_a-CamelCaseString' -By kebab-case | Split-StringByCasingStyle -By snake_case + + this_is_a + camelcasestring + + + #> + [OutputType([string[]])] + [CmdletBinding()] + param ( + # The string to split + [Parameter( + Mandatory, + ValueFromPipeline + )] + [string] $Text, + + # The casing style to split the string by + [Parameter()] + [ValidateSet( + 'lowercase', + 'UPPERCASE', + 'Sentencecase', + 'Title Case', + 'PascalCase', + 'camelCase', + 'kebab-case', + 'UPPER-KEBAB-CASE', + 'snake_case', + 'UPPER_SNAKE_CASE' + )] + [string] $By + ) + + $styles = $PSBoundParameters | Where-Object { $_.Value -eq $true } | Select-Object -ExpandProperty Name + + Write-Verbose "Splitting string [$Text] by casing style [$($styles -join ', ' )]" + $splitText = switch ($By) { + 'PascalCase' { [regex]::Matches($Text, '([A-Z][a-z]*)').Value; break } + 'camelCase' { [regex]::Matches($Text, '([A-Z][a-z]*)|^[a-z]+').Value; break } + 'kebab-case' { $Text -split '-'; break } + 'UPPER-KEBAB-CASE' { $Text -split '-'; break } + 'snake_case' { $Text -split '_'; break } + 'UPPER_SNAKE_CASE' { $Text -split '_'; break } + default { + $Text -split ' ' + } + } + + Write-Verbose "Result: [$($splitText -join ', ')]" + $splitText +} diff --git a/src/functions/public/ConvertTo-CasingStyle.ps1 b/src/functions/public/ConvertTo-CasingStyle.ps1 new file mode 100644 index 0000000..8e39574 --- /dev/null +++ b/src/functions/public/ConvertTo-CasingStyle.ps1 @@ -0,0 +1,71 @@ +filter ConvertTo-CasingStyle { + <# + .SYNOPSIS + Convert a string to a different casing style + + .DESCRIPTION + This function converts a string to a different casing style. + + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'snake_case' + + Convert the string 'thisIsCamelCase' to 'this_is_camel_case' + + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'UPPER_SNAKE_CASE' + + Convert the string 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE' + + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' + + .NOTES + General notes + #> + [OutputType([string])] + [CmdletBinding()] + param ( + # The string to convert + [Parameter( + Mandatory, + ValueFromPipeline + )] + [string] $Text, + + # The casing style to convert the string to + [Parameter(Mandatory)] + [ValidateSet( + 'lowercase', + 'UPPERCASE', + 'Title Case', + 'Sentencecase', + 'PascalCase', + 'camelCase', + 'kebab-case', + 'UPPER-KEBAB-CASE', + 'snake_case', + 'UPPER_SNAKE_CASE' + )] + [string] $To + ) + + $currentStyle = Get-CasingStyle -Text $Text + + $words = Split-StringByCasingStyle -Text $Text -By $currentStyle + + # Convert the words into the target style + switch ($To) { + 'lowercase' { ($words -join '').toLower() } + 'UPPERCASE' { ($words -join '').toUpper() } + 'Title Case' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join ' ' } + 'Sentencecase' { $words -join '' | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() } } + 'kebab-case' { ($words -join '-').ToLower() } + 'snake_case' { ($words -join '_').ToLower() } + 'PascalCase' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join '' } + 'camelCase' { + $words[0].toLower() + (($words | Select-Object -Skip 1 | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1) }) -join '') + } + 'UPPER_SNAKE_CASE' { ($words -join '_').toUpper() } + 'UPPER-KEBAB-CASE' { ($words -join '-').toUpper() } + } +} diff --git a/src/functions/public/Get-CasingStyle.ps1 b/src/functions/public/Get-CasingStyle.ps1 new file mode 100644 index 0000000..2db69cc --- /dev/null +++ b/src/functions/public/Get-CasingStyle.ps1 @@ -0,0 +1,99 @@ +filter Get-CasingStyle { + <# + .SYNOPSIS + Detects the casing style of a string + + .DESCRIPTION + This function detects the casing style of a string. + + .EXAMPLE + 'testtesttest' | Get-CasingStyle + + lowercase + + .EXAMPLE + 'TESTTESTTEST' | Get-CasingStyle + + UPPERCASE + + .EXAMPLE + 'Testtesttest' | Get-CasingStyle + + Sentencecase + + .EXAMPLE + 'TestTestTest' | Get-CasingStyle + + PascalCase + + .EXAMPLE + 'testTestTest' | Get-CasingStyle + + camelCase + + .EXAMPLE + 'test-test-test' | Get-CasingStyle + + kebab-case + + .EXAMPLE + 'TEST-TEST-TEST' | Get-CasingStyle + + UPPER-KEBAB-CASE + + .EXAMPLE + 'test_test_test' | Get-CasingStyle + + snake_case + + .EXAMPLE + 'TEST_TEST_TEST' | Get-CasingStyle + + UPPER_SNAKE_CASE + + .EXAMPLE + 'Test_teSt-Test' | Get-CasingStyle + + Unknown + + .LINK + https://psmodule.io/Casing/Functions/Get-CasingStyle/ + #> + [OutputType([string])] + [CmdletBinding()] + param ( + # The string to check the casing style of + [Parameter( + Mandatory, + ValueFromPipeline + )] + [string] $Text + ) + + $style = if ([regex]::Match($Text, $script:LowerCase).Success) { + 'lowercase' + } elseif ([regex]::Match($Text, $script:UpperCase).Success) { + 'UPPERCASE' + } elseif ([regex]::Match($Text, $script:SentenceCase).Success) { + 'Sentencecase' + } elseif ([regex]::Match($Text, $script:TitleCase).Success) { + 'Title Case' + } elseif ([regex]::Match($Text, $script:PascalCase).Success) { + 'PascalCase' + } elseif ([regex]::Match($Text, $script:CamelCase).Success) { + 'camelCase' + } elseif ([regex]::Match($Text, $script:KebabCase).Success) { + 'kebab-case' + } elseif ([regex]::Match($Text, $script:UpperKebabCase).Success) { + 'UPPER-KEBAB-CASE' + } elseif ([regex]::Match($Text, $script:SnakeCase).Success) { + 'snake_case' + } elseif ([regex]::Match($Text, $script:UpperCase).Success) { + 'UPPER_SNAKE_CASE' + } else { + 'Unknown' + } + + Write-Verbose "Detected casing style: [$style]" + $style +} diff --git a/src/functions/public/Set-PSModuleTest.ps1 b/src/functions/public/Set-PSModuleTest.ps1 deleted file mode 100644 index a87ac11..0000000 --- a/src/functions/public/Set-PSModuleTest.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -function Set-PSModuleTest { - <# - .SYNOPSIS - Performs tests on a module. - - .EXAMPLE - Test-PSModule -Name 'World' - - "Hello, World!" - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', - Justification = 'Reason for suppressing' - )] - [CmdletBinding()] - param ( - # Name of the person to greet. - [Parameter(Mandatory)] - [string] $Name - ) - Write-Output "Hello, $Name!" -} diff --git a/src/variables/private/Cases.ps1 b/src/variables/private/Cases.ps1 new file mode 100644 index 0000000..690866e --- /dev/null +++ b/src/variables/private/Cases.ps1 @@ -0,0 +1,10 @@ +$script:LowerCase = '^[a-z][a-z0-9]*$' +$script:UpperCase = '^[A-Z][A-Z0-9]*$' +$script:SentenceCase = '^[A-Z][a-z0-9]*$' +$script:TitleCase = '^([A-Z][a-z]*)(\s+[A-Z][a-z]*)+$' +$script:PascalCase = '^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)+$' +$script:CamelCase = '^[a-z][a-z0-9]*([A-Z][a-z0-9]*)+$' +$script:KebabCase = '^[a-z][a-z0-9]*(-[a-z0-9]+)+$' +$script:UpperKebabCase = '^[A-Z][A-Z0-9]*(-[A-Z0-9]+)+$' +$script:SnakeCase = '^[a-z][a-z0-9]*(_[a-z0-9]+)+$' +$script:UpperSnakeCase = '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)+$' diff --git a/tests/Casing.Tests.ps1 b/tests/Casing.Tests.ps1 new file mode 100644 index 0000000..bf5b7dc --- /dev/null +++ b/tests/Casing.Tests.ps1 @@ -0,0 +1,101 @@ +Describe 'Casing' { + Context 'Function: Get-CasingStyle' { + It "Get-CasingStyle: Detects 'testtesttest' as lowercase" { + 'testtesttest' | Get-CasingStyle | Should -Be 'lowercase' + } + + It "Get-CasingStyle: Detects 'TESTTESTTEST' as UPPERCASE" { + 'TESTTESTTEST' | Get-CasingStyle | Should -Be 'UPPERCASE' + } + + It "Get-CasingStyle: Detects 'Testtesttest' as Sentencecase" { + 'Testtesttest' | Get-CasingStyle | Should -Be 'Sentencecase' + } + + It "Get-CasingStyle: Detects 'TestTestTest' as PascalCase" { + 'TestTestTest' | Get-CasingStyle | Should -Be 'PascalCase' + } + + It "Get-CasingStyle: Detects 'testTestTest' as camelCase" { + 'testTestTest' | Get-CasingStyle | Should -Be 'camelCase' + } + + It "Get-CasingStyle: Detects 'test-test-test' as kebab-case" { + 'test-test-test' | Get-CasingStyle | Should -Be 'kebab-case' + } + + It "Get-CasingStyle: Detects 'TEST-TEST-TEST' as UPPER-KEBAB-CASE" { + 'TEST-TEST-TEST' | Get-CasingStyle | Should -Be 'UPPER-KEBAB-CASE' + } + + It "Get-CasingStyle: Detects 'test_test_test' as snake_case" { + 'test_test_test' | Get-CasingStyle | Should -Be 'snake_case' + } + + It "Get-CasingStyle: Detects 'TEST_TEST_TEST' as UPPER_SNAKE_CASE" { + 'TEST_TEST_TEST' | Get-CasingStyle | Should -Be 'UPPER_SNAKE_CASE' + } + + It "Get-CasingStyle: Detects 'Test Test Test' as Title Case" { + 'Test Test Test' | Get-CasingStyle | Should -Be 'Title Case' + } + + It "Get-CasingStyle: Detects 'Test_teSt-Test' as Unknown" { + 'Test_teSt-Test' | Get-CasingStyle | Should -Be 'Unknown' + } + + It "Get-CasingStyle: Detects 'Test-Test_test' as Unknown" { + 'Test-Test_test' | Get-CasingStyle | Should -Be 'Unknown' + } + + It "Get-CasingStyle: Detects 'ThisIsAMultiWordPascalString' as PascalCase" { + 'ThisIsAMultiWordPascalString' | Get-CasingStyle | Should -Be 'PascalCase' + } + + It "Get-CasingStyle: Detects 'T' as UPPERCASE" { + 'T' | Get-CasingStyle | Should -Be 'UPPERCASE' + } + + It "Get-CasingStyle: Detects 'TTTT' UPPERCASE" { + 'TTTT' | Get-CasingStyle | Should -Be 'UPPERCASE' + } + + It "Get-CasingStyle: Detects 't' as lowercase" { + 't' | Get-CasingStyle | Should -Be 'lowercase' + } + + It "Get-CasingStyle: Detects 'tttt' as lowercase" { + 'tttt' | Get-CasingStyle | Should -Be 'lowercase' + } + + It "Get-CasingStyle: Detects 'tT' as camelCase" { + 'tT' | Get-CasingStyle | Should -Be 'camelCase' + } + + It "Get-CasingStyle: Detects 't-t' as kebab-case" { + 't-t' | Get-CasingStyle | Should -Be 'kebab-case' + } + + It "Get-CasingStyle: Detects 'T-T' as UPPER-KEBAB-CASE" { + 'T-T' | Get-CasingStyle | Should -Be 'UPPER-KEBAB-CASE' + } + + It "Get-CasingStyle: Detects 't_t' as snake_case" { + 't_t' | Get-CasingStyle | Should -Be 'snake_case' + } + } + + Context 'Function: ConvertTo-CasingStyle' { + It "ConvertTo-CasingStyle: Converts 'thisIsCamelCase' to 'snake_case'" { + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'snake_case' | Should -Be 'this_is_camel_case' + } + + It "ConvertTo-CasingStyle: Converts 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE'" { + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'UPPER_SNAKE_CASE' | Should -Be 'THIS_IS_CAMEL_CASE' + } + + It "ConvertTo-CasingStyle: Converts 'thisIsCamelCase' to 'this-is-camel-case'" { + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' | Should -Be 'this-is-camel-case' + } + } +} diff --git a/tests/PSModuleTest.Tests.ps1 b/tests/PSModuleTest.Tests.ps1 deleted file mode 100644 index 4892023..0000000 --- a/tests/PSModuleTest.Tests.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -Describe 'Module' { - It 'Function: Set-PSModuleTest' { - Set-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' - } -} From cf909263f5b11d3ac3bb724b82c94f6c478cfe73 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 12:15:02 +0100 Subject: [PATCH 02/10] Rename Split-StringByCasingStyle to Split-CasingStyle and update references --- .../public/ConvertTo-CasingStyle.ps1 | 2 +- .../Split-CasingStyle.ps1} | 12 ++++----- tests/Casing.Tests.ps1 | 25 ++++++++++++++++++- 3 files changed, 31 insertions(+), 8 deletions(-) rename src/functions/{private/Split-StringByCasingStyle.ps1 => public/Split-CasingStyle.ps1} (79%) diff --git a/src/functions/public/ConvertTo-CasingStyle.ps1 b/src/functions/public/ConvertTo-CasingStyle.ps1 index 8e39574..d8b08ef 100644 --- a/src/functions/public/ConvertTo-CasingStyle.ps1 +++ b/src/functions/public/ConvertTo-CasingStyle.ps1 @@ -51,7 +51,7 @@ $currentStyle = Get-CasingStyle -Text $Text - $words = Split-StringByCasingStyle -Text $Text -By $currentStyle + $words = Split-CasingStyle -Text $Text -By $currentStyle # Convert the words into the target style switch ($To) { diff --git a/src/functions/private/Split-StringByCasingStyle.ps1 b/src/functions/public/Split-CasingStyle.ps1 similarity index 79% rename from src/functions/private/Split-StringByCasingStyle.ps1 rename to src/functions/public/Split-CasingStyle.ps1 index a3cd8d7..3fe8bbe 100644 --- a/src/functions/private/Split-StringByCasingStyle.ps1 +++ b/src/functions/public/Split-CasingStyle.ps1 @@ -1,4 +1,4 @@ -filter Split-StringByCasingStyle { +filter Split-CasingStyle { <# .SYNOPSIS Splits a kebab-case string into an array of words @@ -7,7 +7,7 @@ This function splits a kebab-case string into an array of words. .EXAMPLE - Split-StringByCasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case + Split-CasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case this is @@ -17,7 +17,7 @@ string .EXAMPLE - Split-StringByCasingStyle -Text 'this_is_a_kebab_case_string' -By 'snake_case' + Split-CasingStyle -Text 'this_is_a_kebab_case_string' -By 'snake_case' this is @@ -27,7 +27,7 @@ string .EXAMPLE - Split-StringByCasingStyle -Text 'ThisIsAPascalCaseString' -By 'PascalCase' + Split-CasingStyle -Text 'ThisIsAPascalCaseString' -By 'PascalCase' This Is @@ -37,7 +37,7 @@ String .EXAMPLE - Split-StringByCasingStyle -Text 'thisIsACamelCaseString' -By 'camelCase' + Split-CasingStyle -Text 'thisIsACamelCaseString' -By 'camelCase' this Is @@ -47,7 +47,7 @@ String .EXAMPLE - Split-StringByCasingStyle -Text 'this_is_a-CamelCaseString' -By kebab-case | Split-StringByCasingStyle -By snake_case + Split-CasingStyle -Text 'this_is_a-CamelCaseString' -By kebab-case | Split-CasingStyle -By snake_case this_is_a camelcasestring diff --git a/tests/Casing.Tests.ps1 b/tests/Casing.Tests.ps1 index bf5b7dc..8b216ce 100644 --- a/tests/Casing.Tests.ps1 +++ b/tests/Casing.Tests.ps1 @@ -84,7 +84,6 @@ 't_t' | Get-CasingStyle | Should -Be 'snake_case' } } - Context 'Function: ConvertTo-CasingStyle' { It "ConvertTo-CasingStyle: Converts 'thisIsCamelCase' to 'snake_case'" { 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'snake_case' | Should -Be 'this_is_camel_case' @@ -98,4 +97,28 @@ 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' | Should -Be 'this-is-camel-case' } } + Context 'Function: Split-CasingStyle' { + It "Split-CasingStyle: Splits 'this_is_a_kebab_case_string' by 'snake_case'" { + 'this_is_a_kebab_case_string' | Split-CasingStyle -By 'snake_case' | Should -Be @('this', 'is', 'a', 'kebab', 'case', 'string') + } + + It "Split-CasingStyle: Splits 'ThisIsAPascalCaseString' by 'PascalCase'" { + 'ThisIsAPascalCaseString' | Split-CasingStyle -By 'PascalCase' | Should -Be @('This', 'Is', 'A', 'Pascal', 'Case', 'String') + } + + It "Split-CasingStyle: Splits 'thisIsACamelCaseString' by 'camelCase'" { + 'thisIsACamelCaseString' | Split-CasingStyle -By 'camelCase' | Should -Be @('this', 'Is', 'A', 'Camel', 'Case', 'String') + } + + It "Split-CasingStyle: Splits 'this_is_a-CamelCaseString' by kebab-case | Split-CasingStyle -By snake_case" { + 'this_is_a-CamelCaseString' | + Split-CasingStyle -By kebab-case | + Split-CasingStyle -By snake_case | + Should -Be @('this_is_a', 'camelcasestring') + } + + It "Split-CasingStyle: Splits 'this-is-a-kebab-case-string' by kebab-case" { + 'this-is-a-kebab-case-string' | Split-CasingStyle -By kebab-case | Should -Be @('this', 'is', 'a', 'kebab', 'case', 'string') + } + } } From 1dcb21670c202b4f92fcea6d4728a39910f34191 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 12:26:28 +0100 Subject: [PATCH 03/10] Update Get-CasingStyle to use UpperSnakeCase and enhance Split-CasingStyle tests --- src/functions/public/Get-CasingStyle.ps1 | 2 +- tests/Casing.Tests.ps1 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/functions/public/Get-CasingStyle.ps1 b/src/functions/public/Get-CasingStyle.ps1 index 2db69cc..1a039e7 100644 --- a/src/functions/public/Get-CasingStyle.ps1 +++ b/src/functions/public/Get-CasingStyle.ps1 @@ -88,7 +88,7 @@ 'UPPER-KEBAB-CASE' } elseif ([regex]::Match($Text, $script:SnakeCase).Success) { 'snake_case' - } elseif ([regex]::Match($Text, $script:UpperCase).Success) { + } elseif ([regex]::Match($Text, $script:UpperSnakeCase).Success) { 'UPPER_SNAKE_CASE' } else { 'Unknown' diff --git a/tests/Casing.Tests.ps1 b/tests/Casing.Tests.ps1 index 8b216ce..40275bd 100644 --- a/tests/Casing.Tests.ps1 +++ b/tests/Casing.Tests.ps1 @@ -114,7 +114,8 @@ 'this_is_a-CamelCaseString' | Split-CasingStyle -By kebab-case | Split-CasingStyle -By snake_case | - Should -Be @('this_is_a', 'camelcasestring') + Split-CasingStyle -By PascalCase | + Should -Be @('this', 'is', 'a', 'Camel', 'Case', 'String') } It "Split-CasingStyle: Splits 'this-is-a-kebab-case-string' by kebab-case" { From 27f6b4d6770acb29ebeae4f897736fd64cb0faa7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 12:36:27 +0100 Subject: [PATCH 04/10] Enhance Split-CasingStyle to support multiple casing styles and update documentation --- src/functions/public/Split-CasingStyle.ps1 | 93 +++++++++++++++++----- tests/Casing.Tests.ps1 | 3 +- 2 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/functions/public/Split-CasingStyle.ps1 b/src/functions/public/Split-CasingStyle.ps1 index 3fe8bbe..f0ec6e9 100644 --- a/src/functions/public/Split-CasingStyle.ps1 +++ b/src/functions/public/Split-CasingStyle.ps1 @@ -1,10 +1,12 @@ filter Split-CasingStyle { <# .SYNOPSIS - Splits a kebab-case string into an array of words + Splits a string based on one or more casing styles. .DESCRIPTION - This function splits a kebab-case string into an array of words. + This function takes a string and an array of casing styles (via the -By parameter) + and splits the string into its component words. It does this iteratively, + applying each split to every token produced by the previous one. .EXAMPLE Split-CasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case @@ -52,19 +54,22 @@ this_is_a camelcasestring + .EXAMPLE + 'this_is_a-PascalString' | Split-CasingStyle -By 'snake_case','kebab-case','PascalCase' + .OUTPUTS + [string[]] An array of strings, each representing a word in the original string. #> - [OutputType([string[]])] [CmdletBinding()] - param ( + param( # The string to split [Parameter( Mandatory, ValueFromPipeline )] - [string] $Text, + [string]$Text, - # The casing style to split the string by + # The casing style(s) to split the string by. [Parameter()] [ValidateSet( 'lowercase', @@ -78,24 +83,68 @@ 'snake_case', 'UPPER_SNAKE_CASE' )] - [string] $By + [string[]]$By ) - $styles = $PSBoundParameters | Where-Object { $_.Value -eq $true } | Select-Object -ExpandProperty Name - - Write-Verbose "Splitting string [$Text] by casing style [$($styles -join ', ' )]" - $splitText = switch ($By) { - 'PascalCase' { [regex]::Matches($Text, '([A-Z][a-z]*)').Value; break } - 'camelCase' { [regex]::Matches($Text, '([A-Z][a-z]*)|^[a-z]+').Value; break } - 'kebab-case' { $Text -split '-'; break } - 'UPPER-KEBAB-CASE' { $Text -split '-'; break } - 'snake_case' { $Text -split '_'; break } - 'UPPER_SNAKE_CASE' { $Text -split '_'; break } - default { - $Text -split ' ' + process { + Write-Verbose "Starting with string: [$Text]" + # Start with the original text as the only token. + $tokens = @($Text) + + # For each casing style in the -By list, split every token accordingly. + foreach ($style in $By) { + Write-Verbose "Splitting by casing style: $style" + $newTokens = @() + foreach ($token in $tokens) { + switch ($style) { + 'PascalCase' { + # Use regex to match sequences like 'Pascal' and 'String' in 'PascalString' + $matchedTokens = [regex]::Matches($token, '([A-Z][a-z]*)') + if ($matchedTokens.Count -gt 0) { + $newTokens += $matchedTokens | ForEach-Object { $_.Value } + } else { + $newTokens += $token + } + break + } + 'camelCase' { + # Match leading lowercase or uppercase letter groups + $matchedTokens = [regex]::Matches($token, '(^[a-z]+|[A-Z][a-z]*)') + if ($matchedTokens.Count -gt 0) { + $newTokens += $matchedTokens | ForEach-Object { $_.Value } + } else { + $newTokens += $token + } + break + } + 'kebab-case' { + $newTokens += $token -split '-' + break + } + 'UPPER-KEBAB-CASE' { + $newTokens += $token -split '-' + break + } + 'snake_case' { + $newTokens += $token -split '_' + break + } + 'UPPER_SNAKE_CASE' { + $newTokens += $token -split '_' + break + } + default { + # For any other case styles, you might split on whitespace + $newTokens += $token -split ' ' + break + } + } + } + # Update tokens with the newly split parts + $tokens = $newTokens + Write-Verbose "Tokens after splitting by $style`: [$($tokens -join ', ')]" } + Write-Verbose "Final result: [$($tokens -join ', ')]" + $tokens } - - Write-Verbose "Result: [$($splitText -join ', ')]" - $splitText } diff --git a/tests/Casing.Tests.ps1 b/tests/Casing.Tests.ps1 index 40275bd..3ca7b8d 100644 --- a/tests/Casing.Tests.ps1 +++ b/tests/Casing.Tests.ps1 @@ -113,8 +113,7 @@ It "Split-CasingStyle: Splits 'this_is_a-CamelCaseString' by kebab-case | Split-CasingStyle -By snake_case" { 'this_is_a-CamelCaseString' | Split-CasingStyle -By kebab-case | - Split-CasingStyle -By snake_case | - Split-CasingStyle -By PascalCase | + Split-CasingStyle -By snake_case, PascalCase | Should -Be @('this', 'is', 'a', 'Camel', 'Case', 'String') } From 0156f41edeee1f33c9e7ff37a717e25773f458b9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 13:25:56 +0100 Subject: [PATCH 05/10] Add unit tests for Get-CasingStyle, ConvertTo-CasingStyle, and Split-CasingStyle functions --- tests/OpenAI.Tests.ps1 | 124 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tests/OpenAI.Tests.ps1 diff --git a/tests/OpenAI.Tests.ps1 b/tests/OpenAI.Tests.ps1 new file mode 100644 index 0000000..6219c0e --- /dev/null +++ b/tests/OpenAI.Tests.ps1 @@ -0,0 +1,124 @@ +# CasingModule.Tests.ps1 +# ================================================ +# Dot-source the module file containing your filters. +# Adjust the path as necessary. +. "$PSScriptRoot\CasingModule.ps1" + +#-------------------------------------------------------------------- +# Test Get-CasingStyle: verify that known inputs are detected correctly, +# and that ambiguous strings return 'Unknown' +#-------------------------------------------------------------------- +Describe 'Get-CasingStyle Tests' { + + Context 'When given valid casing strings' { + $testCases = @( + @{ Input = 'testtest' ; Expected = 'lowercase' }, + @{ Input = 'TESTTEST' ; Expected = 'UPPERCASE' }, + @{ Input = 'Testtest' ; Expected = 'Sentencecase' }, + @{ Input = 'Test Test'; Expected = 'Title Case' }, + @{ Input = 'TestTest' ; Expected = 'PascalCase' }, + @{ Input = 'testTest' ; Expected = 'camelCase' }, + @{ Input = 'test-test'; Expected = 'kebab-case' }, + @{ Input = 'TEST-TEST'; Expected = 'UPPER-KEBAB-CASE' }, + @{ Input = 'test_test'; Expected = 'snake_case' }, + @{ Input = 'TEST_TEST'; Expected = 'UPPER_SNAKE_CASE' } + ) + + It "detects '' as ')'" -ForEach $testCases { + $result = $Input | Get-CasingStyle + $result | Should -Be $Expected + } + } + + Context 'When given an ambiguous or unsupported string' { + It "returns 'Unknown'" { + 'Test_teSt-Test' | Get-CasingStyle | Should -Be 'Unknown' + } + } +} + +#-------------------------------------------------------------------- +# Test ConvertTo-CasingStyle: verify that converting a sample string +# (here, in camelCase) to each target style produces the expected output. +# Also verify that conversion fails when the input style is unknown. +#-------------------------------------------------------------------- +Describe 'ConvertTo-CasingStyle Tests' { + + Context 'Converting from camelCase' { + # Our sample input is in camelCase. + $inputText = 'thisIsCamelCase' + $expectedResults = @( + @{ Name = 'lowercase' ; Expected = 'thisiscamelcase' } + @{ Name = 'UPPERCASE' ; Expected = 'THISISCAMELCASE' } + @{ Name = 'Sentencecase' ; Expected = 'Thisiscamelcase' } + @{ Name = 'Title Case' ; Expected = 'This Is Camel Case' } + @{ Name = 'PascalCase' ; Expected = 'ThisIsCamelCase' } + @{ Name = 'camelCase' ; Expected = 'thisIsCamelCase' } + @{ Name = 'kebab-case' ; Expected = 'this-is-camel-case' } + @{ Name = 'UPPER-KEBAB-CASE' ; Expected = 'THIS-IS-CAMEL-CASE' } + @{ Name = 'snake_case' ; Expected = 'this_is_camel_case' } + @{ Name = 'UPPER_SNAKE_CASE' ; Expected = 'THIS_IS_CAMEL_CASE' } + ) + + foreach ($target in $expectedResults.Keys) { + It "converts '$inputText' to $target" { + $result = $inputText | ConvertTo-CasingStyle -To $target + $result | Should -Be $expectedResults[$target] + } + } + } + + Context 'When the input casing cannot be determined' { + It "throws an error because the ValidateSet in Split-CasingStyle will not accept 'Unknown'" { + { 'Test_teSt-Test' | ConvertTo-CasingStyle -To 'snake_case' } | Should -Throw + } + } +} + +#-------------------------------------------------------------------- +# Test Split-CasingStyle: verify that the function correctly splits +# strings according to the provided casing style(s) +#-------------------------------------------------------------------- +Describe 'Split-CasingStyle Tests' { + + It 'splits a kebab-case string into individual words' { + $inputText = 'this-is-a-kebab-case-string' + $expected = 'this', 'is', 'a', 'kebab', 'case', 'string' + $result = $inputText | Split-CasingStyle -By 'kebab-case' + $result | Should -Be $expected + } + + It 'splits a snake_case string into individual words' { + $inputText = 'this_is_a_snake_case_string' + $expected = 'this', 'is', 'a', 'snake', 'case', 'string' + $result = $inputText | Split-CasingStyle -By 'snake_case' + $result | Should -Be $expected + } + + It 'splits a PascalCase string into individual words' { + $inputText = 'ThisIsAPascalCaseString' + $expected = 'This', 'Is', 'A', 'Pascal', 'Case', 'String' + $result = $inputText | Split-CasingStyle -By 'PascalCase' + $result | Should -Be $expected + } + + It 'splits a camelCase string into individual words' { + $inputText = 'thisIsACamelCaseString' + $expected = 'this', 'Is', 'A', 'Camel', 'Case', 'String' + $result = $inputText | Split-CasingStyle -By 'camelCase' + $result | Should -Be $expected + } + + It 'handles multiple splitting criteria in succession' { + # In this example the string is first split on snake_case, + # then on kebab-case, and finally on PascalCase. + # Explanation: + # • 'this_is_a-PascalString' → snake_case splits to: 'this', 'is', 'a-PascalString' + # • Then kebab-case splits 'a-PascalString' into 'a' and 'PascalString' + # • Then PascalCase splits 'PascalString' into 'Pascal' and 'String' + $inputText = 'this_is_a-PascalString' + $expected = 'this', 'is', 'a', 'Pascal', 'String' + $result = $inputText | Split-CasingStyle -By 'snake_case', 'kebab-case', 'PascalCase' + $result | Should -Be $expected + } +} From d6b09b8e03714fd3bd70223ec2948c3bcad8863b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 13:35:33 +0100 Subject: [PATCH 06/10] Update documentation for ConvertTo-CasingStyle and Split-CasingStyle functions; enhance tests for ConvertTo-CasingStyle --- .../public/ConvertTo-CasingStyle.ps1 | 28 ++++++++--------- src/functions/public/Split-CasingStyle.ps1 | 3 ++ tests/OpenAI.Tests.ps1 | 31 +++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/functions/public/ConvertTo-CasingStyle.ps1 b/src/functions/public/ConvertTo-CasingStyle.ps1 index d8b08ef..357c6e7 100644 --- a/src/functions/public/ConvertTo-CasingStyle.ps1 +++ b/src/functions/public/ConvertTo-CasingStyle.ps1 @@ -1,26 +1,26 @@ filter ConvertTo-CasingStyle { <# - .SYNOPSIS - Convert a string to a different casing style + .SYNOPSIS + Convert a string to a different casing style - .DESCRIPTION - This function converts a string to a different casing style. + .DESCRIPTION + This function converts a string to a different casing style. - .EXAMPLE - 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'snake_case' + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'snake_case' - Convert the string 'thisIsCamelCase' to 'this_is_camel_case' + Convert the string 'thisIsCamelCase' to 'this_is_camel_case' - .EXAMPLE - 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'UPPER_SNAKE_CASE' + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'UPPER_SNAKE_CASE' - Convert the string 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE' + Convert the string 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE' - .EXAMPLE - 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' + .EXAMPLE + 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' - .NOTES - General notes + .LINK + https://psmodule.io/Casing/Functions/ConvertTo-CasingStyle/ #> [OutputType([string])] [CmdletBinding()] diff --git a/src/functions/public/Split-CasingStyle.ps1 b/src/functions/public/Split-CasingStyle.ps1 index f0ec6e9..ee875a9 100644 --- a/src/functions/public/Split-CasingStyle.ps1 +++ b/src/functions/public/Split-CasingStyle.ps1 @@ -59,6 +59,9 @@ .OUTPUTS [string[]] An array of strings, each representing a word in the original string. + + .LINK + https://psmodule.io/Casing/Functions/Split-CasingStyle/ #> [CmdletBinding()] param( diff --git a/tests/OpenAI.Tests.ps1 b/tests/OpenAI.Tests.ps1 index 6219c0e..756478b 100644 --- a/tests/OpenAI.Tests.ps1 +++ b/tests/OpenAI.Tests.ps1 @@ -46,25 +46,22 @@ Describe 'ConvertTo-CasingStyle Tests' { Context 'Converting from camelCase' { # Our sample input is in camelCase. - $inputText = 'thisIsCamelCase' - $expectedResults = @( - @{ Name = 'lowercase' ; Expected = 'thisiscamelcase' } - @{ Name = 'UPPERCASE' ; Expected = 'THISISCAMELCASE' } - @{ Name = 'Sentencecase' ; Expected = 'Thisiscamelcase' } - @{ Name = 'Title Case' ; Expected = 'This Is Camel Case' } - @{ Name = 'PascalCase' ; Expected = 'ThisIsCamelCase' } - @{ Name = 'camelCase' ; Expected = 'thisIsCamelCase' } - @{ Name = 'kebab-case' ; Expected = 'this-is-camel-case' } - @{ Name = 'UPPER-KEBAB-CASE' ; Expected = 'THIS-IS-CAMEL-CASE' } - @{ Name = 'snake_case' ; Expected = 'this_is_camel_case' } - @{ Name = 'UPPER_SNAKE_CASE' ; Expected = 'THIS_IS_CAMEL_CASE' } + $testCases = @( + @{ Name = 'lowercase' ; Text = 'thisIsCamelCase' ; Expected = 'thisiscamelcase' } + @{ Name = 'UPPERCASE' ; Text = 'thisIsCamelCase' ; Expected = 'THISISCAMELCASE' } + @{ Name = 'Sentencecase' ; Text = 'thisIsCamelCase' ; Expected = 'Thisiscamelcase' } + @{ Name = 'Title Case' ; Text = 'thisIsCamelCase' ; Expected = 'This Is Camel Case' } + @{ Name = 'PascalCase' ; Text = 'thisIsCamelCase' ; Expected = 'ThisIsCamelCase' } + @{ Name = 'camelCase' ; Text = 'thisIsCamelCase' ; Expected = 'thisIsCamelCase' } + @{ Name = 'kebab-case' ; Text = 'thisIsCamelCase' ; Expected = 'this-is-camel-case' } + @{ Name = 'UPPER-KEBAB-CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS-IS-CAMEL-CASE' } + @{ Name = 'snake_case' ; Text = 'thisIsCamelCase' ; Expected = 'this_is_camel_case' } + @{ Name = 'UPPER_SNAKE_CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS_IS_CAMEL_CASE' } ) - foreach ($target in $expectedResults.Keys) { - It "converts '$inputText' to $target" { - $result = $inputText | ConvertTo-CasingStyle -To $target - $result | Should -Be $expectedResults[$target] - } + It "converts '' to '' using ''" -ForEach $testCases { + $result = $Text | ConvertTo-CasingStyle -To $Name + $result | Should -Be $Expected } } From d4eae459d17f5d870c76e799d8ca56528f336af5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 13:40:49 +0100 Subject: [PATCH 07/10] Remove unnecessary comments and adjust script structure in OpenAI.Tests.ps1 --- tests/OpenAI.Tests.ps1 | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/OpenAI.Tests.ps1 b/tests/OpenAI.Tests.ps1 index 756478b..e47309c 100644 --- a/tests/OpenAI.Tests.ps1 +++ b/tests/OpenAI.Tests.ps1 @@ -1,10 +1,4 @@ -# CasingModule.Tests.ps1 -# ================================================ -# Dot-source the module file containing your filters. -# Adjust the path as necessary. -. "$PSScriptRoot\CasingModule.ps1" - -#-------------------------------------------------------------------- +#-------------------------------------------------------------------- # Test Get-CasingStyle: verify that known inputs are detected correctly, # and that ambiguous strings return 'Unknown' #-------------------------------------------------------------------- From b582192c2135a25c50375242801f3bd8bc2ab2db Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 13:51:23 +0100 Subject: [PATCH 08/10] Refactor tests: remove OpenAI.Tests.ps1 and create UseCases.Tests.ps1 with enhanced casing style tests --- tests/OpenAI.Tests.ps1 | 115 --------------------------------------- tests/UseCases.Tests.ps1 | 80 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 115 deletions(-) delete mode 100644 tests/OpenAI.Tests.ps1 create mode 100644 tests/UseCases.Tests.ps1 diff --git a/tests/OpenAI.Tests.ps1 b/tests/OpenAI.Tests.ps1 deleted file mode 100644 index e47309c..0000000 --- a/tests/OpenAI.Tests.ps1 +++ /dev/null @@ -1,115 +0,0 @@ -#-------------------------------------------------------------------- -# Test Get-CasingStyle: verify that known inputs are detected correctly, -# and that ambiguous strings return 'Unknown' -#-------------------------------------------------------------------- -Describe 'Get-CasingStyle Tests' { - - Context 'When given valid casing strings' { - $testCases = @( - @{ Input = 'testtest' ; Expected = 'lowercase' }, - @{ Input = 'TESTTEST' ; Expected = 'UPPERCASE' }, - @{ Input = 'Testtest' ; Expected = 'Sentencecase' }, - @{ Input = 'Test Test'; Expected = 'Title Case' }, - @{ Input = 'TestTest' ; Expected = 'PascalCase' }, - @{ Input = 'testTest' ; Expected = 'camelCase' }, - @{ Input = 'test-test'; Expected = 'kebab-case' }, - @{ Input = 'TEST-TEST'; Expected = 'UPPER-KEBAB-CASE' }, - @{ Input = 'test_test'; Expected = 'snake_case' }, - @{ Input = 'TEST_TEST'; Expected = 'UPPER_SNAKE_CASE' } - ) - - It "detects '' as ')'" -ForEach $testCases { - $result = $Input | Get-CasingStyle - $result | Should -Be $Expected - } - } - - Context 'When given an ambiguous or unsupported string' { - It "returns 'Unknown'" { - 'Test_teSt-Test' | Get-CasingStyle | Should -Be 'Unknown' - } - } -} - -#-------------------------------------------------------------------- -# Test ConvertTo-CasingStyle: verify that converting a sample string -# (here, in camelCase) to each target style produces the expected output. -# Also verify that conversion fails when the input style is unknown. -#-------------------------------------------------------------------- -Describe 'ConvertTo-CasingStyle Tests' { - - Context 'Converting from camelCase' { - # Our sample input is in camelCase. - $testCases = @( - @{ Name = 'lowercase' ; Text = 'thisIsCamelCase' ; Expected = 'thisiscamelcase' } - @{ Name = 'UPPERCASE' ; Text = 'thisIsCamelCase' ; Expected = 'THISISCAMELCASE' } - @{ Name = 'Sentencecase' ; Text = 'thisIsCamelCase' ; Expected = 'Thisiscamelcase' } - @{ Name = 'Title Case' ; Text = 'thisIsCamelCase' ; Expected = 'This Is Camel Case' } - @{ Name = 'PascalCase' ; Text = 'thisIsCamelCase' ; Expected = 'ThisIsCamelCase' } - @{ Name = 'camelCase' ; Text = 'thisIsCamelCase' ; Expected = 'thisIsCamelCase' } - @{ Name = 'kebab-case' ; Text = 'thisIsCamelCase' ; Expected = 'this-is-camel-case' } - @{ Name = 'UPPER-KEBAB-CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS-IS-CAMEL-CASE' } - @{ Name = 'snake_case' ; Text = 'thisIsCamelCase' ; Expected = 'this_is_camel_case' } - @{ Name = 'UPPER_SNAKE_CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS_IS_CAMEL_CASE' } - ) - - It "converts '' to '' using ''" -ForEach $testCases { - $result = $Text | ConvertTo-CasingStyle -To $Name - $result | Should -Be $Expected - } - } - - Context 'When the input casing cannot be determined' { - It "throws an error because the ValidateSet in Split-CasingStyle will not accept 'Unknown'" { - { 'Test_teSt-Test' | ConvertTo-CasingStyle -To 'snake_case' } | Should -Throw - } - } -} - -#-------------------------------------------------------------------- -# Test Split-CasingStyle: verify that the function correctly splits -# strings according to the provided casing style(s) -#-------------------------------------------------------------------- -Describe 'Split-CasingStyle Tests' { - - It 'splits a kebab-case string into individual words' { - $inputText = 'this-is-a-kebab-case-string' - $expected = 'this', 'is', 'a', 'kebab', 'case', 'string' - $result = $inputText | Split-CasingStyle -By 'kebab-case' - $result | Should -Be $expected - } - - It 'splits a snake_case string into individual words' { - $inputText = 'this_is_a_snake_case_string' - $expected = 'this', 'is', 'a', 'snake', 'case', 'string' - $result = $inputText | Split-CasingStyle -By 'snake_case' - $result | Should -Be $expected - } - - It 'splits a PascalCase string into individual words' { - $inputText = 'ThisIsAPascalCaseString' - $expected = 'This', 'Is', 'A', 'Pascal', 'Case', 'String' - $result = $inputText | Split-CasingStyle -By 'PascalCase' - $result | Should -Be $expected - } - - It 'splits a camelCase string into individual words' { - $inputText = 'thisIsACamelCaseString' - $expected = 'this', 'Is', 'A', 'Camel', 'Case', 'String' - $result = $inputText | Split-CasingStyle -By 'camelCase' - $result | Should -Be $expected - } - - It 'handles multiple splitting criteria in succession' { - # In this example the string is first split on snake_case, - # then on kebab-case, and finally on PascalCase. - # Explanation: - # • 'this_is_a-PascalString' → snake_case splits to: 'this', 'is', 'a-PascalString' - # • Then kebab-case splits 'a-PascalString' into 'a' and 'PascalString' - # • Then PascalCase splits 'PascalString' into 'Pascal' and 'String' - $inputText = 'this_is_a-PascalString' - $expected = 'this', 'is', 'a', 'Pascal', 'String' - $result = $inputText | Split-CasingStyle -By 'snake_case', 'kebab-case', 'PascalCase' - $result | Should -Be $expected - } -} diff --git a/tests/UseCases.Tests.ps1 b/tests/UseCases.Tests.ps1 new file mode 100644 index 0000000..3567f28 --- /dev/null +++ b/tests/UseCases.Tests.ps1 @@ -0,0 +1,80 @@ +#-------------------------------------------------------------------- +# Test Get-CasingStyle: verify that known inputs are detected correctly, +# and that ambiguous strings return 'Unknown' +#-------------------------------------------------------------------- +Describe 'Get-CasingStyle Tests' { + + Context 'When given valid casing strings' { + $testCases = @( + @{ Text = 'testtest' ; Expected = 'lowercase' }, + @{ Text = 'TESTTEST' ; Expected = 'UPPERCASE' }, + @{ Text = 'Testtest' ; Expected = 'Sentencecase' }, + @{ Text = 'Test Test' ; Expected = 'Title Case' }, + @{ Text = 'TestTest' ; Expected = 'PascalCase' }, + @{ Text = 'testTest' ; Expected = 'camelCase' }, + @{ Text = 'test-test' ; Expected = 'kebab-case' }, + @{ Text = 'TEST-TEST' ; Expected = 'UPPER-KEBAB-CASE' }, + @{ Text = 'test_test' ; Expected = 'snake_case' }, + @{ Text = 'TEST_TEST' ; Expected = 'UPPER_SNAKE_CASE' } + @{ Text = 'Test_teSt-Test'; Expected = 'Unknown' } + ) + + It "detects '' as ')'" -ForEach $testCases { + $Text | Get-CasingStyle | Should -Be $Expected + } + } +} + +#-------------------------------------------------------------------- +# Test ConvertTo-CasingStyle: verify that converting a sample string +# (here, in camelCase) to each target style produces the expected output. +# Also verify that conversion fails when the input style is unknown. +#-------------------------------------------------------------------- +Describe 'ConvertTo-CasingStyle Tests' { + + Context 'Converting from camelCase' { + # Our sample input is in camelCase. + $testCases = @( + @{ Name = 'lowercase' ; Text = 'thisIsCamelCase' ; Expected = 'thisiscamelcase' } + @{ Name = 'UPPERCASE' ; Text = 'thisIsCamelCase' ; Expected = 'THISISCAMELCASE' } + @{ Name = 'Sentencecase' ; Text = 'thisIsCamelCase' ; Expected = 'Thisiscamelcase' } + @{ Name = 'Title Case' ; Text = 'thisIsCamelCase' ; Expected = 'This Is Camel Case' } + @{ Name = 'PascalCase' ; Text = 'thisIsCamelCase' ; Expected = 'ThisIsCamelCase' } + @{ Name = 'camelCase' ; Text = 'thisIsCamelCase' ; Expected = 'thisIsCamelCase' } + @{ Name = 'kebab-case' ; Text = 'thisIsCamelCase' ; Expected = 'this-is-camel-case' } + @{ Name = 'UPPER-KEBAB-CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS-IS-CAMEL-CASE' } + @{ Name = 'snake_case' ; Text = 'thisIsCamelCase' ; Expected = 'this_is_camel_case' } + @{ Name = 'UPPER_SNAKE_CASE' ; Text = 'thisIsCamelCase' ; Expected = 'THIS_IS_CAMEL_CASE' } + ) + + It "converts '' to '' using ''" -ForEach $testCases { + $result = $Text | ConvertTo-CasingStyle -To $Name + $result | Should -Be $Expected + } + } + + Context 'When the input casing cannot be determined' { + It "throws an error because the ValidateSet in Split-CasingStyle will not accept 'Unknown'" { + { 'Test_teSt-Test' | ConvertTo-CasingStyle -To 'snake_case' } | Should -Throw + } + } +} + +#-------------------------------------------------------------------- +# Test Split-CasingStyle: verify that the function correctly splits +# strings according to the provided casing style(s) +#-------------------------------------------------------------------- +Describe 'Split-CasingStyle Tests' { + + $testCases = @( + @{ Text = 'this-is-a-kebab-case-string'; SplitBy = 'kebab-case' ; Expected = 'this', 'is', 'a', 'kebab', 'case', 'string' } + @{ Text = 'this_is_a_snake_case_string' ; SplitBy = 'snake_case' ; Expected = 'this', 'is', 'a', 'snake', 'case', 'string' } + @{ Text = 'ThisIsAPascalCaseString' ; SplitBy = 'PascalCase' ; Expected = 'This', 'Is', 'A', 'Pascal', 'Case', 'String' } + @{ Text = 'thisIsACamelCaseString' ; SplitBy = 'camelCase' ; Expected = 'this', 'Is', 'A', 'Camel', 'Case', 'String' } + @{ Text = 'this_is_a-PascalString' ; SplitBy = 'snake_case', 'kebab-case', 'PascalCase' ; Expected = 'this', 'is', 'a', 'Pascal', 'String' } + ) + + It 'splits using into individual words' -ForEach $testCases { + $Text | Split-CasingStyle -By $SplitBy | Should -Be $expected + } +} From d6f15f0fa699224ad57946ba97738ebb563f9b58 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 13:59:01 +0100 Subject: [PATCH 09/10] Add OUTPUTS section to documentation for ConvertTo-CasingStyle, Get-CasingStyle, and Split-CasingStyle functions --- src/functions/public/ConvertTo-CasingStyle.ps1 | 5 +++++ src/functions/public/Get-CasingStyle.ps1 | 5 +++++ src/functions/public/Split-CasingStyle.ps1 | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/functions/public/ConvertTo-CasingStyle.ps1 b/src/functions/public/ConvertTo-CasingStyle.ps1 index 357c6e7..94c7d8c 100644 --- a/src/functions/public/ConvertTo-CasingStyle.ps1 +++ b/src/functions/public/ConvertTo-CasingStyle.ps1 @@ -19,6 +19,11 @@ .EXAMPLE 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' + .OUTPUTS + [string] + + The converted string. + .LINK https://psmodule.io/Casing/Functions/ConvertTo-CasingStyle/ #> diff --git a/src/functions/public/Get-CasingStyle.ps1 b/src/functions/public/Get-CasingStyle.ps1 index 1a039e7..37df8d4 100644 --- a/src/functions/public/Get-CasingStyle.ps1 +++ b/src/functions/public/Get-CasingStyle.ps1 @@ -56,6 +56,11 @@ Unknown + .OUTPUTS + [string] + + The detected casing style of the input string. + .LINK https://psmodule.io/Casing/Functions/Get-CasingStyle/ #> diff --git a/src/functions/public/Split-CasingStyle.ps1 b/src/functions/public/Split-CasingStyle.ps1 index ee875a9..d99b56c 100644 --- a/src/functions/public/Split-CasingStyle.ps1 +++ b/src/functions/public/Split-CasingStyle.ps1 @@ -58,7 +58,9 @@ 'this_is_a-PascalString' | Split-CasingStyle -By 'snake_case','kebab-case','PascalCase' .OUTPUTS - [string[]] An array of strings, each representing a word in the original string. + [string[]] + + An array of strings, each representing a word in the original string. .LINK https://psmodule.io/Casing/Functions/Split-CasingStyle/ From 584103b6fdcfb0a5fe00b1ee638e7aa1da912743 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 2 Feb 2025 14:07:12 +0100 Subject: [PATCH 10/10] Refactor OUTPUTS section in ConvertTo-CasingStyle, Get-CasingStyle, and Split-CasingStyle functions for clarity --- src/functions/public/ConvertTo-CasingStyle.ps1 | 4 +--- src/functions/public/Get-CasingStyle.ps1 | 4 +--- src/functions/public/Split-CasingStyle.ps1 | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/functions/public/ConvertTo-CasingStyle.ps1 b/src/functions/public/ConvertTo-CasingStyle.ps1 index 94c7d8c..2db5dcc 100644 --- a/src/functions/public/ConvertTo-CasingStyle.ps1 +++ b/src/functions/public/ConvertTo-CasingStyle.ps1 @@ -20,9 +20,7 @@ 'thisIsCamelCase' | ConvertTo-CasingStyle -To 'kebab-case' .OUTPUTS - [string] - - The converted string. + [string] - The converted string .LINK https://psmodule.io/Casing/Functions/ConvertTo-CasingStyle/ diff --git a/src/functions/public/Get-CasingStyle.ps1 b/src/functions/public/Get-CasingStyle.ps1 index 37df8d4..56b574a 100644 --- a/src/functions/public/Get-CasingStyle.ps1 +++ b/src/functions/public/Get-CasingStyle.ps1 @@ -57,9 +57,7 @@ Unknown .OUTPUTS - [string] - - The detected casing style of the input string. + [string] - The detected casing style of the input string .LINK https://psmodule.io/Casing/Functions/Get-CasingStyle/ diff --git a/src/functions/public/Split-CasingStyle.ps1 b/src/functions/public/Split-CasingStyle.ps1 index d99b56c..15aa5ec 100644 --- a/src/functions/public/Split-CasingStyle.ps1 +++ b/src/functions/public/Split-CasingStyle.ps1 @@ -58,9 +58,7 @@ 'this_is_a-PascalString' | Split-CasingStyle -By 'snake_case','kebab-case','PascalCase' .OUTPUTS - [string[]] - - An array of strings, each representing a word in the original string. + [string[]] - An array of strings, each representing a word in the original string .LINK https://psmodule.io/Casing/Functions/Split-CasingStyle/