Skip to content

Instantly share code, notes, and snippets.

@nohwnd
nohwnd / PSGit.psm1
Created January 26, 2020 10:15
PSGitRoot module
$callStack = Get-PSCallStack
$caller = $callStack[1].ScriptName
$callerDirectory = Split-Path $caller
[string] $PSGitRoot = $null
if ((Get-Command 'git' -ErrorAction Ignore))
{
$workTree = @(git rev-parse --git-path $callerDirectory --is-inside-work-tree)
if (0 -lt $workTree.Count -and 'true' -eq $workTree[-1]) {
$PSGitRoot = Resolve-Path (@(git rev-parse --git-path $callerDirectory --show-toplevel)[-1])
@nohwnd
nohwnd / compound-assertion.tests.ps1
Created December 23, 2019 13:08
Compound assertions example
Describe "In Pester v5 assertions don't fail by default" {
It "is awesome for ensuring a lot of stuff about single object" {
$user = @{
Name = 'Jakub'
Age = 31
Languages = [PSCustomObject]@{
Speaking = 'Czech', 'English'
Programming = @(
'C#'
'PowerShell'
@nohwnd
nohwnd / condition-check.Tests.ps1
Last active September 24, 2019 09:16
Check variable in parent scope, an interesting approach to testing a parent if condition.
Get-Module m | Remove-Module
New-Module -Name m -ScriptBlock {
function Do-Expensive { }
} | Import-Module
function f () {
$variable = 2
# if ($variable -eq 1) {
Do-Expensive
# }
@nohwnd
nohwnd / ModuleName.Tests.ps1
Created September 8, 2019 08:11
Using ModuleName to test public surface of a module
Get-Module Pester, m | Remove-Module
Import-Module Pester -MaximumVersion 4.9.9
New-Module -Name m -ScriptBlock {
function a { "hello" }
function b { a }
Export-ModuleMember -Function b
} | Import-Module
@nohwnd
nohwnd / restore-environment.ps1
Created July 5, 2019 08:45
Automatically clean up changes in env variables after test
# this snippet describes how to automatically clean up
# changes in environment varables
# it can clean up re-writing, adding and removing
# scroll down to see how to use it in real test
Get-Module Pester | Remove-Module
Import-Module Pester -MaximumVersion 4.9.9
function Get-Environment {
$vars = Get-Item Env:\
@nohwnd
nohwnd / dot.ps1
Last active June 27, 2019 15:00
Dot sourcing
Import-Module Pester -MaximumVersion 4.9.9
# use the fact that closures are dynamic modules with
# their own session state, and that scriptblocks are bound
# to the session state that created them, that makes
# the call to `dot` transparent, because the scope
# that the function creates is in a different sessionstate
# and so the `$ScriptBlock` still dot-sources directly into
# the calling session state, just like with the naked `.`
$function:dot = {
@nohwnd
nohwnd / define-variable-in-caller-scope.ps1
Created May 31, 2019 09:39
Define variable in caller scope
# Sets variable $a = 1000 in the local scope from which it was called from, like $matches in regex
Get-Module m | Remove-Module
New-Module m {
function f {
[CmdletBinding()]
param()
$sb = [ScriptBlock]::Create('param($Value); $a = $Value')
$ExecutionContext.InvokeCommand.InvokeScript($PSCmdlet.SessionState, $sb, @(1000))
}
@nohwnd
nohwnd / wpf.ps1
Last active October 9, 2021 20:01
Weird WPF binding in PowerShell
# This example shows three versions of behavior, in the first the data binding only
# picks up the property that is defined on the type, in the second it picks up ever
# powershell adapted property Name (alias property), and in the third it picks up
# all properties even though they are all powershell properties and not on the PSObjectType
# is there some special handling for PSObject regarding WPF in Windows PowerShell?
Add-Type -AssemblyName PresentationFramework
[string]$xaml = @"
@nohwnd
nohwnd / sharing-test-data.ps1
Created March 9, 2019 07:31
Share data among tests safely
# GOOD:
# shares data among tests without polluting
# the script scope
Describe "I share data" {
$container = @{ Value = 1 }
It "I give data" {
$container.Value = 5
}
@nohwnd
nohwnd / Import-Script.psm1
Created February 17, 2019 19:04
Importing self-contained scripts. Demo for PSPowerHour.
function Import-Script {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[String] $Path,
[Hashtable] $Parameters = @{},
[Object[]] $Arguments = @(),
[String] $EntryPoint = 'Main'
)