Skip to content

Commit

Permalink
Update Pester to work on PowerShell Core at Windows, Linux, macOS (#925)
Browse files Browse the repository at this point in the history
* Set repository to use Windows-style EOL

* Comparing semantic version strings prior to fetching dynamic parameters now works in Powershell 6.0.0-beta versions

* Add travis.yml for Linux

* Exclude Gherkin from run on PowerShell Core

* Correct macOS name

* Changes to handling chars of new lines

* Rename PowerShell executable name due to rename in v6.0.0-beta.9

* Customize the code to the specifics of systems other than Windows

* Correction of mistakes in the parameter name

* Adjust notation of paths to systems other than Windows

* Improvements to code need to run Pester when Set-StrictMode -Version Latest

* Small remark about lack of WMI on Linux

* Skip failing tests - PowerShell issue #4268

* Merge pull request #926 from GavinEke/patch-1

* Update Travis CI to run on both Linux and macOS

* Better Travis config

* Improve Travis config

* Update CHANGELOG and README about compatibility with PSCore 6.x
  • Loading branch information
it-praktyk authored and nohwnd committed Nov 11, 2017
1 parent 403158e commit 312b05f
Show file tree
Hide file tree
Showing 31 changed files with 534 additions and 232 deletions.
13 changes: 11 additions & 2 deletions .gitattributes
@@ -1,3 +1,12 @@
# Auto detect text files and perform LF normalization
* text=auto
*.ps1 text
* text=auto eol=crlf
*.ps1 text
*.psm1 text
*.psd1 text
*.ps1xml text
*.md text
*.feature text
*.xsd text
*.dtd text
*.dll binary
*.PNG binary
25 changes: 25 additions & 0 deletions .travis.yml
@@ -0,0 +1,25 @@

language: generic

matrix:
include:
- os: osx
osx_image: xcode9.1
before_install:
- brew update
- brew tap caskroom/cask
- brew cask install powershell
- os: linux
dist: trusty
# VM-based builds turned out to be faster
sudo: required
addons:
apt:
sources:
- sourceline: deb [arch=amd64] https://packages.microsoft.com/ubuntu/14.04/prod trusty main
key_url: https://packages.microsoft.com/keys/microsoft.asc
packages:
- powershell

script:
- pwsh -c 'Import-Module ./Pester.psd1; Invoke-Pester -ExcludeTag VersionChecks -EnableExit'
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,5 +1,6 @@
## Unreleased
- Add-AssertionOperator can be called multiple times for identical parameters without errors. [GH-893]
- Support for PowerShell Core on Windows, Linux and macOS added [GH-639]

## 4.0.8 (September 15, 2017)
- Add Assert-VerifiableMocks that throws [GH-881]
Expand Down
14 changes: 9 additions & 5 deletions Functions/Assertions/Be.Tests.ps1
Expand Up @@ -91,13 +91,17 @@ InModuleScope Pester {
$doc | Should be $doc
}

It 'throws exception when self-imposed recursion limit is reached' {
$a1 = @(0,1)
$a2 = @($a1,2)
$a1[0] = $a2
# The test excluded on macOS due to issue https://github.com/PowerShell/PowerShell/issues/4268
If ((GetPesterOS) -ne 'macOS') {
It 'throws exception when self-imposed recursion limit is reached' {
$a1 = @(0,1)
$a2 = @($a1,2)
$a1[0] = $a2

{ $a1 | Should be $a2 } | Should throw 'recursion depth limit'
{ $a1 | Should be $a2 } | Should throw 'recursion depth limit'
}
}

}

Describe "PesterBeFailureMessage" {
Expand Down
2 changes: 1 addition & 1 deletion Functions/Assertions/FileContentMatch.Tests.ps1
Expand Up @@ -3,7 +3,7 @@
InModuleScope Pester {
Describe "PesterFileContentMatch" {
Context "when testing file contents" {
Setup -File "test.txt" "this is line 1`nrush is awesome`nAnd this is Unicode: ☺"
Setup -File "test.txt" "this is line 1$([System.Environment]::NewLine)rush is awesome$([System.Environment]::NewLine)And this is Unicode: ☺"

It "returns true if the file contains the specified content" {
"$TestDrive\test.txt" | Should FileContentMatch rush
Expand Down
2 changes: 1 addition & 1 deletion Functions/Assertions/FileContentMatchExactly.Tests.ps1
Expand Up @@ -3,7 +3,7 @@
InModuleScope Pester {
Describe "PesterFileContentMatchExactly" {
Context "when testing file contents" {
Setup -File "test.txt" "this is line 1`nPester is awesome`nAnd this is Unicode: ☺"
Setup -File "test.txt" "this is line 1$([System.Environment]::NewLine)Pester is awesome$([System.Environment]::NewLine)And this is Unicode: ☺"
It "returns true if the file contains the specified content exactly" {
"$TestDrive\test.txt" | Should FileContentMatchExactly Pester
"$TestDrive\test.txt" | Should -FileContentMatchExactly Pester
Expand Down
4 changes: 2 additions & 2 deletions Functions/Assertions/FileContentMatchMultiline.Tests.ps1
Expand Up @@ -3,13 +3,13 @@ Set-StrictMode -Version Latest
InModuleScope Pester {
Describe "PesterFileContentMatchMultiline" {
Context "when testing file contents" {
Setup -File "test.txt" "this is line 1`nthis is line 2`nPester is awesome"
Setup -File "test.txt" "this is line 1$([System.Environment]::NewLine)this is line 2$([System.Environment]::NewLine)Pester is awesome"
It "returns true if the file matches the specified content on one line" {
"$TestDrive\test.txt" | Should FileContentMatchMultiline "Pester"
}

It "returns true if the file matches the specified content across multiple lines" {
"$TestDrive\test.txt" | Should FileContentMatchMultiline "line 2`nPester"
"$TestDrive\test.txt" | Should FileContentMatchMultiline "line 2$([System.Environment]::NewLine)Pester"
}

It "returns false if the file does not contain the specified content" {
Expand Down
36 changes: 18 additions & 18 deletions Functions/Assertions/PesterThrow.Tests.ps1
Expand Up @@ -211,8 +211,8 @@ InModuleScope Pester {

PesterThrow { & $testScriptPath } $expectedErrorMessage > $null
$result = PesterThrowFailureMessage $unexpectedErrorMessage $expectedErrorMessage
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns true if the actual message is the same as the expected message' {
Expand All @@ -237,8 +237,8 @@ InModuleScope Pester {

PesterThrow { & $testScriptPath } -ErrorId $expectedErrorId > $null
$result = PesterThrowFailureMessage $null -ExpectedErrorId $expectedErrorId
$result | Should Match "^Expected: the expression to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should Match "^Expected: the expression to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns true if the actual error id is the same as the expected error id' {
Expand Down Expand Up @@ -276,8 +276,8 @@ InModuleScope Pester {

PesterThrow { & $testScriptPath } $expectedErrorMessage > $null
$result = PesterThrowFailureMessage $null $expectedErrorMessage $expectedErrorId
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns false if the actual message is not the same as the expected message when the actual error id and expected error id match' {
Expand All @@ -296,8 +296,8 @@ InModuleScope Pester {

PesterThrow { & $testScriptPath } $expectedErrorMessage > $null
$result = PesterThrowFailureMessage $null $expectedErrorMessage $expectedErrorId
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$unexpectedErrorMessage} and error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns false if the actual error id is not the same as the expected error id when the actual message and expected message match' {
Expand All @@ -316,8 +316,8 @@ InModuleScope Pester {

PesterThrow { & $testScriptPath } $expectedErrorMessage > $null
$result = PesterThrowFailureMessage $null $expectedErrorMessage $expectedErrorId
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$unexpectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$unexpectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}
}

Expand All @@ -331,15 +331,15 @@ InModuleScope Pester {
Set-Content -Path $testScriptPath -Value "throw '$unexpectedErrorMessage'"

$result = PesterThrow { & $testScriptPath } $expectedErrorMessage
$result.FailureMessage | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression to throw an exception with message {$expectedErrorMessage}, an exception was raised, message was {$unexpectedErrorMessage}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns true if the actual message is the same as the expected message' {
Set-Content -Path $testScriptPath -Value "throw 'error message'"
$result = PesterThrow { & $testScriptPath } -Negate
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception. Message was {error message}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception. Message was {error message}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception. Message was {error message}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception. Message was {error message}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns false if the actual error id is the same as the expected error id' {
Expand All @@ -355,8 +355,8 @@ InModuleScope Pester {
"

$result = PesterThrow { & $testScriptPath } -ErrorId $expectedErrorId -Negate
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception with error id {$expectedErrorId}, an exception was raised, error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}

It 'returns false if the actual message or actual error id is the same as the expected message or expected error id' {
Expand All @@ -373,8 +373,8 @@ InModuleScope Pester {
"

$result = PesterThrow { & $testScriptPath } $expectedErrorMessage -ErrorId $expectedErrorId -Negate
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$expectedErrorId}`n from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should Match "^Expected: the expression not to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
$result.FailureMessage | Should -Match "^Expected: the expression not to throw an exception with message {$expectedErrorMessage} and error id {$expectedErrorId}, an exception was raised, message was {$expectedErrorMessage} and error id was {$expectedErrorId}$([System.Environment]::NewLine) from $([RegEx]::Escape($testScriptPath)):\d+ char:\d+"
}
}
}
10 changes: 5 additions & 5 deletions Functions/Assertions/PesterThrow.ps1
Expand Up @@ -79,11 +79,11 @@ function PesterThrowFailureMessage($ActualValue, $ExpectedMessage, $ExpectedErro
{ $ExpectedMessage } { 'message was {{{0}}}' -f $ActualExceptionMessage }
{ $ExpectedErrorId } { 'error id was {{{0}}}' -f $ActualErrorId }
}
$null = $StringBuilder.Append(("{0}, an exception was {1}raised, {2}`n {3}" -f
$null = $StringBuilder.Append(("{0}, an exception was {1}raised, {2}$([System.Environment]::NewLine) {3}" -f
($Expected -join ' and '),
@{$true="";$false="not "}[$ActualExceptionWasThrown],
($Actual -join ' and '),
($ActualExceptionLine -replace "`n","`n ")
($ActualExceptionLine -replace "`n","$([System.Environment]::NewLine) ")
))
}

Expand All @@ -107,16 +107,16 @@ function NotPesterThrowFailureMessage($ActualValue, $ExpectedMessage, $ExpectedE
{ $ExpectedMessage } { 'message was {{{0}}}' -f $ActualExceptionMessage }
{ $ExpectedErrorId } { 'error id was {{{0}}}' -f $ActualErrorId }
}
$null = $StringBuilder.Append(("{0}, an exception was {1}raised, {2}`n {3}" -f
$null = $StringBuilder.Append(("{0}, an exception was {1}raised, {2}$([System.Environment]::NewLine) {3}" -f
($Expected -join ' and '),
(@{$true="";$false="not "}[$ActualExceptionWasThrown]),
($Actual -join ' and '),
($ActualExceptionLine -replace "`n","`n ")
($ActualExceptionLine -replace "$([System.Environment]::NewLine)","$([System.Environment]::NewLine) ")
))
}
else
{
$null = $StringBuilder.Append((". Message was {{{0}}}`n {1}" -f $ActualExceptionMessage, ($ActualExceptionLine -replace "`n","`n ")))
$null = $StringBuilder.Append((". Message was {{{0}}}$([System.Environment]::NewLine) {1}" -f $ActualExceptionMessage, ($ActualExceptionLine -replace "$([System.Environment]::NewLine)","$([System.Environment]::NewLine) ")))
}

return $StringBuilder.ToString()
Expand Down
2 changes: 1 addition & 1 deletion Functions/Assertions/Set-TestInconclusive.ps1
Expand Up @@ -57,7 +57,7 @@ function Set-TestInconclusive {
)

Assert-DescribeInProgress -CommandName Set-TestInconclusive
$lineText = $MyInvocation.Line.TrimEnd("`n")
$lineText = $MyInvocation.Line.TrimEnd($([System.Environment]::NewLine))
$line = $MyInvocation.ScriptLineNumber
$file = $MyInvocation.ScriptName

Expand Down
2 changes: 1 addition & 1 deletion Functions/Assertions/Should.ps1
Expand Up @@ -119,7 +119,7 @@ function Should {
end
{
$lineNumber = $MyInvocation.ScriptLineNumber
$lineText = $MyInvocation.Line.TrimEnd("`n")
$lineText = $MyInvocation.Line.TrimEnd("$([System.Environment]::NewLine)")
$file = $MyInvocation.ScriptName

if ($PSCmdlet.ParameterSetName -eq 'Legacy')
Expand Down

1 comment on commit 312b05f

@it-praktyk
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like mention that part of the code was made by (in an alphabetical order)

Thank you!

Please sign in to comment.