Tahir Hassan's Blog

My Technical Notes

Friday, 17 February 2017

MathJax: Selectively ignoring Tags

As per the documentation, use the `tex2jax_ignore` class to make MathJax ignore an element. To make MathJax process an element, use the `tex2jax_process` class, which works even if it has an ignored ancestor element.


<p class="tex2jax_ignore">
    Content in this $paragraph$ is not processed by MathJax, with this exception of <span class="tex2jax_process">$this$</span>.
</p>

Thursday, 16 February 2017

Getting a Web API Working in IIS

1. Set the generated App Pool to be v4 of the .NET Framework.

2. In the Web.config, add the following element inside the `system.webServer` element:


<modules>
    <remove name="UrlRoutingModule-4.0" />
    <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>

Thursday, 9 February 2017

PowerShell: Checking if `-Verbose` switch is specified

You must add the attribute `CmdletBinding` onto your function if you want to take advantage of the `-Verbose` switch.

In order to check if the `-Verbose` switch is specified, use the `$VerbosePreference` variable:


Function Test-Function { 
    [CmdletBinding()] 
    param() 
    
    $VerbosePreference -eq [Management.Automation.ActionPreference]::Continue 
} 

Calling `Test-Function -Verbose` will return `true` and without will return `false`.

`Verbose` is propagated to functions called within the function, therefore, in the following code, `Outer` called with `-Verbose` still returns `true` and `false` without. Therefore we do not have to propagate it ourselves.


Function Outer {
    [CmdletBinding()]
    param()

    Test-Function
}

PowerShell: Checking if `-WhatIf` switch is specified

You must add the attribute `CmdletBinding` with `SupportsShouldProcess` set to `true` onto your function if you want to take advantage of the `-WhatIf` switch.

In order to check if the `-WhatIf` switch is specified, use the `$WhatIfPreference` variable:


Function Test-Function { 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param() 

    [bool]$WhatIfPreference.IsPresent 
}

Calling `Test-Function -WhatIf` will return `true` and without will return `false`.

`WhatIf` is propagated to functions called within the function, therefore, in the following code, `Outer` called with `-WhatIf` still returns `true` and `false` without. Therefore we do not have to propagate it ourselves.


Function Outer {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param()

    Test-Function
}

Wednesday, 8 February 2017

PowerShell: Extremely Basic Unit Testing Module

Below is the code for an extremely basic module that can be used for unit testing. There are two functions defined, `Assert-AreEqual` and `Assert-IsTrue`:


$Script:colorOf = { param($b) if ($b) { 'Green' } else { 'Red' } };
$Script:statusOf = { param($b) if ($b) { 'passed' } else { 'failed' } };

Function Assert-AreEqual {

    param($Expected, $Actual, [string]$Message, [switch]$StopOnFailure)

    Write-Host "$Script:Tahir";

    $passed = $Expected -eq $Actual;
    $color = & $Script:colorOf $passed;
    $status = & $Script:statusOf $passed;

    $writeHost = { param($s) Write-Host $s -ForegroundColor $color; }

    if ($Message) {
        &$writeHost "Assert-AreEqual: [$Message] $status";
    } else {
        &$writeHost "Assert-AreEqual: $status";
    }

    if (-not $passed) {
        &$writeHost "Expected: $Expected";
        &$writeHost "Actual: $Actual";
        &$writeHost "*********************************************";

        if ($StopOnFailure) {
            throw "Assert-AreEqual: $(if ($Message) { "[$Message] " } else { '' } ) stopping on failure";
        }
    }
}

Function Assert-IsTrue {
    param([bool]$Condition, [string]$Message, [switch]$StopOnFailure)

    $color = & $Script:colorOf $Condition;
    $status = & $Script:statusOf $Condition;

    $writeHost = { Write-Host $args[0] -ForegroundColor $color; }

    if ($Message) {
        &$writeHost "Assert-IsTrue: [$Message] $status";
    } else {
        &$writeHost "Assert-IsTrue: $status";
    }

    if (-not $Condition) {
        &$writeHost "*********************************************";

        if ($StopOnFailure) {
            throw "Assert-IsTrue: $(if ($Message) { "[$Message] " } else { '' } ) stopping on failure";
        }
    }
}

Export-ModuleMember Assert-*

You use the module in pretty much the same way as `Assert.AreEqual` and `Assert.IsTrue` are used when unit testing in C#.

For instance, if you expect something will be `true`, use `Assert-IsTrue`. Use the message parameter, so you can keep track of assertions:


Assert-IsTrue $cond "Useful identifying message";

If you want to check the equality of two things, use `Assert-AreEqual`:


Assert-AreEqual $expectedObj $actualObj "Useful identifying message";

PowerShell: Computing `$Confirm` from within a Function

There seems no way of getting the `$Confirm` flag from within a function. Also, it is not as easy as checking `$PSBoundParameters`, because if, for example, function `A` called `B`, but you specified `-Confirm` when calling `A`, then, despite `B` not having had the flag specified, it will work as though you specified the `-Confirm` specified because of how certain special parameters are passed down automatically.

The following `Test-Confirm` function returns a `boolean` value of `Confirm`:


Function Test-Confirm {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] 
    param()
    
    $ConfirmImpact = $MyInvocation.MyCommand.ScriptBlock.Attributes[0].ConfirmImpact
    
    $Confirm = [int]$ConfirmPreference -le [int]$ConfirmImpact
    
    return $Confirm;
}

We can easily test if it successfully returns a valid `Confirm` value by calling it from another function:


Function Outer { 
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] 
    param() 
    
    Test-Confirm 
}

As expected, calling `Outer` with the `-Confirm` flag will return `True` and without it, `False`.

PowerShell: Getting a Function's `ConfirmImpact` from within it

The following `Test-Function` gets the `ConfirmImpact` of a function within itself:


Function Test-Function { 
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] 
    param() 

    $MyInvocation.MyCommand.ScriptBlock.Attributes[0].ConfirmImpact 
}

The only caveat is that the above code assumes that there is only one attribute of type `System.Management.Automation.CmdletBindingAttribute` (or its basetype `CmdletCommonMetadataAttribute` in the same namespace).