tests/general/Help.Example.Tests.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
$excludeCommands = @(
    "Import-ModuleFile"
    , "Get-DeepClone"
    , "Test-TrustedConnection"
    , "Select-DefaultView"

)

enum LcsAssetFileType {
    Model = 1
    ProcessDataPackage = 4
    SoftwareDeployablePackage = 10
    GERConfiguration = 12
    DataPackage = 15
    PowerBIReportModel = 19
}

$commandsRaw = Get-Command -Module d365fo.tools

if ($excludeCommands.Count -gt 0) {
    $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch

} else {
    $commands = $commandsRaw
}

foreach ( $commandName in $commands) {
    # command to be tested
    
    # get all examples from the help
    $examples = Get-Help $commandName -Examples

    # make a describe block that will contain tests for this
    Describe "Examples from $commandName" {
        $examples.Examples.Example | foreach {
            # examples have different format,
            # at least the ones I used that MS provided
            # so you need to either standardize them,
            # or provide some hints about what to do
            # such as putting the code first
            # followed by
            # #output: the desired output

            # here I am simply taking the first line and removing 'PS C:\>'
            # which makes some of the tests fail
            $example = $_.Code -replace "`n.*" -replace "PS C:\\>"

            if ( ($example -like "*|*" ) -or (-not ($example -match $commandName)) -or ($example -like "*).*")) {
                It "Example - $example" -Skip { $true }
            } elseif ($example -match '(?<=^(([^"|^'']\*(?<!\\)"[^"|^'']\*(?<!\\)"[^"|^'']\*)\*|[^"|^'']*))=') {
                $varAssignment = ($example -split "=")[0]

                # for every example we want a single It block
                It "Example - $example" {
                    # mock the tested command so we don't actually do anything
                    # because it can be unsafe and we don't have the environment setup
                    # (so the only thing we are testing is that the code is semantically
                    # correct and provides all the needed params)
                    Mock $commandName {
                        # I am returning true here,
                        # but some of the examples drill down to the returned object
                        # so in strict mode we would fail
                        $true
                    }

                    $exampleExtended = "$example;$varAssignment"
                    
                    # here simply invoke the example
                    $result = Invoke-Expression $exampleExtended
                    # and check that we got result from the mock
                    $result | Should -BeTrue
                }
            } else {
                # for every example we want a single It block
                It "Example - $example" {
                    # mock the tested command so we don't actually do anything
                    # because it can be unsafe and we don't have the environment setup
                    # (so the only thing we are testing is that the code is semantically
                    # correct and provides all the needed params)
                    Mock $commandName {
                        # I am returning true here,
                        # but some of the examples drill down to the returned object
                        # so in strict mode we would fail
                        $true
                    }

                    # here simply invoke the example
                    $result = Invoke-Expression $example
                    # and check that we got result from the mock
                    $result | Should -BeTrue
                }
            }
        }
    }
}