From 415c1bce6b9d4095901844c40f22553609adb15f Mon Sep 17 00:00:00 2001 From: Arwyn <10365998+ArwynFr@users.noreply.github.com> Date: Thu, 15 Jun 2023 21:52:14 +0200 Subject: [PATCH] feat+: add new test command (#2) --- .github/README.adoc | 20 +++- ConventionalCommits/ConventionalCommits.psd1 | 1 + ConventionalCommits/ConventionalCommits.psm1 | 96 +++++++++++++++---- ...lCommits.Tests.ps1 => ConvertTo.Tests.ps1} | 1 - tests/Test.Tests.ps1 | 61 ++++++++++++ 5 files changed, 160 insertions(+), 19 deletions(-) rename tests/{ConventionalCommits.Tests.ps1 => ConvertTo.Tests.ps1} (98%) create mode 100644 tests/Test.Tests.ps1 diff --git a/.github/README.adoc b/.github/README.adoc index d3b5d27..40bdf63 100644 --- a/.github/README.adoc +++ b/.github/README.adoc @@ -12,7 +12,25 @@ The following documents provide additional information on rules and standards ap == How to use the module -This module contains a single command : +This module contains the following commands : + +=== Test-ConventionalCommitHeader + +Verifies whether the commit message header conforms to the conventional commit format. + +```Powershell +Test-ConventionalCommitHeader + [[-Message] ] + [-StrictTypes] + [-AdditionalModifiers] + [] +``` + +`-Message`:: *Required* and *Pipelinable*. The versioning message to parse. See https://www.conventionalcommits.org/en/v1.0.0/[conventionalcommits.org] for details on the message structure. + +`-StrictTypes`:: *Switch*. If true, the command will enforce the commit type to be in the following list: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test`. + +`-AdditionalModifiers`:: *Switch*. If true, the command will allow usage of `+` and `-` in addition to `!`. See below. === ConvertTo-ConventionalCommitHeader diff --git a/ConventionalCommits/ConventionalCommits.psd1 b/ConventionalCommits/ConventionalCommits.psd1 index 37ac2d0..3a3204a 100644 --- a/ConventionalCommits/ConventionalCommits.psd1 +++ b/ConventionalCommits/ConventionalCommits.psd1 @@ -16,5 +16,6 @@ RootModule = 'ConventionalCommits.psm1' FunctionsToExport = @( 'ConvertTo-ConventionalCommitHeader' + 'Test-ConventionalCommitHeader' ) } \ No newline at end of file diff --git a/ConventionalCommits/ConventionalCommits.psm1 b/ConventionalCommits/ConventionalCommits.psm1 index 0d1331c..eae3471 100644 --- a/ConventionalCommits/ConventionalCommits.psm1 +++ b/ConventionalCommits/ConventionalCommits.psm1 @@ -1,5 +1,55 @@ -function ConvertTo-ConventionalCommitHeader { +function Get-InternalStructure { + [CmdletBinding()] + [OutputType([hashtable])] + param ( + [Parameter(ValueFromPipeline)] + [string] + $Message, + + [Parameter()] + [switch] + $AdditionalModifiers + ) + + Process { + $pattern = $AdditionalModifiers ? '^(\w+)(\((\w+)\))?([!+-])?: (.*)' : '^(\w+)(\((\w+)\))?([!])?: (.*)' + $result = $Message -match $pattern + if (-not $result) { return $null } + + return @{ + Type = $matches[1] + Scope = $matches[3] + Modifier = $matches[4] + Description = $matches[5] + } + } +} + +function Test-InternalStructure { + [CmdletBinding()] + [OutputType([bool])] + param ( + [Parameter(ValueFromPipeline)] + [hashtable] + $Header, + + [Parameter()] + [switch] + $StrictTypes + ) + + Process { + $allowed_types = @('build'; 'chore'; 'ci'; 'docs'; 'feat'; 'fix'; 'perf'; 'refactor'; 'revert'; 'style'; 'test') + if ($null -eq $Header) { return $false } + if (-not $StrictTypes) { return $true } + if (-not $allowed_types.Contains($Header.Type)) { return $false } + return $true + } +} + +function Test-ConventionalCommitHeader { [CmdletBinding()] + [OutputType([bool])] param ( [Parameter(ValueFromPipeline)] [string] @@ -14,24 +64,36 @@ function ConvertTo-ConventionalCommitHeader { $AdditionalModifiers ) - $allowed_types = @('build'; 'chore'; 'ci'; 'docs'; 'feat'; 'fix'; 'perf'; 'refactor'; 'revert'; 'style'; 'test') - $pattern = $AdditionalModifiers ? '^(\w+)(\((\w+)\))?([!+-])?: (.*)' : '^(\w+)(\((\w+)\))?([!])?: (.*)' - $result = $Message -match $pattern - - if (-not $result) { - throw 'Commit message header does not follow the conventions' + Process { + return $Message | Get-InternalStructure -AdditionalModifiers:$AdditionalModifiers | Test-InternalStructure -StrictTypes:$StrictTypes } +} - $conventions = @{ - Type = $matches[1] - Scope = $matches[3] - Modifier = $matches[4] - Description = $matches[5] - } +function ConvertTo-ConventionalCommitHeader { + [CmdletBinding()] + [OutputType([hashtable])] + param ( + [Parameter(ValueFromPipeline)] + [string] + $Message, - if ($StrictTypes -and (-not $allowed_types.Contains($conventions.Type))) { - throw 'Commit message header type is not valid' - } + [Parameter()] + [switch] + $StrictTypes, + + [Parameter()] + [switch] + $AdditionalModifiers + ) - return $conventions + Process { + $conventions = $Message | Get-InternalStructure -AdditionalModifiers:$AdditionalModifiers + $valid = $conventions | Test-InternalStructure -StrictTypes:$StrictTypes + + if (-not $valid ) { + throw 'Commit message does not follow the conventions' + } + + return $conventions + } } diff --git a/tests/ConventionalCommits.Tests.ps1 b/tests/ConvertTo.Tests.ps1 similarity index 98% rename from tests/ConventionalCommits.Tests.ps1 rename to tests/ConvertTo.Tests.ps1 index abfa71d..c5ad2b7 100644 --- a/tests/ConventionalCommits.Tests.ps1 +++ b/tests/ConvertTo.Tests.ps1 @@ -23,7 +23,6 @@ InModuleScope ConventionalCommits { It 'Should fail a loose message' { { 'another(scope)!: description' | ConvertTo-ConventionalCommitHeader -StrictTypes } | Should -Throw } - # 'build'; 'chore'; 'ci'; 'docs'; 'feat'; 'fix'; 'perf'; 'refactor'; 'revert'; 'style'; 'test' It 'Should parse a strict message' { $actual = 'build(scope)!: description' | ConvertTo-ConventionalCommitHeader -StrictTypes $actual.Type | Should -Be 'build' diff --git a/tests/Test.Tests.ps1 b/tests/Test.Tests.ps1 new file mode 100644 index 0000000..b0ed63f --- /dev/null +++ b/tests/Test.Tests.ps1 @@ -0,0 +1,61 @@ +InModuleScope ConventionalCommits { + Describe 'Test-ConventionalCommitHeader' { + Context 'Default behavior' { + It 'Should parse a strict message' { + 'fix(scope)!: description' | Test-ConventionalCommitHeader | Should -BeTrue + } + It 'Should parse a loose message' { + 'custom(scope)!: description' | Test-ConventionalCommitHeader | Should -BeTrue + } + It 'Should fail an additional modifier' { + 'fix(scope)+: description' | Test-ConventionalCommitHeader | Should -BeFalse + } + } + Context 'Strict mode' { + It 'Should fail a loose message' { + 'another(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeFalse + } + It 'Should parse a strict message' { + 'build(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'chore(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'ci(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'docs(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'feat(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'fix(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'perf(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'refactor(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'revert(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'style(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + It 'Should parse a strict message' { + 'test(scope)!: description' | Test-ConventionalCommitHeader -StrictTypes | Should -BeTrue + } + } + Context 'Additional modifiers' { + It 'Should parse a minor modifier' { + 'fix(scope)+: description' | Test-ConventionalCommitHeader -AdditionalModifiers | Should -BeTrue + } + It 'Should parse a patch modifier' { + 'fix(scope)-: description' | Test-ConventionalCommitHeader -AdditionalModifiers | Should -BeTrue + } + } + } +} \ No newline at end of file