pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.08k stars 470 forks source link

Can't use break in for loop after Update-TypeData is called #19

Closed pagebrooks closed 11 years ago

pagebrooks commented 12 years ago

After the System.Object type is extended in the Pester module, you can no longer break out of a loop construct using the break keyword in any code that follows. You receive the following exception:

@{should=System.Object}Invalid character '@', labels can only contain characters, numbers and '_'.
At [break statement location]
+    foreach($num in 1..1) { break <<<< }
...
...

You can reproduce if you modify your Pester.psm1 as follows:

function Invoke-Pester($relative_path = ".", [switch] $EnableExit) {
    Reset-GlobalTestResults
    . "$PSScriptRoot\ObjectAdaptations\PesterFailure.ps1"

    Write-Host "break works"
    foreach($num in 1..1) { break }

        Update-TypeData -pre "$PSScriptRoot\ObjectAdaptations\types.ps1xml" -ErrorAction SilentlyContinue

    Write-Host "break does not work"
    foreach($num in 1..1) { break }

    $fixtures_path = Resolve-Path $relative_path
    Write-Host Executing all tests in $fixtures_path
...
...

The error does not occur until the following line of code is executed:

Update-TypeData -pre "$PSScriptRoot\ObjectAdaptations\types.ps1xml" -ErrorAction SilentlyContinue

I'm still trying to figure out exactly what is causing the problem, but it looks like PowerShell is treating break as a variable (label) and fails when the type extensions execute. Just a guess though.

Edit

Found some more information. If you decorate your break statement with a loop label as described in the link below, the error does not appear. Maybe the @ character is being "defaulted" in when no label is specified? At any rate, it looks like Label is being extended with "should."

http://technet.microsoft.com/en-us/library/dd315285.aspx

scottmuc commented 12 years ago

Thanks for the report. I've been wondering when the extension on System.Object would start biting people. Thanks for the thorough report analysis!

manojlds commented 12 years ago

I am not able to reproduce it. But both my Windows 7 and Windows 8 VM have Powershell 3.0 and eventhough I ran the 2.0 engine ( with powershell -version 2.0) I can't be 100% sure about it.

But hey, at the least, there will be no bug in the next version of Powershell :)

pagebrooks commented 12 years ago

That's good to know! I would like to figure out how to fix the problem with PowerShell 2.0. It looks like PowerShell is incorrectly trying to use the extension logic against its own internal objects (loop labels in this case). I tried to see if I could detect when this is happening inside the extension logic, but no luck. Admittedly, I probably didn't do it right though.

mwrock commented 12 years ago

I'm running into this issue as well on PS 2.0. It occurs when Using Pester against functions that use psake. The function calls Invoke-Psake and when Psake prints out its build report and comes accross a task called default, its Continue raises an exception:

6/23/2012 10:57:26 AM: An Error Occurred:
@{should=System.Object}Invalid character '@', labels can only contain character
s, numbers and '_'.
At C:\dev\autobox\Externals\psake\psake.psm1:636 char:21
+             continue <<<<
    + CategoryInfo          : InvalidOperation: (@{should=System.Object}:Strin
   g) [], RuntimeException
    + FullyQualifiedErrorId : InvalidLabelCharacter
AndrewSav commented 12 years ago

This type extension causes all sorts of unwanted behaviour. I noticed at least two things it breaks PowerTab and the prompt in the console starts looking like this: PS C:\Users\andrewsav@{should=System.Object}>

scottmuc commented 12 years ago

Cool, thanks for the feedback guys. I'm thinking that Invoke-Pester should start an isolated application so it doesn't affect your current running shell. I'm open to suggestions on alternate ways to extend System.Object to create the fluent assertions. I want to keep Pester pure PowerShell, but an alternative could be to write a .Net class that has a bunch of extension methods on System.Object.

It's clear that there's an issue here, but it's hard to determine if it's a bug or a major architectural flaw.

AndrewSav commented 12 years ago

Well you already have PesterFailure .Net class, so I don't see anything wrong with having another one.

da9l commented 12 years ago

+1. I'm having exactly the same problem as mwrock has with pester and psake. Any workaround available? Btw, I',m running PS 2.0 on Windows XP.

Ok, I found a workaround for that myself. Don't Invoke-Pester using the default task. Specify a specific task instead and the problem is gone.

scottmuc commented 12 years ago

Ugh, looks like a few of you are really having issues with this. This is top on my list to fix. I've been away from working on Pester lately and would like to get back into it. Thanks for the motivation :-)