From d28139a5bcf4c1cd80007c3bd1a34ccffc1096f8 Mon Sep 17 00:00:00 2001 From: Stephen Maunder Date: Sat, 18 Nov 2017 20:07:56 +0000 Subject: [PATCH] Change build --- CHANGELOG.md | 1 + Tests/SnipeItPS.Tests.ps1 | 211 +++++++++++++++--- {SnipeitPS/docs => docs}/Get-Asset.md | 0 {SnipeitPS/docs => docs}/Get-Categories.md | 0 {SnipeitPS/docs => docs}/Get-Component.md | 0 {SnipeitPS/docs => docs}/Get-Manufacturers.md | 0 {SnipeitPS/docs => docs}/Get-Models.md | 0 {SnipeitPS/docs => docs}/Get-Status.md | 0 {SnipeitPS/docs => docs}/Get-Users.md | 0 {SnipeitPS/docs => docs}/Invoke-Method.md | 0 {SnipeitPS/docs => docs}/New-Asset.md | 0 {SnipeitPS/docs => docs}/New-Component.md | 0 {SnipeitPS/docs => docs}/New-Manufacturer.md | 0 {SnipeitPS/docs => docs}/New-Model.md | 0 {SnipeitPS/docs => docs}/Set-Asset.md | 0 {SnipeitPS/docs => docs}/Set-AssetOwner.md | 0 {SnipeitPS/docs => docs}/Set-Info.md | 0 {SnipeitPS/docs => docs}/Update-Component.md | 0 18 files changed, 180 insertions(+), 32 deletions(-) create mode 100644 CHANGELOG.md rename {SnipeitPS/docs => docs}/Get-Asset.md (100%) rename {SnipeitPS/docs => docs}/Get-Categories.md (100%) rename {SnipeitPS/docs => docs}/Get-Component.md (100%) rename {SnipeitPS/docs => docs}/Get-Manufacturers.md (100%) rename {SnipeitPS/docs => docs}/Get-Models.md (100%) rename {SnipeitPS/docs => docs}/Get-Status.md (100%) rename {SnipeitPS/docs => docs}/Get-Users.md (100%) rename {SnipeitPS/docs => docs}/Invoke-Method.md (100%) rename {SnipeitPS/docs => docs}/New-Asset.md (100%) rename {SnipeitPS/docs => docs}/New-Component.md (100%) rename {SnipeitPS/docs => docs}/New-Manufacturer.md (100%) rename {SnipeitPS/docs => docs}/New-Model.md (100%) rename {SnipeitPS/docs => docs}/Set-Asset.md (100%) rename {SnipeitPS/docs => docs}/Set-AssetOwner.md (100%) rename {SnipeitPS/docs => docs}/Set-Info.md (100%) rename {SnipeitPS/docs => docs}/Update-Component.md (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e7a19a6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +[1.0] \ No newline at end of file diff --git a/Tests/SnipeItPS.Tests.ps1 b/Tests/SnipeItPS.Tests.ps1 index 40d25e9..f3c7f28 100644 --- a/Tests/SnipeItPS.Tests.ps1 +++ b/Tests/SnipeItPS.Tests.ps1 @@ -1,53 +1,200 @@ -$ModulePath = Split-Path -Path $PSScriptRoot -Parent -$ModuleName = Split-Path -Path $ModulePath -Leaf +#Requires -Modules PSScriptAnalyzer -# Make sure one or multiple versions of the module are not loaded -Get-Module -Name $ModuleName | Remove-Module +$here = Split-Path -Parent $MyInvocation.MyCommand.Path +$projectRoot = Split-Path -Parent $here +$moduleRoot = "$projectRoot\SnipeitPS" -# Import the module and store the information about the module -$ModuleInformation = Import-Module -Name "$ModulePath\$ModuleName.psd1" -PassThru -$ModuleInformation | Format-List +$manifestFile = "$moduleRoot\SnipeitPS.psd1" +$changelogFile = "$projectRoot\CHANGELOG.md" +$appveyorFile = "$projectRoot\appveyor.yml" +$publicFunctions = "$moduleRoot\Public" +$internalFunctions = "$moduleRoot\Private" -# Get the functions present in the Manifest -$ExportedFunctions = $ModuleInformation.ExportedFunctions.Values.Name +Describe "SnipeitPS" { + Context "All required tests are present" { + # We want to make sure that every .ps1 file in the Functions directory that isn't a Pester test has an associated Pester test. + # This helps keep me honest and makes sure I'm testing my code appropriately. + It "Includes a test for each PowerShell function in the module" { + # Get-ChildItem -Path $publicFunctions -Filter "*.ps1" -Recurse | Where-Object -FilterScript {$_.Name -notlike '*.Tests.ps1'} | % { + # $expectedTestFile = Join-Path $projectRoot "Tests\$($_.BaseName).Tests.ps1" + # $expectedTestFile | Should Exist + # } + } + } -# Get the functions present in the Public folder -$PS1Functions = Get-ChildItem -Path "$ModulePath\Public\*.ps1" + Context "Manifest, changelog, and AppVeyor" { -Describe "$ModuleName Module - Testing Manifest File (.psd1)" { - Context "Manifest" { - It "Should contain RootModule" { - $ModuleInformation.RootModule | Should Not BeNullOrEmpty + # These tests are...erm, borrowed...from the module tests from the Pester module. + # I think they are excellent for sanity checking, and all credit for the following + # tests goes to Dave Wyatt, the genius behind Pester. I've just adapted them + # slightly to match SnipeitPS. + + $script:manifest = $null + + foreach ($line in (Get-Content $changelogFile)) { + if ($line -match "^\D*(?(\d+\.){1,3}\d+)") { + $changelogVersion = $matches.Version + break + } } - It "Should contain ModuleVersion" { - $ModuleInformation.Version | Should Not BeNullOrEmpty + foreach ($line in (Get-Content $appveyorFile)) { + # (?()) - non-capturing group, but named Version. This makes it + # easy to reference the inside group later. + + if ($line -match '^\D*(?(\d+\.){1,3}\d+).\{build\}') { + $appveyorVersion = $matches.Version + break + } } - It "Should contain GUID" { - $ModuleInformation.Guid | Should Not BeNullOrEmpty + It "Includes a valid manifest file" { + { + $script:manifest = Test-ModuleManifest -Path $script:manifestFile -ErrorAction Stop -WarningAction SilentlyContinue + } | Should Not Throw } - It "Should contain Author" { - $ModuleInformation.Author | Should Not BeNullOrEmpty + # There is a bug that prevents Test-ModuleManifest from updating correctly when the manifest file changes. See here: + # https://connect.microsoft.com/PowerShell/feedback/details/1541659/test-modulemanifest-the-psmoduleinfo-is-not-updated + + # As a temp workaround, we'll just read the manifest as a raw hashtable. + # Credit to this workaround comes from here: + # https://psescape.azurewebsites.net/pester-testing-your-module-manifest/ + $script:manifest = Invoke-Expression (Get-Content $script:manifestFile -Raw) + + It "Manifest file includes the correct root module" { + $script:manifest.RootModule | Should Be 'SnipeitPS.psm1' } - It "Should contain Description" { - $ModuleInformation.Description | Should Not BeNullOrEmpty + It "Manifest file includes the correct guid" { + $script:manifest.Guid | Should Be 'f86f4db4-1cb1-45c4-b7bf-6762531bfdeb' } - It "Compare the count of Function Exported and the PS1 files found" { - $status = $ExportedFunctions.Count -eq $PS1Functions.Count - $status | Should Be $true + It "Manifest file includes a valid version" { + # $script:manifest.Version -as [Version] | Should Not BeNullOrEmpty + $script:manifest.ModuleVersion -as [Version] | Should Not BeNullOrEmpty } - It "Compare the missing function" { - If ($ExportedFunctions.count -ne $PS1Functions.count) { - $Compare = Compare-Object -ReferenceObject $ExportedFunctions -DifferenceObject $PS1Functions.Basename - $Compare.InputObject -Join ',' | Should BeNullOrEmpty + It "Includes a changelog file" { + $changelogFile | Should Exist + } + + # $changelogVersion = $null + It "Changelog includes a valid version number" { + $changelogVersion | Should Not BeNullOrEmpty + $changelogVersion -as [Version] | Should Not BeNullOrEmpty + } + + It "Changelog version matches manifest version" { + $changelogVersion -as [Version] | Should Be ( $script:manifest.ModuleVersion -as [Version] ) + } + + # Back to me! Pester doesn't use AppVeyor, as far as I know, and I do. + + It "Includes an appveyor.yml file" { + $appveyorFile | Should Exist + } + + It "Appveyor.yml file includes the module version" { + $appveyorVersion | Should Not BeNullOrEmpty + $appveyorVersion -as [Version] | Should Not BeNullOrEmpty + } + + It "Appveyor version matches manifest version" { + $appveyorVersion -as [Version] | Should Be ( $script:manifest.ModuleVersion -as [Version] ) + } + } + + # The CI changes I'm testng now will render this section obsolete, + # as it should automatically patch the module manifest file with all + # exported function names. + # Leaving the code here for the moment while I can ensure those + # features are working correctly. + + # + # Context "Function checking" { + # $functionFiles = Get-ChildItem $publicFunctions -Filter *.ps1 | + # Select-Object -ExpandProperty BaseName | + # Where-Object { $_ -notlike "*.Tests" } + + # $internalFiles = Get-ChildItem $internalFunctions -Filter *.ps1 | + # Select-Object -ExpandProperty BaseName | + # Where-Object { $_ -notlike "*.Tests" } + + # #$exportedFunctions = $script:manifest.ExportedFunctions.Values.Name + # $exportedFunctions = $script:manifest.FunctionsToExport + + # foreach ($f in $functionFiles) { + # It "Exports $f" { + # $exportedFunctions -contains $f | Should Be $true + # } + # } + + # foreach ($f in $internalFiles) { + # It "Does not export $f" { + # $exportedFunctions -contains $f | Should Be $false + # } + # } + # } + + Context "Style checking" { + + # This section is again from the mastermind, Dave Wyatt. Again, credit + # goes to him for these tests. + + $files = @( + Get-ChildItem $here -Include *.ps1, *.psm1 + Get-ChildItem $publicFunctions -Include *.ps1, *.psm1 -Recurse + ) + + It 'Source files contain no trailing whitespace' { + $badLines = @( + foreach ($file in $files) { + $lines = [System.IO.File]::ReadAllLines($file.FullName) + $lineCount = $lines.Count + + for ($i = 0; $i -lt $lineCount; $i++) { + if ($lines[$i] -match '\s+$') { + 'File: {0}, Line: {1}' -f $file.FullName, ($i + 1) + } + } + } + ) + + if ($badLines.Count -gt 0) { + throw "The following $($badLines.Count) lines contain trailing whitespace: `r`n`r`n$($badLines -join "`r`n")" + } + } + + It 'Source files all end with a newline' { + $badFiles = @( + foreach ($file in $files) { + $string = [System.IO.File]::ReadAllText($file.FullName) + if ($string.Length -gt 0 -and $string[-1] -ne "`n") { + $file.FullName + } + } + ) + + if ($badFiles.Count -gt 0) { + throw "The following files do not end with a newline: `r`n`r`n$($badFiles -join "`r`n")" } } } -} -Get-Module -Name $ModuleName | Remove-Module \ No newline at end of file + Context 'PSScriptAnalyzer Rules' { + $analysis = Invoke-ScriptAnalyzer -Path "$moduleRoot" -Recurse + $scriptAnalyzerRules = Get-ScriptAnalyzerRule + + forEach ($rule in $scriptAnalyzerRules) { + It "Should pass $rule" { + If (($analysis) -and ($analysis.RuleName -contains $rule)) { + $analysis | + Where RuleName -EQ $rule -OutVariable failures | + Out-Default + $failures.Count | Should Be 0 + } + } + } + } +} \ No newline at end of file diff --git a/SnipeitPS/docs/Get-Asset.md b/docs/Get-Asset.md similarity index 100% rename from SnipeitPS/docs/Get-Asset.md rename to docs/Get-Asset.md diff --git a/SnipeitPS/docs/Get-Categories.md b/docs/Get-Categories.md similarity index 100% rename from SnipeitPS/docs/Get-Categories.md rename to docs/Get-Categories.md diff --git a/SnipeitPS/docs/Get-Component.md b/docs/Get-Component.md similarity index 100% rename from SnipeitPS/docs/Get-Component.md rename to docs/Get-Component.md diff --git a/SnipeitPS/docs/Get-Manufacturers.md b/docs/Get-Manufacturers.md similarity index 100% rename from SnipeitPS/docs/Get-Manufacturers.md rename to docs/Get-Manufacturers.md diff --git a/SnipeitPS/docs/Get-Models.md b/docs/Get-Models.md similarity index 100% rename from SnipeitPS/docs/Get-Models.md rename to docs/Get-Models.md diff --git a/SnipeitPS/docs/Get-Status.md b/docs/Get-Status.md similarity index 100% rename from SnipeitPS/docs/Get-Status.md rename to docs/Get-Status.md diff --git a/SnipeitPS/docs/Get-Users.md b/docs/Get-Users.md similarity index 100% rename from SnipeitPS/docs/Get-Users.md rename to docs/Get-Users.md diff --git a/SnipeitPS/docs/Invoke-Method.md b/docs/Invoke-Method.md similarity index 100% rename from SnipeitPS/docs/Invoke-Method.md rename to docs/Invoke-Method.md diff --git a/SnipeitPS/docs/New-Asset.md b/docs/New-Asset.md similarity index 100% rename from SnipeitPS/docs/New-Asset.md rename to docs/New-Asset.md diff --git a/SnipeitPS/docs/New-Component.md b/docs/New-Component.md similarity index 100% rename from SnipeitPS/docs/New-Component.md rename to docs/New-Component.md diff --git a/SnipeitPS/docs/New-Manufacturer.md b/docs/New-Manufacturer.md similarity index 100% rename from SnipeitPS/docs/New-Manufacturer.md rename to docs/New-Manufacturer.md diff --git a/SnipeitPS/docs/New-Model.md b/docs/New-Model.md similarity index 100% rename from SnipeitPS/docs/New-Model.md rename to docs/New-Model.md diff --git a/SnipeitPS/docs/Set-Asset.md b/docs/Set-Asset.md similarity index 100% rename from SnipeitPS/docs/Set-Asset.md rename to docs/Set-Asset.md diff --git a/SnipeitPS/docs/Set-AssetOwner.md b/docs/Set-AssetOwner.md similarity index 100% rename from SnipeitPS/docs/Set-AssetOwner.md rename to docs/Set-AssetOwner.md diff --git a/SnipeitPS/docs/Set-Info.md b/docs/Set-Info.md similarity index 100% rename from SnipeitPS/docs/Set-Info.md rename to docs/Set-Info.md diff --git a/SnipeitPS/docs/Update-Component.md b/docs/Update-Component.md similarity index 100% rename from SnipeitPS/docs/Update-Component.md rename to docs/Update-Component.md