diff --git a/.github/workflows/Action-Test-Src-Default.yml b/.github/workflows/Action-Test-Src-Default.yml index 0fa6911e..5d3301b2 100644 --- a/.github/workflows/Action-Test-Src-Default.yml +++ b/.github/workflows/Action-Test-Src-Default.yml @@ -1,6 +1,6 @@ -name: Action-Test [Src-Default] +name: Action-Test-Src-Default -run-name: "Action-Test [Src-Default] - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}" +run-name: 'Action-Test-Src-Default - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}' on: workflow_dispatch: @@ -15,36 +15,21 @@ concurrency: permissions: {} jobs: - ActionTest: + ActionTestSrcDefault: + name: Action-Test [Src-Default] - [${{ matrix.os }}] strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - name: Action-Test [Src-Default] - [${{ matrix.os }}] runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@main - - name: Action-Test uses: ./ id: action-test - env: - GITHUB_TOKEN: ${{ github.token }} with: Name: PSModuleTest - Path: tests/src - TestType: SourceCode - - - name: Status - shell: pwsh - env: - PASSED: ${{ steps.action-test.outputs.passed }} - run: | - Write-Host "Passed: [$env:PASSED]" - if ($env:PASSED -ne 'true') { - exit 1 - } + WorkingDirectory: tests/srcTestRepo + Settings: SourceCode diff --git a/.github/workflows/Action-Test-Src-WithManifest.yml b/.github/workflows/Action-Test-Src-WithManifest.yml index b14f85b8..53dc398a 100644 --- a/.github/workflows/Action-Test-Src-WithManifest.yml +++ b/.github/workflows/Action-Test-Src-WithManifest.yml @@ -1,6 +1,6 @@ -name: Action-Test [Src-WithManifest] +name: Action-Test-Src-WithManifest -run-name: "Action-Test [Src-WithManifest] - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}" +run-name: 'Action-Test-Src-WithManifest - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}' on: workflow_dispatch: @@ -15,36 +15,21 @@ concurrency: permissions: {} jobs: - ActionTest: + ActionTestsSrcWithManifest: + name: Action-Test [Src-WithManifest] - [${{ matrix.os }}] strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - name: Action-Test [Src-WithManifest] - [${{ matrix.os }}] runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@main - - name: Action-Test uses: ./ id: action-test - env: - GITHUB_TOKEN: ${{ github.token }} with: Name: PSModuleTest - Path: tests/srcWithManifest - TestType: SourceCode - - - name: Status - shell: pwsh - env: - PASSED: ${{ steps.action-test.outputs.passed }} - run: | - Write-Host "Passed: [$env:PASSED]" - if ($env:PASSED -ne 'true') { - exit 1 - } + WorkingDirectory: tests/srcWithManifestTestRepo + Settings: SourceCode diff --git a/.github/workflows/Action-Test-outputs.yml b/.github/workflows/Action-Test-outputs.yml index 84749eca..b47e5116 100644 --- a/.github/workflows/Action-Test-outputs.yml +++ b/.github/workflows/Action-Test-outputs.yml @@ -1,6 +1,6 @@ -name: Action-Test [outputs] +name: Action-Test-outputs -run-name: "Action-Test [outputs] - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}" +run-name: 'Action-Test-outputs - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}' on: workflow_dispatch: @@ -15,36 +15,22 @@ concurrency: permissions: {} jobs: - ActionTest: + ActionTestOutputs: + name: Action-Test [outputs] - [${{ matrix.os }}] strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - name: Action-Test [outputs] - [${{ matrix.os }}] runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v4 - - name: Initialize environment - uses: PSModule/Initialize-PSModule@main - - name: Action-Test uses: ./ id: action-test - env: - GITHUB_TOKEN: ${{ github.token }} with: Name: PSModuleTest - Path: tests/outputs/modules - TestType: Module - - - name: Status - shell: pwsh - env: - PASSED: ${{ steps.action-test.outputs.passed }} - run: | - Write-Host "Passed: [$env:PASSED]" - if ($env:PASSED -ne 'true') { - exit 1 - } + WorkingDirectory: tests/outputTestRepo + Settings: Module + CodeCoverage_CoveragePercentTarget: 30 diff --git a/.github/workflows/Auto-Release.yml b/.github/workflows/Auto-Release.yml index ec157c9d..680da5c0 100644 --- a/.github/workflows/Auto-Release.yml +++ b/.github/workflows/Auto-Release.yml @@ -30,7 +30,5 @@ jobs: - name: Auto-Release uses: PSModule/Auto-Release@v1 - env: - GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication with: IncrementalPrerelease: false diff --git a/README.md b/README.md index 2461ad07..8a9f1ba5 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,34 @@ # Test-PSModule -Test PowerShell modules with Pester and PSScriptAnalyzer. +Tests PowerShell module repos using PSModule framework rules. -This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule). It is recommended to use the [Process-PSModule workflow](https://github.com/PSModule/Process-PSModule) to automate the whole process of managing the PowerShell module. +This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule). It is recommended to use the +[Process-PSModule workflow](https://github.com/PSModule/Process-PSModule) to automate the whole process of managing the PowerShell module. ## Specifications and practices Test-PSModule enables: -- [Test-Driven Development](https://testdriven.io/test-driven-development/) using [Pester](https://pester.dev) and [PSScriptAnalyzer](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules) +- [Test-Driven Development](https://testdriven.io/test-driven-development/) using [Pester](https://pester.dev) via [Invoke-Pester](https://github.com/PSModule/Invoke-Pester). ## How it works -The action runs the following the Pester test framework: -- [PSScriptAnalyzer tests](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/rules/readme?view=ps-modules) -- [PSModule framework tests](#psmodule-tests) -- If `TestType` is set to `Module`: - - The module manifest is tested using [Test-ModuleManifest](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/test-modulemanifest). - - The module is imported. - - Custom module tests from the `tests` directory in the module repository are run. - - CodeCoverage is calculated. -- If `TestType` is set to `SourceCode`: - - The source code is tested with: - - `PSScriptAnalyzer` for best practices, using custom settings. - - `PSModule.SourceCode` for other PSModule standards. -- The action returns a `passed` output that is `true` if all tests pass, else `false`. -- The following reports are calculated and uploaded as artifacts: - - Test suite results. - - Code coverage results. +- The action runs test on the module repository based on `Settings`: + - `SourceCode` - Tests source code style and standards based on PSModule framework rules. + - `Module` - Tests the module build module style and standards based on PSModule framework rules. + - The module is imported in its own context to avoid conflicts with other modules. +- The action returns the test results as action [outputs](#outputs). +- The following reports are calculated and uploaded as artifacts. This is done to support the action being run in matrix jobs. + - Test suite results. In [Process-PSModule](https://github.com/PSModule/Process-PSModule) this is evaluated in a later job by [Get-PesterTestResults](https://github.com/PSModule/Get-PesterTestResults) + - Code coverage results. In [Process-PSModule](https://github.com/PSModule/Process-PSModule) this is evaluated in a later job by [Get-PesterCodeCoverage](https://github.com/PSModule/Get-PesterCodeCoverage) The action fails if any of the tests fail or it fails to run the tests. This is mitigated by the `continue-on-error` option in the workflow. ## How to use it +It is recommended to use the [Process-PSModule workflow](https://github.com/PSModule/Process-PSModule) to automate the whole process of managing the PowerShell module. + To use the action, create a new file in the `.github/workflows` directory of the module repository and add the following content.
Workflow suggestion - before module is built @@ -57,8 +52,7 @@ jobs: - name: Test-PSModule uses: PSModule/Test-PSModule@main with: - Path: src - TestType: SourceCode + Settings: SourceCode ```
@@ -85,8 +79,7 @@ jobs: - name: Test-PSModule uses: PSModule/Test-PSModule@main with: - Path: outputs/modules - TestType: Module + Settings: Module ``` @@ -97,33 +90,98 @@ jobs: | Name | Description | Required | Default | | ---- | ----------- | -------- | ------- | -| `Path` | The path to the code to test. | `true` | | -| `TestType` | The type of tests to run. Can be either `Module` or `SourceCode`. | `true` | | | `Name` | The name of the module to test. The name of the repository is used if not specified. | `false` | | -| `TestsPath` | The path to the tests to run. | `false` | `tests` | -| `StackTraceVerbosity` | Verbosity level of the stack trace. Allowed values: `None`, `FirstLine`, `Filtered`, `Full`. | `false` | `Filtered` | -| `Verbosity` | Verbosity level of the test output. Allowed values: `None`, `Normal`, `Detailed`, `Diagnostic`. | `false` | `Detailed` | -| `Debug` | Enable debug output. | `'false'` | `false` | -| `Verbose` | Enable verbose output. | `'false'` | `false` | -| `Version` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | | `false` | -| `Prerelease` | Allow prerelease versions if available. | `'false'` | `false` | +| `Settings` | The type of tests to run. Can be either `Module` or `SourceCode`. | `true` | | +| `Debug` | Enable debug output. | `false` | `'false'` | +| `Verbose` | Enable verbose output. | `false` | `'false'` | +| `Version` | Specifies the version of the GitHub module to be installed. The value must be an exact version. | `false` | | +| `Prerelease` | Allow prerelease versions if available. | `false` | `'false'` | +| `WorkingDirectory` | The working directory to use for the action. This is the root folder where tests and outputs are expected. | `false` | `'.'` | +| `StepSummary_Mode` | Controls which tests to show in the GitHub step summary. Allows "Full" (all tests), "Failed" (only failed tests), or "None" (disable step summary). | `false` | `Failed` | +| `StepSummary_ShowTestOverview` | Controls whether to show the test overview table in the GitHub step summary. | `false` | `false` | +| `StepSummary_ShowConfiguration` | Controls whether to show the configuration details in the GitHub step summary. | `false` | `false` | +| `Run_ExcludePath` | Directories/files to exclude from the run. | `false` | | +| `Run_ScriptBlock` | ScriptBlocks containing tests to be executed. | `false` | | +| `Run_Container` | ContainerInfo objects containing tests to be executed. | `false` | | +| `Run_TestExtension` | Filter used to identify test files (e.g. `.Tests.ps1`). | `false` | | +| `Run_Exit` | Whether to exit with a non-zero exit code on failure. | `false` | | +| `Run_Throw` | Whether to throw an exception on test failure. | `false` | | +| `Run_SkipRun` | Discovery only, skip actual test run. | `false` | | +| `Run_SkipRemainingOnFailure` | Skips remaining tests after the first failure. Options: `None`, `Run`, `Container`, `Block`. | `false` | | +| `Filter_Tag` | Tags of Describe/Context/It blocks to run. | `false` | | +| `Filter_ExcludeTag` | Tags of Describe/Context/It blocks to exclude. | `false` | | +| `Filter_Line` | Filter by file + scriptblock start line (e.g. `C:\tests\file1.Tests.ps1:37`). | `false` | | +| `Filter_ExcludeLine` | Exclude by file + scriptblock start line. Precedence over `Filter_Line`. | `false` | | +| `Filter_FullName` | Full name of a test with wildcards, joined by dot. E.g. `*.describe Get-Item.test1` | `false` | | +| `CodeCoverage_Enabled` | Enable code coverage. | `false` | | +| `CodeCoverage_OutputFormat` | Format for the coverage report. Possible values: `JaCoCo`, `CoverageGutters`, `Cobertura`. | `false` | | +| `CodeCoverage_OutputPath` | Where to save the code coverage report (relative to the current dir). | `false` | | +| `CodeCoverage_OutputEncoding` | Encoding of the coverage file. | `false` | | +| `CodeCoverage_Path` | Files/directories to measure coverage on (by default, reuses `Path` from the general settings). | `false` | | +| `CodeCoverage_ExcludeTests` | Exclude tests themselves from coverage. | `false` | | +| `CodeCoverage_RecursePaths` | Recurse through coverage directories. | `false` | | +| `CodeCoverage_CoveragePercentTarget` | Desired minimum coverage percentage. | `false` | | +| `CodeCoverage_UseBreakpoints` | **Experimental**: When `false`, use a Profiler-based tracer instead of breakpoints. | `false` | | +| `CodeCoverage_SingleHitBreakpoints` | Remove breakpoints after first hit. | `false` | | +| `TestResult_Enabled` | Enable test-result output (e.g. NUnitXml, JUnitXml). | `false` | | +| `TestResult_OutputFormat` | Possible values: `NUnitXml`, `NUnit2.5`, `NUnit3`, `JUnitXml`. | `false` | | +| `TestResult_OutputPath` | Where to save the test-result report (relative path). | `false` | | +| `TestResult_OutputEncoding` | Encoding of the test-result file. | `false` | | +| `Should_ErrorAction` | Controls if `Should` throws on error. Use `Stop` to throw, or `Continue` to fail at the end. | `false` | | +| `Debug_ShowFullErrors` | Show Pester internal stack on errors. (Deprecated – overrides `Output.StackTraceVerbosity` to `Full`). | `false` | | +| `Debug_WriteDebugMessages` | Write debug messages to screen. | `false` | | +| `Debug_WriteDebugMessagesFrom` | Filter debug messages by source. Wildcards allowed. | `false` | | +| `Debug_ShowNavigationMarkers` | Write paths after every block/test for easy navigation in Visual Studio Code. | `false` | | +| `Debug_ReturnRawResultObject` | Returns an unfiltered result object, for development only. | `false` | | +| `Output_Verbosity` | Verbosity: `None`, `Normal`, `Detailed`, `Diagnostic`. | `false` | | +| `Output_StackTraceVerbosity` | Stacktrace detail: `None`, `FirstLine`, `Filtered`, `Full`. | `false` | | +| `Output_CIFormat` | CI format of error output: `None`, `Auto`, `AzureDevops`, `GithubActions`. | `false` | | +| `Output_CILogLevel` | CI log level: `Error` or `Warning`. | `false` | | +| `Output_RenderMode` | How to render console output: `Auto`, `Ansi`, `ConsoleColor`, `Plaintext`. | `false` | | +| `TestDrive_Enabled` | Enable `TestDrive`. | `false` | | +| `TestRegistry_Enabled` | Enable `TestRegistry`. | `false` | | ### Outputs -| Name | Description | Possible values | -| ---- | ----------- | --------------- | -| `passed` | If the tests passed. | `true`, `false` | +| Output | Description | +|-------------------------|--------------------------------------| +| `Outcome` | Outcome of the test run. | +| `Conclusion` | Conclusion status of test execution. | +| `Executed` | Indicates if tests were executed. | +| `Result` | Overall result (`Passed`, `Failed`). | +| `FailedCount` | Number of failed tests. | +| `FailedBlocksCount` | Number of failed blocks. | +| `FailedContainersCount` | Number of failed containers. | +| `PassedCount` | Number of passed tests. | +| `SkippedCount` | Number of skipped tests. | +| `InconclusiveCount` | Number of inconclusive tests. | +| `NotRunCount` | Number of tests not run. | +| `TotalCount` | Total tests executed. | ## PSModule tests -The [PSModule framework tests](https://github.com/PSModule/Test-PSModule/blob/main/scripts/tests/PSModule/PSModule.Tests.ps1) verifies the following coding practices that the framework enforces: +### SourceCode tests + +The [PSModule - SourceCode tests](./scripts/tests/SourceCode/PSModule/PSModule.Tests.ps1) verifies the following coding practices that the framework enforces: + +| ID | Category | Description | +|---------------------|---------------------|--------------------------------------------------------------------------------------------| +| NumberOfProcessors | General | Should use `[System.Environment]::ProcessorCount` instead of `$env:NUMBER_OF_PROCESSORS`. | +| Verbose | General | Should not contain `-Verbose` unless it is explicitly disabled with `:$false`. | +| OutNull | General | Should use `$null = ...` instead of piping output to `Out-Null`. | +| NoTernary | General | Should not use ternary operations to maintain compatibility with PowerShell 5.1 and below. | +| LowercaseKeywords | General | All PowerShell keywords should be written in lowercase. | +| FunctionCount | Functions (Generic) | Each script file should contain exactly one function or filter. | +| FunctionName | Functions (Generic) | Script filenames should match the name of the function or filter they contain. | +| CmdletBinding | Functions (Generic) | Functions should include the `[CmdletBinding()]` attribute. | +| ParamBlock | Functions (Generic) | Functions should have a parameter block (`param()`). | +| FunctionTest | Functions (Public) | All public functions/filters should have corresponding tests. | -- Script filename and function/filter name should match. +### Module tests -## Tools +The [PSModule - Module tests](./scripts/tests/Module/PSModule/PSModule.Tests.ps1) verifies the following coding practices that the framework enforces: -- Pester | [Docs](https://www.pester.dev) | [GitHub](https://github.com/Pester/Pester) | [PS Gallery](https://www.powershellgallery.com/packages/Pester/) -- PSScriptAnalyzer [Docs](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules) | [GitHub](https://github.com/PowerShell/PSScriptAnalyzer) | [PS Gallery](https://www.powershellgallery.com/packages/PSScriptAnalyzer/) -- PSResourceGet | [Docs](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.psresourceget/?view=powershellget-3.x) | [GitHub](https://github.com/PowerShell/PSResourceGet) | [PS Gallery](https://www.powershellgallery.com/packages/Microsoft.PowerShell.PSResourceGet/) -- [Test-ModuleManifest | Microsoft Learn](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/test-modulemanifest) -- [PowerShellGet | Microsoft Learn](https://learn.microsoft.com/en-us/powershell/module/PowerShellGet/test-scriptfileinfo) +| Name | Description | +| ------ | ----------- | +| Module Manifest exists | Verifies that a module manifest file is present. | +| Module Manifest is valid | Verifies that the module manifest file is valid. | diff --git a/action.yml b/action.yml index 03e4bdd5..74936e66 100644 --- a/action.yml +++ b/action.yml @@ -9,24 +9,193 @@ inputs: Name: description: The name of the module to test. The name of the repository is used if not specified. required: false - Path: - description: The path to the code to test. - required: true - TestType: + Settings: description: The type of tests to run. Can be either 'Module' or 'SourceCode'. required: true - TestsPath: - description: The path to the tests to run. + StepSummary_Mode: + description: | + Controls which tests to show in the GitHub step summary. Allows "Full" (show all tests), "Failed" (only failed tests), or "None" (disable step summary). + required: false + StepSummary_ShowTestOverview: + description: | + Controls whether to show the test overview table in the GitHub step summary. + required: false + StepSummary_ShowConfiguration: + description: | + Controls whether to show the configuration details in the GitHub step summary. + required: false + Run_Path: + description: | + Directories to be searched for tests, paths directly to test files, or combination of both. + required: false + Run_ExcludePath: + description: | + Directories or files to be excluded from the run. + required: false + Run_ScriptBlock: + description: | + ScriptBlocks containing tests to be executed. + required: false + Run_Container: + description: | + ContainerInfo objects containing tests to be executed. + required: false + Run_TestExtension: + description: | + Filter used to identify test files. + required: false + Run_Exit: + description: | + Exit with non-zero exit code when the test run fails. Exit code is always set to `$LASTEXITCODE` even when this option is `$false`. + When used together with Throw, throwing an exception is preferred. + required: false + Run_Throw: + description: | + Throw an exception when test run fails. When used together with Exit, throwing an exception is preferred. + required: false + Run_SkipRun: + description: | + Runs the discovery phase but skips run. Use it with PassThru to get object populated with all tests. + required: false + Run_SkipRemainingOnFailure: + description: | + Skips remaining tests after failure for selected scope, options are None, Run, Container and Block. + required: false + Filter_Tag: + description: | + Tags of Describe, Context or It to be run. + required: false + Filter_ExcludeTag: + description: | + Tags of Describe, Context or It to be excluded from the run. + required: false + Filter_Line: + description: | + Filter by file and scriptblock start line, useful to run parsed tests programmatically to avoid problems with expanded names. + Example: 'C:\tests\file1.Tests.ps1:37' + required: false + Filter_ExcludeLine: + description: | + Exclude by file and scriptblock start line, takes precedence over Line. + required: false + Filter_FullName: + description: | + Full name of test with -like wildcards, joined by dot. Example: '*.describe Get-Item.test1' + required: false + CodeCoverage_Enabled: + description: | + Enable CodeCoverage. + required: false + CodeCoverage_OutputFormat: + description: | + Format to use for code coverage report. Possible values: JaCoCo, CoverageGutters, Cobertura + required: false + CodeCoverage_OutputPath: + description: | + Path relative to the current directory where code coverage report is saved. + required: false + CodeCoverage_OutputEncoding: + description: | + Encoding of the output file. + required: false + CodeCoverage_Path: + description: | + Directories or files to be used for code coverage, by default the Path(s) from general settings are used, unless overridden here. + required: false + CodeCoverage_ExcludeTests: + description: | + Exclude tests from code coverage. This uses the TestFilter from general configuration. + required: false + CodeCoverage_RecursePaths: + description: | + Will recurse through directories in the Path option. + required: false + CodeCoverage_CoveragePercentTarget: + description: | + Target percent of code coverage that you want to achieve. + required: false + CodeCoverage_UseBreakpoints: + description: | + EXPERIMENTAL: When false, use Profiler based tracer to do CodeCoverage instead of using breakpoints. required: false - default: tests - StackTraceVerbosity: - description: "Verbosity level of the stack trace. Allowed values: 'None', 'FirstLine', 'Filtered', 'Full'." + CodeCoverage_SingleHitBreakpoints: + description: | + Remove breakpoint when it is hit. required: false - default: 'Filtered' - Verbosity: - description: "Verbosity level of the test output. Allowed values: 'None', 'Normal', 'Detailed', 'Diagnostic'." + TestResult_Enabled: + description: | + Enable TestResult. + required: false + TestResult_OutputFormat: + description: | + Format to use for test result report. Possible values: NUnitXml, NUnit2.5, NUnit3 or JUnitXml + required: false + TestResult_OutputPath: + description: | + Path relative to the current directory where test result report is saved. + required: false + TestResult_OutputEncoding: + description: | + Encoding of the output file. + required: false + TestResult_TestSuiteName: + description: | + Set the name assigned to the root 'test-suite' element. + required: false + Should_ErrorAction: + description: | + Controls if Should throws on error. Use 'Stop' to throw on error, or 'Continue' to fail at the end of the test. + required: false + Debug_ShowFullErrors: + description: | + Show full errors including Pester internal stack. This property is deprecated, and if set to true it will override Output.StackTraceVerbosity to 'Full'. + required: false + Debug_WriteDebugMessages: + description: | + Write Debug messages to screen. + required: false + Debug_WriteDebugMessagesFrom: + description: | + Write Debug messages from a given source, WriteDebugMessages must be set to true for this to work. + You can use like wildcards to get messages from multiple sources, as well as * to get everything. + required: false + Debug_ShowNavigationMarkers: + description: | + Write paths after every block and test, for easy navigation in VSCode. + required: false + Debug_ReturnRawResultObject: + description: | + Returns unfiltered result object, this is for development only. Do not rely on this object for additional properties, + non-public properties will be renamed without previous notice. + required: false + Output_Verbosity: + description: | + The verbosity of output, options are None, Normal, Detailed and Diagnostic. + required: false + Output_StackTraceVerbosity: + description: | + The verbosity of stacktrace output, options are None, FirstLine, Filtered and Full. + required: false + Output_CIFormat: + description: | + The CI format of error output in build logs, options are None, Auto, AzureDevops and GithubActions. + required: false + Output_CILogLevel: + description: | + The CI log level in build logs, options are Error and Warning. + required: false + Output_RenderMode: + description: | + The mode used to render console output, options are Auto, Ansi, ConsoleColor and Plaintext. + required: false + TestDrive_Enabled: + description: | + Enable TestDrive. + required: false + TestRegistry_Enabled: + description: | + Enable TestRegistry. required: false - default: 'Detailed' Debug: description: Enable debug output. required: false @@ -42,45 +211,133 @@ inputs: description: Allow prerelease versions if available. required: false default: 'false' + WorkingDirectory: + description: The working directory to use for the action. This is the root folder where tests and outputs are expected. + required: false + default: '.' outputs: - passed: - description: If the tests passed. - value: ${{ fromJSON(steps.test.outputs.result).passed }} + Outcome: + description: | + The outcome of the test run. + value: ${{ steps.test.outcome }} + Conclusion: + description: | + The conclusion of the test run. + value: ${{ steps.test.conclusion }} + Executed: + description: | + Whether tests were executed. + value: ${{ steps.test.outputs.Executed }} + Result: + description: | + Overall result of the Pester test run (e.g., Passed, Failed). + value: ${{ steps.test.outputs.Result }} + FailedCount: + description: | + Number of failed tests. + value: ${{ steps.test.outputs.FailedCount }} + FailedBlocksCount: + description: | + Number of failed blocks. + value: ${{ steps.test.outputs.FailedBlocksCount }} + FailedContainersCount: + description: | + Number of failed containers. + value: ${{ steps.test.outputs.FailedContainersCount }} + PassedCount: + description: | + Number of passed tests. + value: ${{ steps.test.outputs.PassedCount }} + SkippedCount: + description: | + Number of skipped tests. + value: ${{ steps.test.outputs.SkippedCount }} + InconclusiveCount: + description: | + Number of inconclusive tests. + value: ${{ steps.test.outputs.InconclusiveCount }} + NotRunCount: + description: | + Number of tests not run. + value: ${{ steps.test.outputs.NotRunCount }} + TotalCount: + description: | + Total count of tests. + value: ${{ steps.test.outputs.TotalCount }} runs: using: composite steps: - - name: Run Test-PSModule - uses: PSModule/GitHub-Script@v1 + - name: Install-PSModuleHelpers + uses: PSModule/Install-PSModuleHelpers@v1 + + - name: Get test paths + shell: pwsh + id: paths + working-directory: ${{ inputs.WorkingDirectory }} + env: + PSMODULE_TEST_PSMODULE_INPUT_Name: ${{ inputs.Name }} + PSMODULE_TEST_PSMODULE_INPUT_Settings: ${{ inputs.Settings }} + run: | + # Get test paths + ${{ github.action_path }}/scripts/main.ps1 + + - name: Invoke-Pester + uses: PSModule/Invoke-Pester@v4 id: test env: - GITHUB_ACTION_INPUT_Name: ${{ inputs.Name }} - GITHUB_ACTION_INPUT_Path: ${{ inputs.Path }} - GITHUB_ACTION_INPUT_TestType: ${{ inputs.TestType }} - GITHUB_ACTION_INPUT_TestsPath: ${{ inputs.TestsPath }} - GITHUB_ACTION_INPUT_StackTraceVerbosity: ${{ inputs.StackTraceVerbosity }} - GITHUB_ACTION_INPUT_Verbosity: ${{ inputs.Verbosity }} + LocalTestPath: ${{ steps.paths.outputs.LocalTestPath }} + WorkingDirectory: ${{ inputs.WorkingDirectory }} with: Debug: ${{ inputs.Debug }} Prerelease: ${{ inputs.Prerelease }} Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} - ShowOutput: true - Script: | - # Test-PSModule - ${{ github.action_path }}/scripts/main.ps1 - - - name: Upload test results - uses: actions/upload-artifact@v4 - if: ${{ inputs.TestType == 'Module' && (success() || failure()) }} - with: - name: ${{ runner.os }}-Test-Report - path: ${{ github.workspace }}/outputs/Test-Report.xml - - - name: Upload code coverage report - uses: actions/upload-artifact@v4 - if: ${{ inputs.TestType == 'Module' && (success() || failure()) }} - with: - name: ${{ runner.os }}-CodeCoverage-Report - path: ${{ github.workspace }}/outputs/CodeCoverage-Report.xml + WorkingDirectory: ${{ inputs.WorkingDirectory }} + Path: ${{ steps.paths.outputs.TestPath }} + StepSummary_Mode: ${{ inputs.StepSummary_Mode }} + StepSummary_ShowTestOverview: ${{ inputs.StepSummary_ShowTestOverview }} + StepSummary_ShowConfiguration: ${{ inputs.StepSummary_ShowConfiguration }} + Run_Path: ${{ steps.paths.outputs.CodePath }} + Run_ExcludePath: ${{ inputs.Run_ExcludePath }} + Run_ScriptBlock: ${{ inputs.Run_ScriptBlock }} + Run_Container: ${{ inputs.Run_Container }} + Run_TestExtension: ${{ inputs.Run_TestExtension }} + Run_Exit: ${{ inputs.Run_Exit }} + Run_Throw: ${{ inputs.Run_Throw }} + Run_SkipRun: ${{ inputs.Run_SkipRun }} + Run_SkipRemainingOnFailure: ${{ inputs.Run_SkipRemainingOnFailure }} + Filter_Tag: ${{ inputs.Filter_Tag }} + Filter_ExcludeTag: ${{ inputs.Filter_ExcludeTag }} + Filter_Line: ${{ inputs.Filter_Line }} + Filter_ExcludeLine: ${{ inputs.Filter_ExcludeLine }} + Filter_FullName: ${{ inputs.Filter_FullName }} + CodeCoverage_Enabled: ${{ inputs.CodeCoverage_Enabled }} + CodeCoverage_OutputFormat: ${{ inputs.CodeCoverage_OutputFormat }} + CodeCoverage_OutputPath: ${{ inputs.CodeCoverage_OutputPath }} + CodeCoverage_OutputEncoding: ${{ inputs.CodeCoverage_OutputEncoding }} + CodeCoverage_Path: ${{ inputs.CodeCoverage_Path }} + CodeCoverage_ExcludeTests: ${{ inputs.CodeCoverage_ExcludeTests }} + CodeCoverage_RecursePaths: ${{ inputs.CodeCoverage_RecursePaths }} + CodeCoverage_CoveragePercentTarget: ${{ inputs.CodeCoverage_CoveragePercentTarget }} + CodeCoverage_UseBreakpoints: ${{ inputs.CodeCoverage_UseBreakpoints }} + CodeCoverage_SingleHitBreakpoints: ${{ inputs.CodeCoverage_SingleHitBreakpoints }} + TestResult_Enabled: ${{ inputs.TestResult_Enabled }} + TestResult_OutputFormat: ${{ inputs.TestResult_OutputFormat }} + TestResult_OutputPath: ${{ inputs.TestResult_OutputPath }} + TestResult_OutputEncoding: ${{ inputs.TestResult_OutputEncoding }} + TestResult_TestSuiteName: PSModuleTest-${{ inputs.Settings }}-${{ runner.os }} + Should_ErrorAction: ${{ inputs.Should_ErrorAction }} + Debug_ShowFullErrors: ${{ inputs.Debug_ShowFullErrors }} + Debug_WriteDebugMessages: ${{ inputs.Debug_WriteDebugMessages }} + Debug_WriteDebugMessagesFrom: ${{ inputs.Debug_WriteDebugMessagesFrom }} + Debug_ShowNavigationMarkers: ${{ inputs.Debug_ShowNavigationMarkers }} + Debug_ReturnRawResultObject: ${{ inputs.Debug_ReturnRawResultObject }} + Output_Verbosity: ${{ inputs.Output_Verbosity }} + Output_StackTraceVerbosity: ${{ inputs.Output_StackTraceVerbosity }} + Output_CIFormat: ${{ inputs.Output_CIFormat }} + Output_CILogLevel: ${{ inputs.Output_CILogLevel }} + Output_RenderMode: ${{ inputs.Output_RenderMode }} + TestDrive_Enabled: ${{ inputs.TestDrive_Enabled }} + TestRegistry_Enabled: ${{ inputs.TestRegistry_Enabled }} diff --git a/scripts/helpers/Resolve-PSModuleDependency.ps1 b/scripts/helpers/Resolve-PSModuleDependency.ps1 deleted file mode 100644 index 3e0cea8e..00000000 --- a/scripts/helpers/Resolve-PSModuleDependency.ps1 +++ /dev/null @@ -1,68 +0,0 @@ - -function Resolve-PSModuleDependency { - <# - .SYNOPSIS - Resolve dependencies for a module based on the manifest file. - - .DESCRIPTION - Resolve dependencies for a module based on the manifest file, following PSModuleInfo structure - - .EXAMPLE - Resolve-PSModuleDependency -Path 'C:\MyModule\MyModule.psd1' - - Installs all modules defined in the manifest file, following PSModuleInfo structure. - - .NOTES - Should later be adapted to support both pre-reqs, and dependencies. - Should later be adapted to take 4 parameters sets: specific version ("requiredVersion" | "GUID"), latest version ModuleVersion, - and latest version within a range MinimumVersion - MaximumVersion. - #> - [Alias('Resolve-PSModuleDependencies')] - #Requires -Modules Retry - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidUsingWriteHost', '', Scope = 'Function', - Justification = 'Want to just write to the console, not the pipeline.' - )] - [CmdletBinding()] - param( - # The path to the manifest file. - [Parameter(Mandatory)] - [string] $ManifestFilePath - ) - - Write-Host 'Resolving dependencies' - - $manifest = Import-PowerShellDataFile -Path $ManifestFilePath - Write-Host "Reading [$ManifestFilePath]" - Write-Host "Found [$($manifest.RequiredModules.Count)] modules to install" - - foreach ($requiredModule in $manifest.RequiredModules) { - $installParams = @{} - - if ($requiredModule -is [string]) { - $installParams.Name = $requiredModule - } else { - $installParams.Name = $requiredModule.ModuleName - $installParams.MinimumVersion = $requiredModule.ModuleVersion - $installParams.RequiredVersion = $requiredModule.RequiredVersion - $installParams.MaximumVersion = $requiredModule.MaximumVersion - } - $installParams.Force = $true - $installParams.Verbose = $false - - Write-Host "[$($installParams.Name)] - Installing module" - $VerbosePreferenceOriginal = $VerbosePreference - $VerbosePreference = 'SilentlyContinue' - Retry -Count 5 -Delay 10 { - Install-Module @installParams -AllowPrerelease:$false - } - $VerbosePreference = $VerbosePreferenceOriginal - Write-Host "[$($installParams.Name)] - Importing module" - $VerbosePreferenceOriginal = $VerbosePreference - $VerbosePreference = 'SilentlyContinue' - Import-Module @installParams - $VerbosePreference = $VerbosePreferenceOriginal - Write-Host "[$($installParams.Name)] - Done" - } - Write-Host 'Resolving dependencies - Done' -} diff --git a/scripts/helpers/Test-PSModule.ps1 b/scripts/helpers/Test-PSModule.ps1 deleted file mode 100644 index bed29ef6..00000000 --- a/scripts/helpers/Test-PSModule.ps1 +++ /dev/null @@ -1,181 +0,0 @@ -function Test-PSModule { - <# - .SYNOPSIS - Performs tests on a module. - #> - [OutputType([int])] - [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', '', Scope = 'Function', - Justification = 'Parameters are used in nested ScriptBlocks' - )] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidUsingWriteHost', '', Scope = 'Function', - Justification = 'Want to just write to the console, not the pipeline.' - )] - param( - # Path to the folder where the code to test is located. - [Parameter(Mandatory)] - [string] $Path, - - # Run module tests. - [Parameter()] - [ValidateSet('SourceCode', 'Module')] - [string] $TestType = 'SourceCode', - - # Path to the folder where the tests are located. - [Parameter()] - [string] $TestsPath = 'tests', - - # Verbosity level of the stack trace. - [Parameter()] - [ValidateSet('None', 'FirstLine', 'Filtered', 'Full')] - [string] $StackTraceVerbosity = 'Filtered', - - # Verbosity level of the test output. - [Parameter()] - [ValidateSet('None', 'Normal', 'Detailed', 'Diagnostic')] - [string] $Verbosity = 'Detailed' - ) - - $moduleName = Split-Path -Path $Path -Leaf - $testSourceCode = $TestType -eq 'SourceCode' - $testModule = $TestType -eq 'Module' - $moduleTestsPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath $TestsPath - - LogGroup 'Get test kit versions' { - $PSSAModule = Get-PSResource -Name PSScriptAnalyzer -Verbose:$false | Sort-Object Version -Descending | Select-Object -First 1 - $pesterModule = Get-PSResource -Name Pester -Verbose:$false | Sort-Object Version -Descending | Select-Object -First 1 - - [PSCustomObject]@{ - PowerShell = $PSVersionTable.PSVersion.ToString() - Pester = $pesterModule.version - PSScriptAnalyzer = $PSSAModule.version - } | Format-List - } - - LogGroup 'Add test - Common - PSScriptAnalyzer' { - $containers = @() - $PSSATestsPath = Join-Path -Path $PSScriptRoot -ChildPath '..\tests\PSScriptAnalyzer' - $settingsFileName = if ($testModule) { 'Settings.Module.psd1' } else { 'Settings.SourceCode.psd1' } - $settingsFilePath = Join-Path -Path $PSSATestsPath -ChildPath $settingsFileName - $containerParams = @{ - Path = Join-Path $PSSATestsPath 'PSScriptAnalyzer.Tests.ps1' - Data = @{ - Path = $Path - SettingsFilePath = $settingsFilePath - Debug = $false - Verbose = $false - } - } - Write-Host ($containerParams | ConvertTo-Json) - $containers += New-PesterContainer @containerParams - } - - LogGroup 'Add test - Common - PSModule' { - $containerParams = @{ - Path = Join-Path -Path $PSScriptRoot -ChildPath '..\tests\PSModule\Common.Tests.ps1' - Data = @{ - Path = $Path - Debug = $false - Verbose = $false - } - } - Write-Host ($containerParams | ConvertTo-Json) - $containers += New-PesterContainer @containerParams - } - - if ($testModule) { - LogGroup 'Add test - Module - PSModule' { - $containerParams = @{ - Path = Join-Path -Path $PSScriptRoot -ChildPath '..\tests\PSModule\Module.Tests.ps1' - Data = @{ - Path = $Path - Debug = $false - Verbose = $false - } - } - Write-Host ($containerParams | ConvertTo-Json) - $containers += New-PesterContainer @containerParams - } - } - - if ($testSourceCode) { - LogGroup 'Add test - SourceCode - PSModule' { - $containerParams = @{ - Path = Join-Path -Path $PSScriptRoot -ChildPath '..\tests\PSModule\SourceCode.Tests.ps1' - Data = @{ - Path = $Path - TestsPath = $moduleTestsPath - Debug = $false - Verbose = $false - } - } - Write-Host ($containerParams | ConvertTo-Json) - $containers += New-PesterContainer @containerParams - } - } - - if ($testModule) { - if (Test-Path -Path $moduleTestsPath) { - LogGroup "Add test - Module - $moduleName" { - $containerParams = @{ - Path = $moduleTestsPath - } - Write-Host ($containerParams | ConvertTo-Json) - $containers += New-PesterContainer @containerParams - } - } else { - Write-GitHubWarning "⚠️ No tests found - [$moduleTestsPath]" - } - } - - if ((Test-Path -Path $moduleTestsPath) -and $testModule) { - LogGroup 'Install module dependencies' { - $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - Resolve-PSModuleDependency -ManifestFilePath $moduleManifestPath - } - - LogGroup "Importing module: $moduleName" { - Add-PSModulePath -Path (Split-Path $Path -Parent) - $existingModule = Get-Module -Name $ModuleName -ListAvailable - $existingModule | Remove-Module -Force - $existingModule.RequiredModules | ForEach-Object { $_ | Remove-Module -Force -ErrorAction SilentlyContinue } - $existingModule.NestedModules | ForEach-Object { $_ | Remove-Module -Force -ErrorAction SilentlyContinue } - Import-Module -Name $moduleName -Force -RequiredVersion '999.0.0' -Global - } - } - - LogGroup 'Pester config' { - $pesterParams = @{ - Configuration = @{ - Run = @{ - Path = $Path - Container = $containers - PassThru = $true - } - TestResult = @{ - Enabled = $testModule - OutputFormat = 'NUnitXml' - OutputPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath 'outputs\Test-Report.xml' - TestSuiteName = 'Unit tests' - } - CodeCoverage = @{ - Enabled = $testModule - OutputPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath 'outputs\CodeCoverage-Report.xml' - OutputFormat = 'JaCoCo' - OutputEncoding = 'UTF8' - CoveragePercentTarget = 75 - } - Output = @{ - CIFormat = 'Auto' - StackTraceVerbosity = $StackTraceVerbosity - Verbosity = $Verbosity - } - } - } - Write-Host ($pesterParams | ConvertTo-Json -Depth 5 -WarningAction SilentlyContinue) - } - - Invoke-Pester @pesterParams -} diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 575a4ef4..1706791f 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -1,66 +1,38 @@ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidUsingWriteHost', '', - Justification = 'Want to just write to the console, not the pipeline.' -)] -[CmdletBinding()] +[CmdletBinding()] param() -$path = (Join-Path -Path $PSScriptRoot -ChildPath 'helpers') -LogGroup "Loading helper scripts from [$path]" { - Get-ChildItem -Path $path -Filter '*.ps1' -Recurse | ForEach-Object { - Write-Host " - $($_.FullName)" - . $_.FullName - } +$env:GITHUB_REPOSITORY_NAME = $env:GITHUB_REPOSITORY -replace '.+/' +$moduleName = if ([string]::IsNullOrEmpty($env:PSMODULE_TEST_PSMODULE_INPUT_Name)) { + $env:GITHUB_REPOSITORY_NAME +} else { + $env:PSMODULE_TEST_PSMODULE_INPUT_Name } - -LogGroup 'Loading inputs' { - $moduleName = ($env:GITHUB_ACTION_INPUT_Name | IsNullOrEmpty) ? $env:GITHUB_REPOSITORY_NAME : $env:GITHUB_ACTION_INPUT_Name - $codeToTest = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "$env:GITHUB_ACTION_INPUT_Path\$moduleName" - if (-not (Test-Path -Path $codeToTest)) { - $codeToTest = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath $env:GITHUB_ACTION_INPUT_Path +$settings = $env:PSMODULE_TEST_PSMODULE_INPUT_Settings +$testPath = Resolve-Path -Path "$PSScriptRoot/tests/$settings" | Select-Object -ExpandProperty Path + +$localTestPath = Resolve-Path -Path 'tests' | Select-Object -ExpandProperty Path +switch ($settings) { + 'Module' { + $modulePath = Resolve-Path -Path "outputs/module/$moduleName" | Select-Object -ExpandProperty Path + $codePath = Install-PSModule -Path $modulePath -PassThru } - if (-not (Test-Path -Path $codeToTest)) { - throw "Path [$codeToTest] does not exist." + 'SourceCode' { + $codePath = Resolve-Path -Path 'src' | Select-Object -ExpandProperty Path } - - if (-not (Test-Path -Path $env:GITHUB_ACTION_INPUT_TestsPath)) { - throw "Path [$env:GITHUB_ACTION_INPUT_TestsPath] does not exist." + default { + throw "Invalid test type: [$settings]" } - - [pscustomobject]@{ - ModuleName = $moduleName - CodeToTest = $codeToTest - TestType = $env:GITHUB_ACTION_INPUT_TestType - TestsPath = $env:GITHUB_ACTION_INPUT_TestsPath - StackTraceVerbosity = $env:GITHUB_ACTION_INPUT_StackTraceVerbosity - Verbosity = $env:GITHUB_ACTION_INPUT_Verbosity - } | Format-List -} - -$params = @{ - Path = $codeToTest - TestType = $env:GITHUB_ACTION_INPUT_TestType - TestsPath = $env:GITHUB_ACTION_INPUT_TestsPath - StackTraceVerbosity = $env:GITHUB_ACTION_INPUT_StackTraceVerbosity - Verbosity = $env:GITHUB_ACTION_INPUT_Verbosity -} -$testResults = Test-PSModule @params - -LogGroup 'Test results' { - $testResults | Format-List -} - -$failedTests = [int]$testResults.FailedCount - -if (($failedTests -gt 0) -or ($testResults.Result -ne 'Passed')) { - Write-GitHubError "❌ Some [$failedTests] tests failed." - Set-GitHubOutput -Name 'passed' -Value $false - $return = 1 -} elseif ($failedTests -eq 0) { - Write-GitHubNotice '✅ All tests passed.' - Set-GitHubOutput -Name 'passed' -Value $true - $return = 0 } -Write-Host '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━' -exit $return +[pscustomobject]@{ + ModuleName = $moduleName + Settings = $settings + CodePath = $codePath + LocalTestPath = $localTestPath + TestPath = $testPath +} | Format-List | Out-String + +"ModuleName=$moduleName" >> $env:GITHUB_OUTPUT +"CodePath=$codePath" >> $env:GITHUB_OUTPUT +"LocalTestPath=$localTestPath" >> $env:GITHUB_OUTPUT +"TestPath=$testPath" >> $env:GITHUB_OUTPUT diff --git a/scripts/tests/Module/Module.Configuration.ps1 b/scripts/tests/Module/Module.Configuration.ps1 new file mode 100644 index 00000000..e76f767f --- /dev/null +++ b/scripts/tests/Module/Module.Configuration.ps1 @@ -0,0 +1,8 @@ +@{ + TestResult = @{ + Enabled = $true + } + Output = @{ + Verbosity = 'Detailed' + } +} diff --git a/scripts/tests/Module/PSModule/PSModule.Container.ps1 b/scripts/tests/Module/PSModule/PSModule.Container.ps1 new file mode 100644 index 00000000..31d42d3c --- /dev/null +++ b/scripts/tests/Module/PSModule/PSModule.Container.ps1 @@ -0,0 +1,8 @@ +@{ + Path = Get-ChildItem -Path $PSScriptRoot -Filter *.Tests.ps1 | Select-Object -ExpandProperty FullName + Data = @{ + Path = $env:PSMODULE_INVOKE_PESTER_INPUT_Run_Path + Debug = $false + Verbose = $false + } +} diff --git a/scripts/tests/PSModule/Module.Tests.ps1 b/scripts/tests/Module/PSModule/PSModule.Tests.ps1 similarity index 54% rename from scripts/tests/PSModule/Module.Tests.ps1 rename to scripts/tests/Module/PSModule/PSModule.Tests.ps1 index 772f2a5b..1253ce7f 100644 --- a/scripts/tests/PSModule/Module.Tests.ps1 +++ b/scripts/tests/Module/PSModule/PSModule.Tests.ps1 @@ -9,29 +9,19 @@ Param( ) BeforeAll { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', 'moduleName', - Justification = 'moduleName is used in the test.' - )] - $moduleName = Split-Path -Path $Path -Leaf + $moduleName = Split-Path -Path (Split-Path -Path $Path -Parent) -Leaf + $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" + Write-Verbose "Module Manifest Path: [$moduleManifestPath]" } Describe 'PSModule - Module tests' { Context 'Module' { - It 'The module should be available' { - Get-Module -Name $moduleName -ListAvailable | Should -Not -BeNullOrEmpty - Write-Verbose (Get-Module -Name $moduleName -ListAvailable | Out-String) - } It 'The module should be importable' { - { Import-Module -Name $moduleName -RequiredVersion 999.0.0 -Force } | Should -Not -Throw + { Import-Module -Name $moduleName } | Should -Not -Throw } } - Context "Module Manifest" { - BeforeAll { - $moduleManifestPath = Join-Path -Path $Path -ChildPath "$moduleName.psd1" - Write-Verbose "Module Manifest Path: [$moduleManifestPath]" - } + Context 'Module Manifest' { It 'Module Manifest exists' { $result = Test-Path -Path $moduleManifestPath $result | Should -Be $true diff --git a/scripts/tests/PSModule/Common.Tests.ps1 b/scripts/tests/PSModule/Common.Tests.ps1 deleted file mode 100644 index 843e8b17..00000000 --- a/scripts/tests/PSModule/Common.Tests.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'Path', - Justification = 'Path is used to specify the path to the module to test.' -)] -[CmdLetBinding()] -Param( - [Parameter(Mandatory)] - [string] $Path -) - -# These tests are for the whole module and its parts. The scope of these tests are on the src folder and the specific module folder within it. -Describe 'Script files' { - Context 'Module design tests' { - # It 'Script file should only contain one function or filter' {} - # It 'All script files have tests' {} # Look for the folder name in tests called the same as section/folder name of functions - } - - Describe 'Function/filter design' { - # It 'comment based doc block start is indented with 4 spaces' {} - # It 'comment based doc is indented with 8 spaces' {} - # It 'has synopsis for all functions' {} - # It 'has description for all functions' {} - # It 'has examples for all functions' {} - # It 'has output documentation for all functions' {} - # It 'has [CmdletBinding()] attribute' {} - # It 'boolean parameters in CmdletBinding() attribute are written without assignments' {} - # I.e. [CmdletBinding(ShouldProcess)] instead of [CmdletBinding(ShouldProcess = $true)] - # It 'has [OutputType()] attribute' {} - # It 'has verb 'New','Set','Disable','Enable' etc. and uses "ShoudProcess" in the [CmdletBinding()] attribute' {} - } - - Describe 'Parameter design' { - # It 'has parameter description for all functions' {} - # It 'has parameter validation for all functions' {} - # It 'parameters have [Parameters()] attribute' {} - # It 'boolean parameters to the [Parameter()] attribute are written without assignments' {} - # I.e. [Parameter(Mandatory)] instead of [Parameter(Mandatory = $true)] - # It 'datatype for parameters are written on the same line as the parameter name' {} - # It 'datatype for parameters and parameter name are separated by a single space' {} - # It 'parameters are separated by a blank line' {} - } -} diff --git a/scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1 b/scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1 deleted file mode 100644 index 2a6039b8..00000000 --- a/scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'Path', - Justification = 'Path is being used.' -)] -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'SettingsFilePath', - Justification = 'SettingsFilePath is being used.' -)] -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', 'relativeSettingsFilePath', - Justification = 'relativeSettingsFilePath is being used.' -)] -[CmdLetBinding()] -Param( - [Parameter(Mandatory)] - [string] $Path, - - [Parameter(Mandatory)] - [string] $SettingsFilePath -) - -BeforeDiscovery { - $rules = [Collections.Generic.List[System.Collections.Specialized.OrderedDictionary]]::new() - $ruleObjects = Get-ScriptAnalyzerRule -Verbose:$false | Sort-Object -Property Severity, CommonName - foreach ($ruleObject in $ruleObjects) { - $rules.Add( - [ordered]@{ - RuleName = $ruleObject.RuleName - CommonName = $ruleObject.CommonName - Severity = $ruleObject.Severity - Description = $ruleObject.Description - } - ) - } - Write-Warning "Discovered [$($rules.Count)] rules" - $relativeSettingsFilePath = $SettingsFilePath.Replace($PSScriptRoot, '').Trim('\').Trim('/') -} - -Describe "PSScriptAnalyzer tests using settings file [$relativeSettingsFilePath]" { - BeforeAll { - $testResults = Invoke-ScriptAnalyzer -Path $Path -Settings $SettingsFilePath -Recurse -Verbose:$false - Write-Warning "Found [$($testResults.Count)] issues" - } - - Context 'Severity: <_>' -ForEach 'Error', 'Warning', 'Information' { - It ' ()' -ForEach ($rules | Where-Object -Property Severity -EQ $_) { - $issues = [Collections.Generic.List[string]]::new() - $testResults | Where-Object -Property RuleName -EQ $RuleName | ForEach-Object { - $relativePath = $_.ScriptPath.Replace($Path, '').Trim('\').Trim('/') - $issues.Add(([Environment]::NewLine + " - $relativePath`:L$($_.Line):C$($_.Column)")) - } - $issues -join '' | Should -BeNullOrEmpty -Because $Description - } - } -} diff --git a/scripts/tests/PSScriptAnalyzer/Settings.Module.psd1 b/scripts/tests/PSScriptAnalyzer/Settings.Module.psd1 deleted file mode 100644 index 7c3a739c..00000000 --- a/scripts/tests/PSScriptAnalyzer/Settings.Module.psd1 +++ /dev/null @@ -1,47 +0,0 @@ -@{ - Rules = @{ - PSAlignAssignmentStatement = @{ - Enable = $true - CheckHashtable = $true - } - PSAvoidLongLines = @{ - Enable = $true - MaximumLineLength = 150 - } - PSAvoidSemicolonsAsLineTerminators = @{ - Enable = $true - } - PSPlaceCloseBrace = @{ - Enable = $true - NewLineAfter = $false - IgnoreOneLineBlock = $true - NoEmptyLineBefore = $false - } - PSPlaceOpenBrace = @{ - Enable = $true - OnSameLine = $true - NewLineAfter = $true - IgnoreOneLineBlock = $true - } - PSProvideCommentHelp = @{ - Enable = $true - ExportedOnly = $false - BlockComment = $true - VSCodeSnippetCorrection = $false - Placement = 'begin' - } - PSUseConsistentIndentation = @{ - Enable = $true - IndentationSize = 4 - PipelineIndentation = 'IncreaseIndentationForFirstPipeline' - Kind = 'space' - } - PSUseConsistentWhitespace = @{ - Enable = $false - } - } - ExcludeRules = @( - 'PSAvoidUsingCmdletAliases', - 'PSUseToExportFieldsInManifest' - ) -} diff --git a/scripts/tests/PSScriptAnalyzer/Settings.SourceCode.psd1 b/scripts/tests/PSScriptAnalyzer/Settings.SourceCode.psd1 deleted file mode 100644 index e9081f9a..00000000 --- a/scripts/tests/PSScriptAnalyzer/Settings.SourceCode.psd1 +++ /dev/null @@ -1,57 +0,0 @@ -@{ - Rules = @{ - PSAlignAssignmentStatement = @{ - Enable = $true - CheckHashtable = $true - } - PSAvoidLongLines = @{ - Enable = $true - MaximumLineLength = 150 - } - PSAvoidSemicolonsAsLineTerminators = @{ - Enable = $true - } - PSPlaceCloseBrace = @{ - Enable = $true - NewLineAfter = $false - IgnoreOneLineBlock = $true - NoEmptyLineBefore = $false - } - PSPlaceOpenBrace = @{ - Enable = $true - OnSameLine = $true - NewLineAfter = $true - IgnoreOneLineBlock = $true - } - PSProvideCommentHelp = @{ - Enable = $true - ExportedOnly = $false - BlockComment = $true - VSCodeSnippetCorrection = $false - Placement = 'begin' - } - PSUseConsistentIndentation = @{ - Enable = $true - IndentationSize = 4 - PipelineIndentation = 'IncreaseIndentationForFirstPipeline' - Kind = 'space' - } - PSUseConsistentWhitespace = @{ - Enable = $true - CheckInnerBrace = $true - CheckOpenBrace = $true - CheckOpenParen = $true - CheckOperator = $true - CheckPipe = $true - CheckPipeForRedundantWhitespace = $true - CheckSeparator = $true - CheckParameter = $true - IgnoreAssignmentOperatorInsideHashTable = $true - } - } - ExcludeRules = @( - 'PSMissingModuleManifestField', # This rule is not applicable until the module is built. - 'PSAvoidUsingCmdletAliases', - 'PSUseToExportFieldsInManifest' - ) -} diff --git a/scripts/tests/SourceCode/PSModule/PSModule.Container.ps1 b/scripts/tests/SourceCode/PSModule/PSModule.Container.ps1 new file mode 100644 index 00000000..1f425cff --- /dev/null +++ b/scripts/tests/SourceCode/PSModule/PSModule.Container.ps1 @@ -0,0 +1,9 @@ +@{ + Path = Get-ChildItem -Path $PSScriptRoot -Filter *.Tests.ps1 | Select-Object -ExpandProperty FullName + Data = @{ + Path = $env:PSMODULE_INVOKE_PESTER_INPUT_Run_Path + TestsPath = $env:LocalTestPath + Debug = $false + Verbose = $false + } +} diff --git a/scripts/tests/PSModule/SourceCode.Tests.ps1 b/scripts/tests/SourceCode/PSModule/PSModule.Tests.ps1 similarity index 84% rename from scripts/tests/PSModule/SourceCode.Tests.ps1 rename to scripts/tests/SourceCode/PSModule/PSModule.Tests.ps1 index bbed2449..001ca7f7 100644 --- a/scripts/tests/PSModule/SourceCode.Tests.ps1 +++ b/scripts/tests/SourceCode/PSModule/PSModule.Tests.ps1 @@ -10,6 +10,10 @@ 'PSUseDeclaredVarsMoreThanAssignments', 'functionBearingFiles', Justification = 'Variables are used in the test.' )] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingWriteHost', '', + Justification = 'Logging to Github Actions.' +)] [CmdLetBinding()] Param( # The path to the 'src' folder of the repo. @@ -23,80 +27,85 @@ Param( BeforeAll { $scriptFiles = Get-ChildItem -Path $Path -Include *.psm1, *.ps1 -Recurse -File - LogGroup "Found $($scriptFiles.Count) script files in [$Path]" { - $scriptFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Script files [$($scriptFiles.Count)]" + $scriptFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $functionsPath = Join-Path -Path $Path -ChildPath 'functions' $functionFiles = (Test-Path -Path $functionsPath) ? (Get-ChildItem -Path $functionsPath -File -Filter '*.ps1' -Recurse) : $null - - LogGroup "Found $($functionFiles.Count) function files in [$functionsPath]" { - $functionFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Function files [$($functionFiles.Count)]" + $functionFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $privateFunctionsPath = Join-Path -Path $functionsPath -ChildPath 'private' $privateFunctionFiles = (Test-Path -Path $privateFunctionsPath) ? (Get-ChildItem -Path $privateFunctionsPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($privateFunctionFiles.Count) private function files in [$privateFunctionsPath]" { - $privateFunctionFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Private [$($privateFunctionFiles.Count)]" + $privateFunctionFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $publicFunctionsPath = Join-Path -Path $functionsPath -ChildPath 'public' $publicFunctionFiles = (Test-Path -Path $publicFunctionsPath) ? (Get-ChildItem -Path $publicFunctionsPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($publicFunctionFiles.Count) public function files in [$publicFunctionsPath]" { - $publicFunctionFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Public [$($publicFunctionFiles.Count)]" + $publicFunctionFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $variablesPath = Join-Path -Path $Path -ChildPath 'variables' $variableFiles = (Test-Path -Path $variablesPath) ? (Get-ChildItem -Path $variablesPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($variableFiles.Count) variable files in [$variablesPath]" { - $variableFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Variable files [$($variableFiles.Count)]" + $variableFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $privateVariablesPath = Join-Path -Path $variablesPath -ChildPath 'private' $privateVariableFiles = (Test-Path -Path $privateVariablesPath) ? (Get-ChildItem -Path $privateVariablesPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($privateVariableFiles.Count) private variable files in [$privateVariablesPath]" { - $privateVariableFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Private [$($privateVariableFiles.Count)]" + $privateVariableFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $publicVariablesPath = Join-Path -Path $variablesPath -ChildPath 'public' $publicVariableFiles = (Test-Path -Path $publicVariablesPath) ? (Get-ChildItem -Path $publicVariablesPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($publicVariableFiles.Count) public variable files in [$publicVariablesPath]" { - $publicVariableFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Public [$($publicVariableFiles.Count)]" + $publicVariableFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $classPath = Join-Path -Path $Path -ChildPath 'classes' $classFiles = (Test-Path -Path $classPath) ? (Get-ChildItem -Path $classPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($classFiles.Count) class files in [$classPath]" { - $classFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Class [$($classFiles.Count)]" + $classFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $privateClassPath = Join-Path -Path $classPath -ChildPath 'private' $privateClassFiles = (Test-Path -Path $privateClassPath) ? (Get-ChildItem -Path $privateClassPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($privateClassFiles.Count) private class files in [$privateClassPath]" { - $privateClassFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Private [$($privateClassFiles.Count)]" + $privateClassFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' $publicClassPath = Join-Path -Path $classPath -ChildPath 'public' $publicClassFiles = (Test-Path -Path $publicClassPath) ? (Get-ChildItem -Path $publicClassPath -File -Filter '*.ps1' -Recurse) : $null - LogGroup "Found $($publicClassFiles.Count) public class files in [$publicClassPath]" { - $publicClassFiles | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose - } + Write-Host "::group:: - Public [$($publicClassFiles.Count)]" + $publicClassFiles | ForEach-Object { + Write-Host " - $($_.FullName)" + } + Write-Host '::endgroup::' + $testFiles = Get-ChildItem -Path $TestsPath -Include *.Tests.ps1 -Recurse -File + Write-Host "::group:: - Test files [$($testFiles.Count)]" + $testFiles | ForEach-Object { + Write-Host " - $($_.FullName)" } + Write-Host '::endgroup::' } Describe 'PSModule - SourceCode tests' { @@ -110,7 +119,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:NumberOfProcessors:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping NumberOfProcessors test' + Write-Host "::warning title=Skipping NumberOfProcessors test:: - $relativePath - $skipReason" } else { $issues += " - $($_.Path):L$($_.LineNumber)" } @@ -127,7 +136,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:Verbose:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping Verbose test' + Write-Host "::warning title=Skipping Verbose test:: - $relativePath - $skipReason" } else { Select-String -Path $filePath -Pattern '\s(-Verbose(?::\$true)?)\b(?!:\$false)' -AllMatches | ForEach-Object { $issues += " - $relativePath`:L$($_.LineNumber) - $($_.Line)" @@ -145,7 +154,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:OutNull:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping OutNull test' + Write-Host "::warning title=Skipping OutNull test:: - $relativePath - $skipReason" } else { Select-String -Path $filePath -Pattern 'Out-Null' -AllMatches | ForEach-Object { $issues += " - $relativePath`:L$($_.LineNumber) - $($_.Line)" @@ -163,7 +172,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:NoTernary:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping NoTernary test' + Write-Host "::warning title=Skipping NoTernary test:: - $relativePath - $skipReason" } else { Select-String -Path $filePath -Pattern '(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping LowercaseKeywords test' + Write-Host "::warning title=Skipping LowercaseKeywords test:: - $relativePath - $skipReason" } else { $errors = $null $tokens = $null @@ -201,8 +210,8 @@ Describe 'PSModule - SourceCode tests' { } } - Context 'classes' { - } + # Context 'classes' { + # } Context 'functions' { Context 'Generic' { @@ -237,7 +246,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:FunctionCount:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping FunctionCount test' + Write-Host "::warning title=Skipping FunctionCount test:: - $relativePath - $skipReason" } else { $Ast = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $tokens = $Ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] } , $true ) @@ -258,7 +267,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:FunctionName:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping FunctionName test' + Write-Host "::warning title=Skipping FunctionName test:: - $relativePath - $skipReason" } else { $Ast = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $tokens = $Ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] } , $true ) @@ -279,7 +288,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:CmdletBinding:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping CmdletBinding test' + Write-Host "::warning title=Skipping CmdletBinding test:: - $relativePath - $skipReason" } else { $scriptAst = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $tokens = $scriptAst.FindAll({ $true }, $true) @@ -305,7 +314,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:ParamBlock:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping ParamBlock test' + Write-Host "::warning title=Skipping ParamBlock test:: - $relativePath - $skipReason" } else { $scriptAst = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $tokens = $scriptAst.FindAll({ $args[0] -is [System.Management.Automation.Language.ParamBlockAst] }, $true) @@ -357,7 +366,7 @@ Describe 'PSModule - SourceCode tests' { $skipTest = Select-String -Path $filePath -Pattern '#SkipTest:FunctionTest:(?.+)' -AllMatches if ($skipTest.Matches.Count -gt 0) { $skipReason = $skipTest.Matches.Groups | Where-Object { $_.Name -eq 'Reason' } | Select-Object -ExpandProperty Value - Write-GitHubWarning -Message " - $relativePath - $skipReason" -Title 'Skipping FunctionTest test' + Write-Host "::warning title=Skipping FunctionTest test:: - $relativePath - $skipReason" } else { $Ast = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $tokens = $Ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] } , $true ) @@ -372,14 +381,9 @@ Describe 'PSModule - SourceCode tests' { Should -BeNullOrEmpty -Because 'a test should exist for each of the functions in the module' } } - Context 'private functions' {} - } - - Context 'variables' { + # Context 'private functions' {} } - Context 'Module manifest' { - # It 'Module Manifest exists (maifest.psd1 or modulename.psd1)' {} - # It 'Module Manifest is valid' {} - } + # Context 'variables' { + # } } diff --git a/scripts/tests/SourceCode/SourceCode.Configuration.ps1 b/scripts/tests/SourceCode/SourceCode.Configuration.ps1 new file mode 100644 index 00000000..e76f767f --- /dev/null +++ b/scripts/tests/SourceCode/SourceCode.Configuration.ps1 @@ -0,0 +1,8 @@ +@{ + TestResult = @{ + Enabled = $true + } + Output = @{ + Verbosity = 'Detailed' + } +} diff --git a/tests/outputs/docs/PSModuleTest/Get-PSModuleTest.md b/tests/outputTestRepo/outputs/docs/PSModuleTest/Get-PSModuleTest.md similarity index 100% rename from tests/outputs/docs/PSModuleTest/Get-PSModuleTest.md rename to tests/outputTestRepo/outputs/docs/PSModuleTest/Get-PSModuleTest.md diff --git a/tests/outputs/docs/PSModuleTest/New-PSModuleTest.md b/tests/outputTestRepo/outputs/docs/PSModuleTest/New-PSModuleTest.md similarity index 100% rename from tests/outputs/docs/PSModuleTest/New-PSModuleTest.md rename to tests/outputTestRepo/outputs/docs/PSModuleTest/New-PSModuleTest.md diff --git a/tests/outputs/docs/PSModuleTest/Set-PSModuleTest.md b/tests/outputTestRepo/outputs/docs/PSModuleTest/Set-PSModuleTest.md similarity index 100% rename from tests/outputs/docs/PSModuleTest/Set-PSModuleTest.md rename to tests/outputTestRepo/outputs/docs/PSModuleTest/Set-PSModuleTest.md diff --git a/tests/outputs/docs/PSModuleTest/Test-PSModuleTest.md b/tests/outputTestRepo/outputs/docs/PSModuleTest/Test-PSModuleTest.md similarity index 100% rename from tests/outputs/docs/PSModuleTest/Test-PSModuleTest.md rename to tests/outputTestRepo/outputs/docs/PSModuleTest/Test-PSModuleTest.md diff --git a/tests/outputs/modules/PSModuleTest/PSModuleTest.psd1 b/tests/outputTestRepo/outputs/module/PSModuleTest/PSModuleTest.psd1 similarity index 98% rename from tests/outputs/modules/PSModuleTest/PSModuleTest.psd1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/PSModuleTest.psd1 index ebe988d3..b0fdcc2f 100644 --- a/tests/outputs/modules/PSModuleTest/PSModuleTest.psd1 +++ b/tests/outputTestRepo/outputs/module/PSModuleTest/PSModuleTest.psd1 @@ -14,7 +14,7 @@ ProcessorArchitecture = 'None' RequiredModules = @( @{ - ModuleVersion = '1.0' + ModuleVersion = '1.1.5' ModuleName = 'PSSemVer' } 'Utilities' diff --git a/tests/outputs/modules/PSModuleTest/PSModuleTest.psm1 b/tests/outputTestRepo/outputs/module/PSModuleTest/PSModuleTest.psm1 similarity index 100% rename from tests/outputs/modules/PSModuleTest/PSModuleTest.psm1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/PSModuleTest.psm1 diff --git a/tests/outputs/modules/PSModuleTest/assemblies/LsonLib.dll b/tests/outputTestRepo/outputs/module/PSModuleTest/assemblies/LsonLib.dll similarity index 100% rename from tests/outputs/modules/PSModuleTest/assemblies/LsonLib.dll rename to tests/outputTestRepo/outputs/module/PSModuleTest/assemblies/LsonLib.dll diff --git a/tests/outputs/modules/PSModuleTest/data/Config.psd1 b/tests/outputTestRepo/outputs/module/PSModuleTest/data/Config.psd1 similarity index 100% rename from tests/outputs/modules/PSModuleTest/data/Config.psd1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/data/Config.psd1 diff --git a/tests/outputs/modules/PSModuleTest/data/Settings.psd1 b/tests/outputTestRepo/outputs/module/PSModuleTest/data/Settings.psd1 similarity index 100% rename from tests/outputs/modules/PSModuleTest/data/Settings.psd1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/data/Settings.psd1 diff --git a/tests/outputs/modules/PSModuleTest/formats/CultureInfo.Format.ps1xml b/tests/outputTestRepo/outputs/module/PSModuleTest/formats/CultureInfo.Format.ps1xml similarity index 100% rename from tests/outputs/modules/PSModuleTest/formats/CultureInfo.Format.ps1xml rename to tests/outputTestRepo/outputs/module/PSModuleTest/formats/CultureInfo.Format.ps1xml diff --git a/tests/outputs/modules/PSModuleTest/formats/Mygciview.Format.ps1xml b/tests/outputTestRepo/outputs/module/PSModuleTest/formats/Mygciview.Format.ps1xml similarity index 100% rename from tests/outputs/modules/PSModuleTest/formats/Mygciview.Format.ps1xml rename to tests/outputTestRepo/outputs/module/PSModuleTest/formats/Mygciview.Format.ps1xml diff --git a/tests/outputs/modules/PSModuleTest/modules/OtherPSModule.psm1 b/tests/outputTestRepo/outputs/module/PSModuleTest/modules/OtherPSModule.psm1 similarity index 100% rename from tests/outputs/modules/PSModuleTest/modules/OtherPSModule.psm1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/modules/OtherPSModule.psm1 diff --git a/tests/outputs/modules/PSModuleTest/scripts/loader.ps1 b/tests/outputTestRepo/outputs/module/PSModuleTest/scripts/loader.ps1 similarity index 100% rename from tests/outputs/modules/PSModuleTest/scripts/loader.ps1 rename to tests/outputTestRepo/outputs/module/PSModuleTest/scripts/loader.ps1 diff --git a/tests/outputs/modules/PSModuleTest/types/DirectoryInfo.Types.ps1xml b/tests/outputTestRepo/outputs/module/PSModuleTest/types/DirectoryInfo.Types.ps1xml similarity index 100% rename from tests/outputs/modules/PSModuleTest/types/DirectoryInfo.Types.ps1xml rename to tests/outputTestRepo/outputs/module/PSModuleTest/types/DirectoryInfo.Types.ps1xml diff --git a/tests/outputs/modules/PSModuleTest/types/FileInfo.Types.ps1xml b/tests/outputTestRepo/outputs/module/PSModuleTest/types/FileInfo.Types.ps1xml similarity index 100% rename from tests/outputs/modules/PSModuleTest/types/FileInfo.Types.ps1xml rename to tests/outputTestRepo/outputs/module/PSModuleTest/types/FileInfo.Types.ps1xml diff --git a/tests/outputTestRepo/tests/Environments/Environment.Tests.ps1 b/tests/outputTestRepo/tests/Environments/Environment.Tests.ps1 new file mode 100644 index 00000000..211be946 --- /dev/null +++ b/tests/outputTestRepo/tests/Environments/Environment.Tests.ps1 @@ -0,0 +1,15 @@ +Describe 'Environment Variables are available' { + It 'Should be available [<_>]' -ForEach @( + 'TEST_APP_ENT_CLIENT_ID', + 'TEST_APP_ENT_PRIVATE_KEY', + 'TEST_APP_ORG_CLIENT_ID', + 'TEST_APP_ORG_PRIVATE_KEY', + 'TEST_USER_ORG_FG_PAT', + 'TEST_USER_USER_FG_PAT', + 'TEST_USER_PAT' + ) { + $name = $_ + Write-Verbose "Environment variable: [$name]" -Verbose + Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/outputTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 b/tests/outputTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 new file mode 100644 index 00000000..9bf1bb64 --- /dev/null +++ b/tests/outputTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 @@ -0,0 +1,44 @@ +[CmdletBinding()] +Param( + # Path to the module to test. + [Parameter()] + [string] $Path +) + +Write-Verbose "Path to the module: [$Path]" -Verbose +Describe 'PSModuleTest.Tests.ps1' { + Context 'Function: Test-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Test-PSModuleTest -Name 'World' | Out-String) -Verbose + Test-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Get-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Get-PSModuleTest -Name 'World' | Out-String) -Verbose + Get-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: New-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (New-PSModuleTest -Name 'World' | Out-String) -Verbose + New-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Set-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Set-PSModuleTest -Name 'World' | Out-String) -Verbose + Set-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Variables' { + It "Exports a variable for SolarSystems that contains 'Solar System'" { + Write-Verbose ($SolarSystems | Out-String) -Verbose + $SolarSystems[0].Name | Should -Be 'Solar System' + } + } +} diff --git a/tests/srcTestRepo/README.md b/tests/srcTestRepo/README.md new file mode 100644 index 00000000..b459e352 --- /dev/null +++ b/tests/srcTestRepo/README.md @@ -0,0 +1,3 @@ +# Test module + +This is a test readme. diff --git a/tests/srcTestRepo/icon/icon.png b/tests/srcTestRepo/icon/icon.png new file mode 100644 index 00000000..be83fd5f Binary files /dev/null and b/tests/srcTestRepo/icon/icon.png differ diff --git a/tests/srcTestRepo/mkdocs.yml b/tests/srcTestRepo/mkdocs.yml new file mode 100644 index 00000000..df5e17ad --- /dev/null +++ b/tests/srcTestRepo/mkdocs.yml @@ -0,0 +1,75 @@ +site_name: -{{ REPO_NAME }}- +theme: + name: material + language: en + font: + text: Roboto + code: Sono + logo: Assets/icon.png + favicon: Assets/icon.png + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/link + name: Switch to dark mode + # Palette toggle for dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + toggle: + primary: black + accent: green + icon: material/toggle-switch-off-outline + name: Switch to light mode + # Palette toggle for light mode + - media: '(prefers-color-scheme: light)' + scheme: default + toggle: + primary: indigo + accent: green + icon: material/toggle-switch + name: Switch to system preference + icon: + repo: material/github + features: + - navigation.instant + - navigation.instant.progress + - navigation.indexes + - navigation.top + - navigation.tracking + - navigation.expand + - search.suggest + - search.highlight + +repo_name: -{{ REPO_OWNER }}-/-{{ REPO_NAME }}- +repo_url: https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}- + +plugins: + - search + +markdown_extensions: + - toc: + permalink: true # Adds a link icon to headings + - attr_list + - admonition + - md_in_html + - pymdownx.details # Enables collapsible admonitions + +extra: + social: + - icon: fontawesome/brands/discord + link: https://discord.gg/jedJWCPAhD + name: -{{ REPO_OWNER }}- on Discord + - icon: fontawesome/brands/github + link: https://github.com/-{{ REPO_OWNER }}-/ + name: -{{ REPO_OWNER }}- on GitHub + consent: + title: Cookie consent + description: >- + We use cookies to recognize your repeated visits and preferences, as well + as to measure the effectiveness of our documentation and whether users + find what they're searching for. With your consent, you're helping us to + make our documentation better. + actions: + - accept + - reject diff --git a/tests/src/assemblies/LsonLib.dll b/tests/srcTestRepo/src/assemblies/LsonLib.dll similarity index 100% rename from tests/src/assemblies/LsonLib.dll rename to tests/srcTestRepo/src/assemblies/LsonLib.dll diff --git a/tests/src/classes/private/SecretWriter.ps1 b/tests/srcTestRepo/src/classes/private/SecretWriter.ps1 similarity index 100% rename from tests/src/classes/private/SecretWriter.ps1 rename to tests/srcTestRepo/src/classes/private/SecretWriter.ps1 diff --git a/tests/src/classes/public/Book.ps1 b/tests/srcTestRepo/src/classes/public/Book.ps1 similarity index 100% rename from tests/src/classes/public/Book.ps1 rename to tests/srcTestRepo/src/classes/public/Book.ps1 diff --git a/tests/src/data/Config.psd1 b/tests/srcTestRepo/src/data/Config.psd1 similarity index 100% rename from tests/src/data/Config.psd1 rename to tests/srcTestRepo/src/data/Config.psd1 diff --git a/tests/src/data/Settings.psd1 b/tests/srcTestRepo/src/data/Settings.psd1 similarity index 100% rename from tests/src/data/Settings.psd1 rename to tests/srcTestRepo/src/data/Settings.psd1 diff --git a/tests/src/finally.ps1 b/tests/srcTestRepo/src/finally.ps1 similarity index 100% rename from tests/src/finally.ps1 rename to tests/srcTestRepo/src/finally.ps1 diff --git a/tests/src/formats/CultureInfo.Format.ps1xml b/tests/srcTestRepo/src/formats/CultureInfo.Format.ps1xml similarity index 100% rename from tests/src/formats/CultureInfo.Format.ps1xml rename to tests/srcTestRepo/src/formats/CultureInfo.Format.ps1xml diff --git a/tests/src/formats/Mygciview.Format.ps1xml b/tests/srcTestRepo/src/formats/Mygciview.Format.ps1xml similarity index 100% rename from tests/src/formats/Mygciview.Format.ps1xml rename to tests/srcTestRepo/src/formats/Mygciview.Format.ps1xml diff --git a/tests/src/functions/private/Get-InternalPSModule.ps1 b/tests/srcTestRepo/src/functions/private/Get-InternalPSModule.ps1 similarity index 100% rename from tests/src/functions/private/Get-InternalPSModule.ps1 rename to tests/srcTestRepo/src/functions/private/Get-InternalPSModule.ps1 diff --git a/tests/src/functions/private/Set-InternalPSModule.ps1 b/tests/srcTestRepo/src/functions/private/Set-InternalPSModule.ps1 similarity index 100% rename from tests/src/functions/private/Set-InternalPSModule.ps1 rename to tests/srcTestRepo/src/functions/private/Set-InternalPSModule.ps1 diff --git a/tests/src/functions/public/Test-PSModuleTest.ps1 b/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 similarity index 52% rename from tests/src/functions/public/Test-PSModuleTest.ps1 rename to tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 index 4056e2f6..57257f1d 100644 --- a/tests/src/functions/public/Test-PSModuleTest.ps1 +++ b/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 @@ -1,5 +1,9 @@ -#SkipTest:Verbose:Just want to test that a function can have multiple skips. -function Test-PSModuleTest { +#Requires -Modules Utilities +#Requires -Modules @{ ModuleName = 'PSSemVer'; RequiredVersion = '1.1.4' } +#Requires -Modules @{ ModuleName = 'DynamicParams'; ModuleVersion = '1.1.8' } +#Requires -Modules @{ ModuleName = 'Store'; ModuleVersion = '0.3.1' } + +function Get-PSModuleTest { <# .SYNOPSIS Performs tests on a module. @@ -16,5 +20,4 @@ function Test-PSModuleTest { [string] $Name ) Write-Output "Hello, $Name!" - Write-Verbose 'Verbose message' -Verbose } diff --git a/tests/src/functions/public/New-PSModuleTest.ps1 b/tests/srcTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 similarity index 81% rename from tests/src/functions/public/New-PSModuleTest.ps1 rename to tests/srcTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 index 8fc0641f..5fa16bc3 100644 --- a/tests/src/functions/public/New-PSModuleTest.ps1 +++ b/tests/srcTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 @@ -1,6 +1,5 @@ -#Requires -Modules @{ModuleName='PSSemVer'; ModuleVersion='1.0'} -#SkipTest:FunctionTest:Difficult to test due to the nature of the function. -#SkipTest:Verbose:Just want to test that a function can have multiple skips. +#Requires -Modules @{ModuleName='PSSemVer'; ModuleVersion='1.1.4'} + function New-PSModuleTest { <# .SYNOPSIS @@ -28,11 +27,11 @@ function New-PSModuleTest { [Parameter(Mandatory)] [string] $Name ) - Write-Debug "Debug message" - Write-Verbose "Verbose message" -Verbose Write-Output "Hello, $Name!" } New-Alias New-PSModuleTestAlias3 New-PSModuleTest New-Alias -Name New-PSModuleTestAlias4 -Value New-PSModuleTest + + Set-Alias New-PSModuleTestAlias5 New-PSModuleTest diff --git a/tests/srcTestRepo/src/functions/public/PSModule/PSModule.md b/tests/srcTestRepo/src/functions/public/PSModule/PSModule.md new file mode 100644 index 00000000..79741cf4 --- /dev/null +++ b/tests/srcTestRepo/src/functions/public/PSModule/PSModule.md @@ -0,0 +1 @@ +# This is PSModule diff --git a/tests/src/functions/public/Set-PSModuleTest.ps1 b/tests/srcTestRepo/src/functions/public/SomethingElse/Set-PSModuleTest.ps1 similarity index 100% rename from tests/src/functions/public/Set-PSModuleTest.ps1 rename to tests/srcTestRepo/src/functions/public/SomethingElse/Set-PSModuleTest.ps1 diff --git a/tests/srcTestRepo/src/functions/public/SomethingElse/SomethingElse.md b/tests/srcTestRepo/src/functions/public/SomethingElse/SomethingElse.md new file mode 100644 index 00000000..d9f7e9ee --- /dev/null +++ b/tests/srcTestRepo/src/functions/public/SomethingElse/SomethingElse.md @@ -0,0 +1 @@ +# This is SomethingElse diff --git a/tests/src/functions/public/Get-PSModuleTest.ps1 b/tests/srcTestRepo/src/functions/public/Test-PSModuleTest.ps1 similarity index 83% rename from tests/src/functions/public/Get-PSModuleTest.ps1 rename to tests/srcTestRepo/src/functions/public/Test-PSModuleTest.ps1 index 0e9aacfe..26be2b9b 100644 --- a/tests/src/functions/public/Get-PSModuleTest.ps1 +++ b/tests/srcTestRepo/src/functions/public/Test-PSModuleTest.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules Utilities - -function Get-PSModuleTest { +function Test-PSModuleTest { <# .SYNOPSIS Performs tests on a module. diff --git a/tests/src/functions/public/completers.ps1 b/tests/srcTestRepo/src/functions/public/completers.ps1 similarity index 100% rename from tests/src/functions/public/completers.ps1 rename to tests/srcTestRepo/src/functions/public/completers.ps1 diff --git a/tests/src/header.ps1 b/tests/srcTestRepo/src/header.ps1 similarity index 100% rename from tests/src/header.ps1 rename to tests/srcTestRepo/src/header.ps1 diff --git a/tests/src/init/initializer.ps1 b/tests/srcTestRepo/src/init/initializer.ps1 similarity index 100% rename from tests/src/init/initializer.ps1 rename to tests/srcTestRepo/src/init/initializer.ps1 diff --git a/tests/src/modules/OtherPSModule.psm1 b/tests/srcTestRepo/src/modules/OtherPSModule.psm1 similarity index 100% rename from tests/src/modules/OtherPSModule.psm1 rename to tests/srcTestRepo/src/modules/OtherPSModule.psm1 diff --git a/tests/src/scripts/loader.ps1 b/tests/srcTestRepo/src/scripts/loader.ps1 similarity index 100% rename from tests/src/scripts/loader.ps1 rename to tests/srcTestRepo/src/scripts/loader.ps1 diff --git a/tests/src/types/DirectoryInfo.Types.ps1xml b/tests/srcTestRepo/src/types/DirectoryInfo.Types.ps1xml similarity index 100% rename from tests/src/types/DirectoryInfo.Types.ps1xml rename to tests/srcTestRepo/src/types/DirectoryInfo.Types.ps1xml diff --git a/tests/src/types/FileInfo.Types.ps1xml b/tests/srcTestRepo/src/types/FileInfo.Types.ps1xml similarity index 100% rename from tests/src/types/FileInfo.Types.ps1xml rename to tests/srcTestRepo/src/types/FileInfo.Types.ps1xml diff --git a/tests/src/variables/private/PrivateVariables.ps1 b/tests/srcTestRepo/src/variables/private/PrivateVariables.ps1 similarity index 100% rename from tests/src/variables/private/PrivateVariables.ps1 rename to tests/srcTestRepo/src/variables/private/PrivateVariables.ps1 diff --git a/tests/src/variables/public/Moons.ps1 b/tests/srcTestRepo/src/variables/public/Moons.ps1 similarity index 100% rename from tests/src/variables/public/Moons.ps1 rename to tests/srcTestRepo/src/variables/public/Moons.ps1 diff --git a/tests/src/variables/public/Planets.ps1 b/tests/srcTestRepo/src/variables/public/Planets.ps1 similarity index 100% rename from tests/src/variables/public/Planets.ps1 rename to tests/srcTestRepo/src/variables/public/Planets.ps1 diff --git a/tests/src/variables/public/SolarSystems.ps1 b/tests/srcTestRepo/src/variables/public/SolarSystems.ps1 similarity index 100% rename from tests/src/variables/public/SolarSystems.ps1 rename to tests/srcTestRepo/src/variables/public/SolarSystems.ps1 diff --git a/tests/srcTestRepo/tests/Environment.Tests.ps1 b/tests/srcTestRepo/tests/Environment.Tests.ps1 new file mode 100644 index 00000000..211be946 --- /dev/null +++ b/tests/srcTestRepo/tests/Environment.Tests.ps1 @@ -0,0 +1,15 @@ +Describe 'Environment Variables are available' { + It 'Should be available [<_>]' -ForEach @( + 'TEST_APP_ENT_CLIENT_ID', + 'TEST_APP_ENT_PRIVATE_KEY', + 'TEST_APP_ORG_CLIENT_ID', + 'TEST_APP_ORG_PRIVATE_KEY', + 'TEST_USER_ORG_FG_PAT', + 'TEST_USER_USER_FG_PAT', + 'TEST_USER_PAT' + ) { + $name = $_ + Write-Verbose "Environment variable: [$name]" -Verbose + Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 b/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 new file mode 100644 index 00000000..9bf1bb64 --- /dev/null +++ b/tests/srcTestRepo/tests/PSModuleTest.Tests.ps1 @@ -0,0 +1,44 @@ +[CmdletBinding()] +Param( + # Path to the module to test. + [Parameter()] + [string] $Path +) + +Write-Verbose "Path to the module: [$Path]" -Verbose +Describe 'PSModuleTest.Tests.ps1' { + Context 'Function: Test-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Test-PSModuleTest -Name 'World' | Out-String) -Verbose + Test-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Get-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Get-PSModuleTest -Name 'World' | Out-String) -Verbose + Get-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: New-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (New-PSModuleTest -Name 'World' | Out-String) -Verbose + New-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Set-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Set-PSModuleTest -Name 'World' | Out-String) -Verbose + Set-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Variables' { + It "Exports a variable for SolarSystems that contains 'Solar System'" { + Write-Verbose ($SolarSystems | Out-String) -Verbose + $SolarSystems[0].Name | Should -Be 'Solar System' + } + } +} diff --git a/tests/srcWithManifestTestRepo/README.md b/tests/srcWithManifestTestRepo/README.md new file mode 100644 index 00000000..b459e352 --- /dev/null +++ b/tests/srcWithManifestTestRepo/README.md @@ -0,0 +1,3 @@ +# Test module + +This is a test readme. diff --git a/tests/srcWithManifestTestRepo/icon/icon.png b/tests/srcWithManifestTestRepo/icon/icon.png new file mode 100644 index 00000000..be83fd5f Binary files /dev/null and b/tests/srcWithManifestTestRepo/icon/icon.png differ diff --git a/tests/srcWithManifestTestRepo/mkdocs.yml b/tests/srcWithManifestTestRepo/mkdocs.yml new file mode 100644 index 00000000..df5e17ad --- /dev/null +++ b/tests/srcWithManifestTestRepo/mkdocs.yml @@ -0,0 +1,75 @@ +site_name: -{{ REPO_NAME }}- +theme: + name: material + language: en + font: + text: Roboto + code: Sono + logo: Assets/icon.png + favicon: Assets/icon.png + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/link + name: Switch to dark mode + # Palette toggle for dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + toggle: + primary: black + accent: green + icon: material/toggle-switch-off-outline + name: Switch to light mode + # Palette toggle for light mode + - media: '(prefers-color-scheme: light)' + scheme: default + toggle: + primary: indigo + accent: green + icon: material/toggle-switch + name: Switch to system preference + icon: + repo: material/github + features: + - navigation.instant + - navigation.instant.progress + - navigation.indexes + - navigation.top + - navigation.tracking + - navigation.expand + - search.suggest + - search.highlight + +repo_name: -{{ REPO_OWNER }}-/-{{ REPO_NAME }}- +repo_url: https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}- + +plugins: + - search + +markdown_extensions: + - toc: + permalink: true # Adds a link icon to headings + - attr_list + - admonition + - md_in_html + - pymdownx.details # Enables collapsible admonitions + +extra: + social: + - icon: fontawesome/brands/discord + link: https://discord.gg/jedJWCPAhD + name: -{{ REPO_OWNER }}- on Discord + - icon: fontawesome/brands/github + link: https://github.com/-{{ REPO_OWNER }}-/ + name: -{{ REPO_OWNER }}- on GitHub + consent: + title: Cookie consent + description: >- + We use cookies to recognize your repeated visits and preferences, as well + as to measure the effectiveness of our documentation and whether users + find what they're searching for. With your consent, you're helping us to + make our documentation better. + actions: + - accept + - reject diff --git a/tests/srcWithManifest/assemblies/LsonLib.dll b/tests/srcWithManifestTestRepo/src/assemblies/LsonLib.dll similarity index 100% rename from tests/srcWithManifest/assemblies/LsonLib.dll rename to tests/srcWithManifestTestRepo/src/assemblies/LsonLib.dll diff --git a/tests/srcWithManifest/classes/private/SecretWriter.ps1 b/tests/srcWithManifestTestRepo/src/classes/private/SecretWriter.ps1 similarity index 100% rename from tests/srcWithManifest/classes/private/SecretWriter.ps1 rename to tests/srcWithManifestTestRepo/src/classes/private/SecretWriter.ps1 diff --git a/tests/srcWithManifest/classes/public/Book.ps1 b/tests/srcWithManifestTestRepo/src/classes/public/Book.ps1 similarity index 100% rename from tests/srcWithManifest/classes/public/Book.ps1 rename to tests/srcWithManifestTestRepo/src/classes/public/Book.ps1 diff --git a/tests/srcWithManifest/data/Config.psd1 b/tests/srcWithManifestTestRepo/src/data/Config.psd1 similarity index 100% rename from tests/srcWithManifest/data/Config.psd1 rename to tests/srcWithManifestTestRepo/src/data/Config.psd1 diff --git a/tests/srcWithManifest/data/Settings.psd1 b/tests/srcWithManifestTestRepo/src/data/Settings.psd1 similarity index 100% rename from tests/srcWithManifest/data/Settings.psd1 rename to tests/srcWithManifestTestRepo/src/data/Settings.psd1 diff --git a/tests/srcWithManifest/finally.ps1 b/tests/srcWithManifestTestRepo/src/finally.ps1 similarity index 100% rename from tests/srcWithManifest/finally.ps1 rename to tests/srcWithManifestTestRepo/src/finally.ps1 diff --git a/tests/srcWithManifest/formats/CultureInfo.Format.ps1xml b/tests/srcWithManifestTestRepo/src/formats/CultureInfo.Format.ps1xml similarity index 100% rename from tests/srcWithManifest/formats/CultureInfo.Format.ps1xml rename to tests/srcWithManifestTestRepo/src/formats/CultureInfo.Format.ps1xml diff --git a/tests/srcWithManifest/formats/Mygciview.Format.ps1xml b/tests/srcWithManifestTestRepo/src/formats/Mygciview.Format.ps1xml similarity index 100% rename from tests/srcWithManifest/formats/Mygciview.Format.ps1xml rename to tests/srcWithManifestTestRepo/src/formats/Mygciview.Format.ps1xml diff --git a/tests/srcWithManifest/functions/private/Get-InternalPSModule.ps1 b/tests/srcWithManifestTestRepo/src/functions/private/Get-InternalPSModule.ps1 similarity index 100% rename from tests/srcWithManifest/functions/private/Get-InternalPSModule.ps1 rename to tests/srcWithManifestTestRepo/src/functions/private/Get-InternalPSModule.ps1 diff --git a/tests/srcWithManifest/functions/private/Set-InternalPSModule.ps1 b/tests/srcWithManifestTestRepo/src/functions/private/Set-InternalPSModule.ps1 similarity index 100% rename from tests/srcWithManifest/functions/private/Set-InternalPSModule.ps1 rename to tests/srcWithManifestTestRepo/src/functions/private/Set-InternalPSModule.ps1 diff --git a/tests/srcWithManifest/functions/public/Test-PSModuleTest.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 similarity index 52% rename from tests/srcWithManifest/functions/public/Test-PSModuleTest.ps1 rename to tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 index 4056e2f6..57257f1d 100644 --- a/tests/srcWithManifest/functions/public/Test-PSModuleTest.ps1 +++ b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 @@ -1,5 +1,9 @@ -#SkipTest:Verbose:Just want to test that a function can have multiple skips. -function Test-PSModuleTest { +#Requires -Modules Utilities +#Requires -Modules @{ ModuleName = 'PSSemVer'; RequiredVersion = '1.1.4' } +#Requires -Modules @{ ModuleName = 'DynamicParams'; ModuleVersion = '1.1.8' } +#Requires -Modules @{ ModuleName = 'Store'; ModuleVersion = '0.3.1' } + +function Get-PSModuleTest { <# .SYNOPSIS Performs tests on a module. @@ -16,5 +20,4 @@ function Test-PSModuleTest { [string] $Name ) Write-Output "Hello, $Name!" - Write-Verbose 'Verbose message' -Verbose } diff --git a/tests/srcWithManifest/functions/public/New-PSModuleTest.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 similarity index 81% rename from tests/srcWithManifest/functions/public/New-PSModuleTest.ps1 rename to tests/srcWithManifestTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 index 8fc0641f..5fa16bc3 100644 --- a/tests/srcWithManifest/functions/public/New-PSModuleTest.ps1 +++ b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/New-PSModuleTest.ps1 @@ -1,6 +1,5 @@ -#Requires -Modules @{ModuleName='PSSemVer'; ModuleVersion='1.0'} -#SkipTest:FunctionTest:Difficult to test due to the nature of the function. -#SkipTest:Verbose:Just want to test that a function can have multiple skips. +#Requires -Modules @{ModuleName='PSSemVer'; ModuleVersion='1.1.4'} + function New-PSModuleTest { <# .SYNOPSIS @@ -28,11 +27,11 @@ function New-PSModuleTest { [Parameter(Mandatory)] [string] $Name ) - Write-Debug "Debug message" - Write-Verbose "Verbose message" -Verbose Write-Output "Hello, $Name!" } New-Alias New-PSModuleTestAlias3 New-PSModuleTest New-Alias -Name New-PSModuleTestAlias4 -Value New-PSModuleTest + + Set-Alias New-PSModuleTestAlias5 New-PSModuleTest diff --git a/tests/srcWithManifestTestRepo/src/functions/public/PSModule/PSModule.md b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/PSModule.md new file mode 100644 index 00000000..79741cf4 --- /dev/null +++ b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/PSModule.md @@ -0,0 +1 @@ +# This is PSModule diff --git a/tests/srcWithManifest/functions/public/Set-PSModuleTest.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/SomethingElse/Set-PSModuleTest.ps1 similarity index 100% rename from tests/srcWithManifest/functions/public/Set-PSModuleTest.ps1 rename to tests/srcWithManifestTestRepo/src/functions/public/SomethingElse/Set-PSModuleTest.ps1 diff --git a/tests/srcWithManifestTestRepo/src/functions/public/SomethingElse/SomethingElse.md b/tests/srcWithManifestTestRepo/src/functions/public/SomethingElse/SomethingElse.md new file mode 100644 index 00000000..d9f7e9ee --- /dev/null +++ b/tests/srcWithManifestTestRepo/src/functions/public/SomethingElse/SomethingElse.md @@ -0,0 +1 @@ +# This is SomethingElse diff --git a/tests/srcWithManifest/functions/public/Get-PSModuleTest.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/Test-PSModuleTest.ps1 similarity index 83% rename from tests/srcWithManifest/functions/public/Get-PSModuleTest.ps1 rename to tests/srcWithManifestTestRepo/src/functions/public/Test-PSModuleTest.ps1 index 0e9aacfe..26be2b9b 100644 --- a/tests/srcWithManifest/functions/public/Get-PSModuleTest.ps1 +++ b/tests/srcWithManifestTestRepo/src/functions/public/Test-PSModuleTest.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules Utilities - -function Get-PSModuleTest { +function Test-PSModuleTest { <# .SYNOPSIS Performs tests on a module. diff --git a/tests/srcWithManifestTestRepo/src/functions/public/completers.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/completers.ps1 new file mode 100644 index 00000000..6b1adbb7 --- /dev/null +++ b/tests/srcWithManifestTestRepo/src/functions/public/completers.ps1 @@ -0,0 +1,8 @@ +Register-ArgumentCompleter -CommandName New-PSModuleTest -ParameterName Name -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters + + 'Alice', 'Bob', 'Charlie' | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/tests/srcWithManifest/header.ps1 b/tests/srcWithManifestTestRepo/src/header.ps1 similarity index 100% rename from tests/srcWithManifest/header.ps1 rename to tests/srcWithManifestTestRepo/src/header.ps1 diff --git a/tests/srcWithManifest/init/initializer.ps1 b/tests/srcWithManifestTestRepo/src/init/initializer.ps1 similarity index 100% rename from tests/srcWithManifest/init/initializer.ps1 rename to tests/srcWithManifestTestRepo/src/init/initializer.ps1 diff --git a/tests/srcWithManifest/manifest.psd1 b/tests/srcWithManifestTestRepo/src/manifest.psd1 similarity index 100% rename from tests/srcWithManifest/manifest.psd1 rename to tests/srcWithManifestTestRepo/src/manifest.psd1 diff --git a/tests/srcWithManifest/modules/OtherPSModule.psm1 b/tests/srcWithManifestTestRepo/src/modules/OtherPSModule.psm1 similarity index 100% rename from tests/srcWithManifest/modules/OtherPSModule.psm1 rename to tests/srcWithManifestTestRepo/src/modules/OtherPSModule.psm1 diff --git a/tests/srcWithManifest/scripts/loader.ps1 b/tests/srcWithManifestTestRepo/src/scripts/loader.ps1 similarity index 100% rename from tests/srcWithManifest/scripts/loader.ps1 rename to tests/srcWithManifestTestRepo/src/scripts/loader.ps1 diff --git a/tests/srcWithManifest/types/DirectoryInfo.Types.ps1xml b/tests/srcWithManifestTestRepo/src/types/DirectoryInfo.Types.ps1xml similarity index 100% rename from tests/srcWithManifest/types/DirectoryInfo.Types.ps1xml rename to tests/srcWithManifestTestRepo/src/types/DirectoryInfo.Types.ps1xml diff --git a/tests/srcWithManifest/types/FileInfo.Types.ps1xml b/tests/srcWithManifestTestRepo/src/types/FileInfo.Types.ps1xml similarity index 100% rename from tests/srcWithManifest/types/FileInfo.Types.ps1xml rename to tests/srcWithManifestTestRepo/src/types/FileInfo.Types.ps1xml diff --git a/tests/srcWithManifest/variables/private/PrivateVariables.ps1 b/tests/srcWithManifestTestRepo/src/variables/private/PrivateVariables.ps1 similarity index 100% rename from tests/srcWithManifest/variables/private/PrivateVariables.ps1 rename to tests/srcWithManifestTestRepo/src/variables/private/PrivateVariables.ps1 diff --git a/tests/srcWithManifest/variables/public/Moons.ps1 b/tests/srcWithManifestTestRepo/src/variables/public/Moons.ps1 similarity index 100% rename from tests/srcWithManifest/variables/public/Moons.ps1 rename to tests/srcWithManifestTestRepo/src/variables/public/Moons.ps1 diff --git a/tests/srcWithManifest/variables/public/Planets.ps1 b/tests/srcWithManifestTestRepo/src/variables/public/Planets.ps1 similarity index 100% rename from tests/srcWithManifest/variables/public/Planets.ps1 rename to tests/srcWithManifestTestRepo/src/variables/public/Planets.ps1 diff --git a/tests/srcWithManifest/variables/public/SolarSystems.ps1 b/tests/srcWithManifestTestRepo/src/variables/public/SolarSystems.ps1 similarity index 100% rename from tests/srcWithManifest/variables/public/SolarSystems.ps1 rename to tests/srcWithManifestTestRepo/src/variables/public/SolarSystems.ps1 diff --git a/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 b/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 new file mode 100644 index 00000000..211be946 --- /dev/null +++ b/tests/srcWithManifestTestRepo/tests/Environments/Environment.Tests.ps1 @@ -0,0 +1,15 @@ +Describe 'Environment Variables are available' { + It 'Should be available [<_>]' -ForEach @( + 'TEST_APP_ENT_CLIENT_ID', + 'TEST_APP_ENT_PRIVATE_KEY', + 'TEST_APP_ORG_CLIENT_ID', + 'TEST_APP_ORG_PRIVATE_KEY', + 'TEST_USER_ORG_FG_PAT', + 'TEST_USER_USER_FG_PAT', + 'TEST_USER_PAT' + ) { + $name = $_ + Write-Verbose "Environment variable: [$name]" -Verbose + Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 b/tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 new file mode 100644 index 00000000..9bf1bb64 --- /dev/null +++ b/tests/srcWithManifestTestRepo/tests/MyTests/PSModuleTest.Tests.ps1 @@ -0,0 +1,44 @@ +[CmdletBinding()] +Param( + # Path to the module to test. + [Parameter()] + [string] $Path +) + +Write-Verbose "Path to the module: [$Path]" -Verbose +Describe 'PSModuleTest.Tests.ps1' { + Context 'Function: Test-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Test-PSModuleTest -Name 'World' | Out-String) -Verbose + Test-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Get-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Get-PSModuleTest -Name 'World' | Out-String) -Verbose + Get-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: New-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (New-PSModuleTest -Name 'World' | Out-String) -Verbose + New-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Function: Set-PSModuleTest' { + It 'Should be able to call the function' { + Write-Verbose (Set-PSModuleTest -Name 'World' | Out-String) -Verbose + Set-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' + } + } + + Context 'Variables' { + It "Exports a variable for SolarSystems that contains 'Solar System'" { + Write-Verbose ($SolarSystems | Out-String) -Verbose + $SolarSystems[0].Name | Should -Be 'Solar System' + } + } +} diff --git a/tests/srcWithManifestTestRepo/tools/1-build.ps1 b/tests/srcWithManifestTestRepo/tools/1-build.ps1 new file mode 100644 index 00000000..e762395b --- /dev/null +++ b/tests/srcWithManifestTestRepo/tools/1-build.ps1 @@ -0,0 +1 @@ +"1 - Build script executed." diff --git a/tests/srcWithManifestTestRepo/tools/2-build.ps1 b/tests/srcWithManifestTestRepo/tools/2-build.ps1 new file mode 100644 index 00000000..d2575a02 --- /dev/null +++ b/tests/srcWithManifestTestRepo/tools/2-build.ps1 @@ -0,0 +1 @@ +"2 - Build script executed." diff --git a/tests/tests/PSModuleTest.Tests.ps1 b/tests/tests/PSModuleTest.Tests.ps1 deleted file mode 100644 index 00b3cde7..00000000 --- a/tests/tests/PSModuleTest.Tests.ps1 +++ /dev/null @@ -1,11 +0,0 @@ -Describe 'Module' { - It 'Function: Get-PSModuleTest' { - Get-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' - } - It 'Function: Set-PSModuleTest' { - Set-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' - } - It 'Function: Test-PSModuleTest' { - Test-PSModuleTest -Name 'World' | Should -Be 'Hello, World!' - } -}