Implement tests for software-report-module (#6815)

* Minor improvements

* fix typos

* fix brew rendering

* add temp test

* Implement tests

* Add arguments validation

* ToMarkdown()

* Use before-All and helpers

* Get rid of arrays

* Add validation, no new nodes after header

* Fix naming

* add workflow

* Revisit comments + tiny improvements

* Fix tables

* Fix html table indent

* remove comment

* attemp to break test - testing CI

* revert breaking test

* fix nitpicks
This commit is contained in:
Maxim Lobanov
2022-12-21 10:58:27 +01:00
committed by GitHub
parent bc38aa4173
commit 4aeccc7b5b
16 changed files with 2597 additions and 430 deletions

View File

@@ -0,0 +1,525 @@
using module ../SoftwareReport.psm1
using module ../SoftwareReport.DifferenceCalculator.psm1
Describe "Comparer.E2E" {
It "Some tools are updated" {
# Previous report
$prevSoftwareReport = [SoftwareReport]::new("macOS 11")
$prevSoftwareReport.Root.AddToolVersion("OS Version:", "macOS 11.7.1 (20G817)")
$prevSoftwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$prevInstalledSoftware = $prevSoftwareReport.Root.AddHeader("Installed Software")
$prevTools = $prevInstalledSoftware.AddHeader("Tools")
$prevTools.AddToolVersion("ToolWillBeUpdated1", "1.0.0")
$prevTools.AddToolVersion("ToolWillBeUpdated2", "3.0.1")
$prevTools.AddToolVersionsList("ToolWillBeUpdated3", @("14.0.0", "15.5.1"), "^\d+")
# Next report
$nextSoftwareReport = [SoftwareReport]::new("macOS 11")
$nextSoftwareReport.Root.AddToolVersion("OS Version:", "macOS 11.7.1 (20G817)")
$nextSoftwareReport.Root.AddToolVersion("Image Version:", "20220922.1")
$nextInstalledSoftware = $nextSoftwareReport.Root.AddHeader("Installed Software")
$nextTools = $nextInstalledSoftware.AddHeader("Tools")
$nextTools.AddToolVersion("ToolWillBeUpdated1", "2.5.0")
$nextTools.AddToolVersion("ToolWillBeUpdated2", "3.0.2")
$nextTools.AddToolVersionsList("ToolWillBeUpdated3", @("14.2.0", "15.5.1"), "^\d+")
# Compare reports
$comparer = [SoftwareReportDifferenceCalculator]::new($prevSoftwareReport, $nextSoftwareReport)
$comparer.CompareReports()
$comparer.GetMarkdownReport() | Should -BeExactly @'
# :desktop_computer: Actions Runner Image: macOS 11
- OS Version: macOS 11.7.1 (20G817)
- Image Version: 20220922.1
## :mega: What's changed?
### Updated
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Previous (20220918.1)</th>
<th>Current (20220922.1)</th>
</thead>
<tbody>
<tr>
<td rowspan="3">Tools</td>
<td>ToolWillBeUpdated1</td>
<td>1.0.0</td>
<td>2.5.0</td>
</tr>
<tr>
<td>ToolWillBeUpdated2</td>
<td>3.0.1</td>
<td>3.0.2</td>
</tr>
<tr>
<td>ToolWillBeUpdated3</td>
<td>14.0.0</td>
<td>14.2.0</td>
</tr>
</tbody>
</table>
'@
}
It "Some tools are updated, added and removed" {
# Previous report
$prevSoftwareReport = [SoftwareReport]::new("macOS 11")
$prevSoftwareReport.Root.AddToolVersion("OS Version:", "macOS 11.7.1 (20G817)")
$prevSoftwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$prevInstalledSoftware = $prevSoftwareReport.Root.AddHeader("Installed Software")
$prevLanguagesAndRuntimes = $prevInstalledSoftware.AddHeader("Language and Runtime")
$prevLanguagesAndRuntimes.AddToolVersion("ToolWillBeRemoved", "5.1.16(1)-release")
$prevLanguagesAndRuntimes.AddToolVersionsListInline("ToolWithMultipleVersions3", @("1.2.100", "1.2.200", "1.3.500", "1.4.100", "1.4.200"), "^\d+\.\d+\.\d")
$prevLanguagesAndRuntimes.AddToolVersion("ToolWithoutChanges", "5.34.0")
$prevLanguagesAndRuntimes.AddToolVersion("ToolWillBeUpdated", "8.1.0")
$prevCachedTools = $prevInstalledSoftware.AddHeader("Cached Tools")
$prevCachedTools.AddToolVersionsList("ToolWithMultipleVersions1", @("2.7.3", "2.8.1", "3.1.2"), "^\d+\.\d+")
$prevCachedTools.AddToolVersionsList("ToolWithMultipleVersions2", @("14.8.0", "15.1.0", "16.4.2"), "^\d+")
$prevSQLSection = $prevInstalledSoftware.AddHeader("Databases")
$prevSQLSection.AddToolVersion("MineSQL", "6.1.0")
$prevSQLSection.AddNote("First Note")
# Next report
$nextSoftwareReport = [SoftwareReport]::new("macOS 11")
$nextSoftwareReport.Root.AddToolVersion("OS Version:", "macOS 11.7.2 (20G922)")
$nextSoftwareReport.Root.AddToolVersion("Image Version:", "20220922.0")
$nextInstalledSoftware = $nextSoftwareReport.Root.AddHeader("Installed Software")
$nextLanguagesAndRuntimes = $nextInstalledSoftware.AddHeader("Language and Runtime")
$nextLanguagesAndRuntimes.AddToolVersion("ToolWillBeAdded", "16.18.0")
$nextLanguagesAndRuntimes.AddToolVersionsListInline("ToolWithMultipleVersions3", @("1.2.200", "1.3.515", "1.4.100", "1.4.200", "1.5.800"), "^\d+\.\d+\.\d")
$nextLanguagesAndRuntimes.AddToolVersion("ToolWithoutChanges", "5.34.0")
$nextLanguagesAndRuntimes.AddToolVersion("ToolWillBeUpdated", "8.3.0")
$nextCachedTools = $nextInstalledSoftware.AddHeader("Cached Tools")
$nextCachedTools.AddToolVersionsList("ToolWithMultipleVersions1", @("2.7.3", "2.8.1", "3.1.2"), "^\d+\.\d+")
$nextCachedTools.AddToolVersionsList("ToolWithMultipleVersions2", @("15.1.0", "16.4.2", "17.0.1"), "^\d+")
$nextSQLSection = $nextInstalledSoftware.AddHeader("Databases")
$nextSQLSection.AddToolVersion("MineSQL", "6.1.1")
$nextSQLSection.AddNote("Second Note")
# Compare reports
$comparer = [SoftwareReportDifferenceCalculator]::new($prevSoftwareReport, $nextSoftwareReport)
$comparer.CompareReports()
$comparer.GetMarkdownReport() | Should -BeExactly @'
# :desktop_computer: Actions Runner Image: macOS 11
- OS Version: macOS 11.7.2 (20G922)
- Image Version: 20220922.0
## :mega: What's changed?
### Added :heavy_plus_sign:
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Current (20220922.0)</th>
</thead>
<tbody>
<tr>
<td rowspan="2">Language and Runtime</td>
<td>ToolWillBeAdded</td>
<td>16.18.0</td>
</tr>
<tr>
<td>ToolWithMultipleVersions3</td>
<td>1.5.800</td>
</tr>
<tr>
<td rowspan="1">Cached Tools</td>
<td>ToolWithMultipleVersions2</td>
<td>17.0.1</td>
</tr>
</tbody>
</table>
### Deleted :heavy_minus_sign:
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Previous (20220918.1)</th>
</thead>
<tbody>
<tr>
<td rowspan="2">Language and Runtime</td>
<td>ToolWithMultipleVersions3</td>
<td>1.2.100</td>
</tr>
<tr>
<td>ToolWillBeRemoved</td>
<td>5.1.16(1)-release</td>
</tr>
<tr>
<td rowspan="1">Cached Tools</td>
<td>ToolWithMultipleVersions2</td>
<td>14.8.0</td>
</tr>
</tbody>
</table>
### Updated
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Previous (20220918.1)</th>
<th>Current (20220922.0)</th>
</thead>
<tbody>
<tr>
<td rowspan="1"></td>
<td>OS Version</td>
<td>macOS 11.7.1 (20G817)</td>
<td>macOS 11.7.2 (20G922)</td>
</tr>
<tr>
<td rowspan="2">Language and Runtime</td>
<td>ToolWithMultipleVersions3</td>
<td>1.3.500</td>
<td>1.3.515</td>
</tr>
<tr>
<td>ToolWillBeUpdated</td>
<td>8.1.0</td>
<td>8.3.0</td>
</tr>
<tr>
<td rowspan="1">Databases</td>
<td>MineSQL</td>
<td>6.1.0</td>
<td>6.1.1</td>
</tr>
</tbody>
</table>
'@
}
It "Header tree changes" {
# Previous report
$prevSoftwareReport = [SoftwareReport]::new("macOS 11")
$prevSoftwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$prevInstalledSoftware = $prevSoftwareReport.Root.AddHeader("Installed Software")
$prevInstalledSoftware.AddToolVersion("ToolWithoutChanges", "5.34.0")
$prevInstalledSoftware.AddHeader("HeaderWillBeRemoved").AddHeader("SubheaderWillBeRemoved").AddToolVersion("ToolWillBeRemoved", "1.0.0")
$prevInstalledSoftware.AddHeader("Header1").AddToolVersion("ToolWillBeMovedToAnotherHeader", "3.0.0")
# Next report
$nextSoftwareReport = [SoftwareReport]::new("macOS 11")
$nextSoftwareReport.Root.AddToolVersion("Image Version:", "20220922.0")
$nextInstalledSoftware = $nextSoftwareReport.Root.AddHeader("Installed Software")
$nextInstalledSoftware.AddToolVersion("ToolWithoutChanges", "5.34.0")
$nextInstalledSoftware.AddHeader("HeaderWillBeAdded").AddHeader("SubheaderWillBeAdded").AddToolVersion("ToolWillBeAdded", "5.0.0")
$nextInstalledSoftware.AddHeader("Header2").AddToolVersion("ToolWillBeMovedToAnotherHeader", "3.0.0")
# Compare reports
$comparer = [SoftwareReportDifferenceCalculator]::new($prevSoftwareReport, $nextSoftwareReport)
$comparer.CompareReports()
$comparer.GetMarkdownReport() | Should -BeExactly @'
# :desktop_computer: Actions Runner Image: macOS 11
- Image Version: 20220922.0
## :mega: What's changed?
### Added :heavy_plus_sign:
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Current (20220922.0)</th>
</thead>
<tbody>
<tr>
<td rowspan="1">HeaderWillBeAdded ><br> SubheaderWillBeAdded</td>
<td>ToolWillBeAdded</td>
<td>5.0.0</td>
</tr>
<tr>
<td rowspan="1">Header2</td>
<td>ToolWillBeMovedToAnotherHeader</td>
<td>3.0.0</td>
</tr>
</tbody>
</table>
### Deleted :heavy_minus_sign:
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Previous (20220918.1)</th>
</thead>
<tbody>
<tr>
<td rowspan="1">HeaderWillBeRemoved ><br> SubheaderWillBeRemoved</td>
<td>ToolWillBeRemoved</td>
<td>1.0.0</td>
</tr>
<tr>
<td rowspan="1">Header1</td>
<td>ToolWillBeMovedToAnotherHeader</td>
<td>3.0.0</td>
</tr>
</tbody>
</table>
'@
}
It "Tables are added and removed" {
# Previous report
$prevSoftwareReport = [SoftwareReport]::new("macOS 11")
$prevSoftwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$prevInstalledSoftware = $prevSoftwareReport.Root.AddHeader("Installed Software")
$prevInstalledSoftware.AddHeader("HeaderWillExist").AddTable(@(
[PSCustomObject]@{TableInExistingHeaderWillBeRemoved = "Q"; Value = "25"},
[PSCustomObject]@{TableInExistingHeaderWillBeRemoved = "O"; Value = "24"}
))
$prevTools = $prevInstalledSoftware.AddHeader("Tools")
$prevTools.AddHeader("HeaderWillBeRemoved").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "Z"; Value = "30"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "W"; Value = "29"}
))
# Next report
$nextSoftwareReport = [SoftwareReport]::new("macOS 11")
$nextSoftwareReport.Root.AddToolVersion("Image Version:", "20220922.1")
$nextInstalledSoftware = $nextSoftwareReport.Root.AddHeader("Installed Software")
$nextInstalledSoftware.AddHeader("HeaderWillExist")
$nextTools = $nextInstalledSoftware.AddHeader("Tools")
$nextTools.AddToolVersion("ToolWillBeAdded", "3.0.1")
$nextTools.AddTable(@(
[PSCustomObject]@{NewTableInExistingHeader = "A"; Value = "1"},
[PSCustomObject]@{NewTableInExistingHeader = "B"; Value = "2"}
))
$nextTools.AddHeader("NewHeaderWithTable").AddTable(@(
[PSCustomObject]@{NewTableInNewHeader = "C"; Value = "3"},
[PSCustomObject]@{NewTableInNewHeader = "D"; Value = "4"}
))
# Compare reports
$comparer = [SoftwareReportDifferenceCalculator]::new($prevSoftwareReport, $nextSoftwareReport)
$comparer.CompareReports()
$comparer.GetMarkdownReport() | Should -BeExactly @'
# :desktop_computer: Actions Runner Image: macOS 11
- Image Version: 20220922.1
## :mega: What's changed?
### Added :heavy_plus_sign:
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Current (20220922.1)</th>
</thead>
<tbody>
<tr>
<td rowspan="1">Tools</td>
<td>ToolWillBeAdded</td>
<td>3.0.1</td>
</tr>
</tbody>
</table>
#### Tools
| NewTableInExistingHeader | Value |
| ------------------------ | ----- |
| A | 1 |
| B | 2 |
#### Tools > NewHeaderWithTable
| NewTableInNewHeader | Value |
| ------------------- | ----- |
| C | 3 |
| D | 4 |
### Deleted :heavy_minus_sign:
#### HeaderWillExist
| TableInExistingHeaderWillBeRemoved | Value |
| ---------------------------------- | ------ |
| ~~Q~~ | ~~25~~ |
| ~~O~~ | ~~24~~ |
#### Tools > HeaderWillBeRemoved
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ------ |
| ~~Z~~ | ~~30~~ |
| ~~W~~ | ~~29~~ |
'@
}
It "Tables are changed" {
# Previous report
$prevSoftwareReport = [SoftwareReport]::new("macOS 11")
$prevSoftwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$prevInstalledSoftware = $prevSoftwareReport.Root.AddHeader("Installed Software")
$prevTools = $prevInstalledSoftware.AddHeader("Tools")
$prevTools.AddHeader("TableWithAddedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "AA"; Value = "10"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "AB"; Value = "11"}
))
$prevTools.AddHeader("TableWithRemovedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "BA"; Value = "32"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "BB"; Value = "33"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "BC"; Value = "34"}
))
$prevTools.AddHeader("TableWithUpdatedRow").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CA"; Value = "42"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CB"; Value = "43"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CC"; Value = "44"}
))
$prevTools.AddHeader("TableWithUpdatedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DA"; Value = "50"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DB"; Value = "51"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DC"; Value = "52"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DD"; Value = "53"}
))
$prevTools.AddHeader("TableWithComplexChanges").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EA"; Value = "62"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EB"; Value = "63"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EC"; Value = "64"}
[PSCustomObject]@{TableWillBeRemovedWithHeader = "ED"; Value = "65"}
))
$prevTools.AddHeader("TableWithOnlyHeaderChanged").AddTable(@(
[PSCustomObject]@{TableWithOnlyHeaderChanged = "FA"; Value = "72"},
[PSCustomObject]@{TableWithOnlyHeaderChanged = "FB"; Value = "73"}
))
$prevTools.AddHeader("TableWithHeaderAndRowsChanges").AddTable(@(
[PSCustomObject]@{TableWithHeaderAndRowsChanges = "GA"; Value = "82"},
[PSCustomObject]@{TableWithHeaderAndRowsChanges = "GB"; Value = "83"},
[PSCustomObject]@{TableWithHeaderAndRowsChanges = "GC"; Value = "84"}
))
# Next report
$nextSoftwareReport = [SoftwareReport]::new("macOS 11")
$nextSoftwareReport.Root.AddToolVersion("Image Version:", "20220922.1")
$nextInstalledSoftware = $nextSoftwareReport.Root.AddHeader("Installed Software")
$nextTools = $nextInstalledSoftware.AddHeader("Tools")
$nextTools.AddHeader("TableWithAddedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "AA"; Value = "10"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "AB"; Value = "11"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "AC"; Value = "12"}
))
$nextTools.AddHeader("TableWithRemovedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "BB"; Value = "33"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "BC"; Value = "34"}
))
$nextTools.AddHeader("TableWithUpdatedRow").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CA"; Value = "42"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CB"; Value = "500"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "CC"; Value = "44"}
))
$nextTools.AddHeader("TableWithUpdatedRows").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DA"; Value = "50"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DB"; Value = "5100"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DC"; Value = "5200"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "DD"; Value = "53"}
))
$nextTools.AddHeader("TableWithComplexChanges").AddTable(@(
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EB"; Value = "63"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EC"; Value = "640"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "ED"; Value = "65"},
[PSCustomObject]@{TableWillBeRemovedWithHeader = "EE"; Value = "66"}
))
$nextTools.AddHeader("TableWithOnlyHeaderChanged").AddTable(@(
[PSCustomObject]@{TableWithOnlyHeaderChanged2 = "FA"; Value = "72"},
[PSCustomObject]@{TableWithOnlyHeaderChanged2 = "FB"; Value = "73"}
))
$nextTools.AddHeader("TableWithHeaderAndRowsChanges").AddTable(@(
[PSCustomObject]@{TableWithHeaderAndRowsChanges2 = "GA"; Value = "82"},
[PSCustomObject]@{TableWithHeaderAndRowsChanges2 = "GE"; Value = "850"},
[PSCustomObject]@{TableWithHeaderAndRowsChanges2 = "GC"; Value = "840"}
))
# Compare reports
$comparer = [SoftwareReportDifferenceCalculator]::new($prevSoftwareReport, $nextSoftwareReport)
$comparer.CompareReports()
$comparer.GetMarkdownReport() | Should -BeExactly @'
# :desktop_computer: Actions Runner Image: macOS 11
- Image Version: 20220922.1
## :mega: What's changed?
### Added :heavy_plus_sign:
#### Tools > TableWithAddedRows
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ----- |
| AC | 12 |
#### Tools > TableWithHeaderAndRowsChanges
| TableWithHeaderAndRowsChanges2 | Value |
| ------------------------------ | ----- |
| GA | 82 |
| GE | 850 |
| GC | 840 |
### Deleted :heavy_minus_sign:
#### Tools > TableWithRemovedRows
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ------ |
| ~~BA~~ | ~~32~~ |
#### Tools > TableWithHeaderAndRowsChanges
| TableWithHeaderAndRowsChanges | Value |
| ----------------------------- | ------ |
| ~~GA~~ | ~~82~~ |
| ~~GB~~ | ~~83~~ |
| ~~GC~~ | ~~84~~ |
### Updated
#### Tools > TableWithUpdatedRow
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ------ |
| ~~CB~~ | ~~43~~ |
| CB | 500 |
#### Tools > TableWithUpdatedRows
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ------ |
| ~~DB~~ | ~~51~~ |
| ~~DC~~ | ~~52~~ |
| DB | 5100 |
| DC | 5200 |
#### Tools > TableWithComplexChanges
| TableWillBeRemovedWithHeader | Value |
| ---------------------------- | ------ |
| ~~EA~~ | ~~62~~ |
| ~~EC~~ | ~~64~~ |
| EC | 640 |
| EE | 66 |
'@
}
}

View File

@@ -0,0 +1,603 @@
using module ../SoftwareReport.Nodes.psm1
using module ../SoftwareReport.DifferenceCalculator.psm1
BeforeDiscovery {
Import-Module $(Join-Path $PSScriptRoot "TestHelpers.psm1") -DisableNameChecking
}
Describe "Comparer.UnitTests" {
Describe "Headers Tree" {
It "Add Node to existing header" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersion("MyTool1", "2.1.3")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Version | Should -Be "2.1.3"
$comparer.AddedItems[0].Headers | Should -BeArray @("MyHeader")
}
It "Add new header with Node" {
$prevReport = [HeaderNode]::new("Version 1")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddHeader("MySubHeader").AddToolVersion("MyTool1", "2.1.3")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Version | Should -Be "2.1.3"
$comparer.AddedItems[0].Headers | Should -BeArray @("MyHeader", "MySubHeader")
}
It "Remove Node from existing header" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
$comparer.DeletedItems[0].Headers | Should -BeArray @("MyHeader")
}
It "Remove header with Node" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
$comparer.DeletedItems[0].Headers | Should -BeArray @("MyHeader", "MySubheader")
}
It "Node with minor changes" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.4")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Version | Should -Be "2.1.4"
$comparer.ChangedItems[0].Headers | Should -BeArray @("MyHeader", "MySubHeader")
}
It "Node without changes" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.3")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
}
It "Node is moved to different header" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddHeader("MySubheader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddHeader("MySubheader2").AddToolVersion("MyTool1", "2.1.3")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Version | Should -Be "2.1.3"
$comparer.AddedItems[0].Headers | Should -BeArray @("MyHeader", "MySubheader2")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
$comparer.DeletedItems[0].Headers | Should -BeArray @("MyHeader", "MySubheader")
}
It "Complex structure" {
$prevReport = [HeaderNode]::new("Version 1")
$prevSubHeader = $prevReport.AddHeader("MyHeader").AddHeader("MySubheader")
$prevSubHeader.AddToolVersion("MyTool1", "2.1.3")
$prevSubHeader.AddHeader("MySubSubheader").AddToolVersion("MyTool2", "2.9.1")
$prevReport.AddHeader("MyHeader2")
$prevReport.AddHeader("MyHeader3").AddHeader("MySubheader3").AddToolVersion("MyTool3", "14.2.1")
$nextReport = [HeaderNode]::new("Version 2")
$nextSubHeader = $nextReport.AddHeader("MyHeader").AddHeader("MySubheader")
$nextSubHeader.AddToolVersion("MyTool1", "2.1.4")
$nextSubSubHeader = $nextSubHeader.AddHeader("MySubSubheader")
$nextSubSubHeader.AddToolVersion("MyTool2", "2.9.1")
$nextSubSubHeader.AddToolVersion("MyTool4", "2.7.6")
$nextReport.AddHeader("MyHeader2")
$nextReport.AddHeader("MyHeader3")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool4"
$comparer.AddedItems[0].CurrentReportNode.Version | Should -Be "2.7.6"
$comparer.AddedItems[0].Headers | Should -BeArray @("MyHeader", "MySubheader", "MySubSubheader")
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Version | Should -Be "2.1.4"
$comparer.ChangedItems[0].Headers | Should -BeArray @("MyHeader", "MySubheader")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool3"
$comparer.DeletedItems[0].PreviousReportNode.Version | Should -Be "14.2.1"
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
$comparer.DeletedItems[0].Headers | Should -BeArray @("MyHeader3", "MySubheader3")
}
}
Describe "ToolVersionNode" {
It "ToolVersionNode is updated" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersion("MyTool1", "2.1.3")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersion("MyTool1", "2.1.4")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Version | Should -Be "2.1.3"
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Version | Should -Be "2.1.4"
$comparer.ChangedItems[0].Headers | Should -BeArray @("MyHeader")
}
}
Describe "ToolVersionsListNode" {
It "Single version is not changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3"), "^.+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3"), "^.+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
}
It "Single version is changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3"), "^\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.4"), "^\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Versions | Should -BeArray @("2.1.3")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Versions | Should -BeArray @("2.1.4")
}
It "Major version is added" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3"), "^\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3", "3.1.4"), "^\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Versions | Should -BeArray @("3.1.4")
}
It "Major version is removed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3", "3.1.4"), "^\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("3.1.4"), "^\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Versions | Should -BeArray @("2.1.3")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
}
It "Major version is changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("3.1.4"), "^\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("3.2.0"), "^\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Versions | Should -BeArray @("3.1.4")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Versions | Should -BeArray @("3.2.0")
}
It "Major version is added, removed and updated at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("1.0.0", "2.1.3", "3.1.4", "4.0.2"), "^\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.1.3", "3.2.0", "4.0.2", "5.1.0"), "^\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Versions | Should -BeArray @("5.1.0")
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Versions | Should -BeArray @("3.1.4")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Versions | Should -BeArray @("3.2.0")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Versions | Should -BeArray @("1.0.0")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
}
It "Minor version is added, removed and updated at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.3.8", "2.4.9", "2.5.3", "2.6.0", "2.7.4", "2.8.0"), "^\d+\.\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.5.3", "2.6.2", "2.7.5", "2.8.0", "2.9.2", "2.10.3"), "^\d+\.\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Versions | Should -BeArray @("2.9.2", "2.10.3")
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].PreviousReportNode.Versions | Should -BeArray @("2.6.0", "2.7.4")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.ChangedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.ChangedItems[0].CurrentReportNode.Versions | Should -BeArray @("2.6.2", "2.7.5")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Versions | Should -BeArray @("2.3.8", "2.4.9")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
}
It "Patch version is added, removed and updated at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.3.8", "2.4.9", "2.5.3", "2.6.0", "2.7.4"), "^\d+\.\d+\.\d+")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddToolVersionsList("MyTool1", @("2.4.9", "2.5.4", "2.6.0", "2.7.5", "2.8.2"), "^\d+\.\d+\.\d+")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.AddedItems[0].CurrentReportNode.ToolName | Should -Be "MyTool1"
$comparer.AddedItems[0].CurrentReportNode.Versions | Should -BeArray @("2.5.4", "2.7.5", "2.8.2")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([ToolVersionsListNode])
$comparer.DeletedItems[0].PreviousReportNode.ToolName | Should -Be "MyTool1"
$comparer.DeletedItems[0].PreviousReportNode.Versions | Should -BeArray @("2.3.8", "2.5.3", "2.7.4")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
}
}
Describe "TableNode" {
It "Rows are added" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2", "C1|C2", "D1|D2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
$comparer.AddedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.AddedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.AddedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2")
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.AddedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value"
$comparer.AddedItems[0].CurrentReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2", "C1|C2", "D1|D2")
}
It "Rows are deleted" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2", "C1|C2", "D1|D2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("C1|C2", "D1|D2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.DeletedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.DeletedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2", "C1|C2", "D1|D2")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.DeletedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value"
$comparer.DeletedItems[0].CurrentReportNode.Rows | Should -BeArray @("C1|C2", "D1|D2")
}
It "Rows are changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B3|B4")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].CurrentReportNode.Rows | Should -BeArray @("A1|A2", "B3|B4")
}
It "Rows are changed and updated at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B3|B4", "C1|C2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].CurrentReportNode.Rows | Should -BeArray @("A1|A2", "B3|B4", "C1|C2")
}
It "Rows are changed and removed at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2", "C1|C2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B3|B4")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 1
$comparer.DeletedItems | Should -HaveCount 0
$comparer.ChangedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2", "C1|C2")
$comparer.ChangedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.ChangedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value"
$comparer.ChangedItems[0].CurrentReportNode.Rows | Should -BeArray @("A1|A2", "B3|B4")
}
It "Rows are not changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
}
It "Rows are not changed but header is changed" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value2", @("A1|A2", "B1|B2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
}
It "Rows are changed and header is changed at the same time" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value", @("A1|A2", "B1|B2")))
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddHeader("MyHeader").AddNode([TableNode]::new("Name|Value2", @("A1|A2", "B1|B2", "C1|C2")))
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 1
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 1
$comparer.AddedItems[0].PreviousReportNode | Should -BeNullOrEmpty
$comparer.AddedItems[0].CurrentReportNode | Should -BeOfType ([TableNode])
$comparer.AddedItems[0].CurrentReportNode.Headers | Should -Be "Name|Value2"
$comparer.AddedItems[0].CurrentReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2", "C1|C2")
$comparer.DeletedItems[0].PreviousReportNode | Should -BeOfType ([TableNode])
$comparer.DeletedItems[0].PreviousReportNode.Headers | Should -Be "Name|Value"
$comparer.DeletedItems[0].PreviousReportNode.Rows | Should -BeArray @("A1|A2", "B1|B2")
$comparer.DeletedItems[0].CurrentReportNode | Should -BeNullOrEmpty
}
}
Describe "NoteNode" {
It "NoteNode is ignored from report" {
$prevReport = [HeaderNode]::new("Version 1")
$prevReport.AddNote("MyFirstNote")
$prevReport.AddHeader("MyFirstHeader").AddNote("MyFirstSubNote")
$nextReport = [HeaderNode]::new("Version 2")
$nextReport.AddNote("MySecondNote")
$nextReport.AddHeader("MySecondHeader").AddNote("MySecondSubNote")
$comparer = [SoftwareReportDifferenceCalculator]::new($prevReport, $nextReport)
$comparer.CompareReports()
$comparer.AddedItems | Should -HaveCount 0
$comparer.ChangedItems | Should -HaveCount 0
$comparer.DeletedItems | Should -HaveCount 0
}
}
}

View File

@@ -0,0 +1,291 @@
using module ../SoftwareReport.Nodes.psm1
using module ../SoftwareReport.DifferenceRender.psm1
BeforeDiscovery {
Import-Module $(Join-Path $PSScriptRoot "TestHelpers.psm1") -DisableNameChecking
}
Describe "ComparerReport.UnitTests" {
BeforeAll {
$script:DifferenceRender = [SoftwareReportDifferenceRender]::new()
}
Context "CalculateHtmlTableRowSpan" {
It "Without the equal cells" {
$table = @(
[PSCustomObject]@{ Key = "A"; Value = "1" }
[PSCustomObject]@{ Key = "B"; Value = "2" }
[PSCustomObject]@{ Key = "C"; Value = "3" }
)
$actual = $DifferenceRender.CalculateHtmlTableRowSpan($table, "Key")
$actual | Should -BeArray @(1, 1, 1)
}
It "Only equal cells" {
$table = @(
[PSCustomObject]@{ Key = "A"; Value = "D" }
[PSCustomObject]@{ Key = "B"; Value = "D" }
[PSCustomObject]@{ Key = "C"; Value = "D" }
)
$actual = $DifferenceRender.CalculateHtmlTableRowSpan($table, "Value")
$actual | Should -BeArray @(3, 0, 0)
}
It "Single row" {
$table = @(
[PSCustomObject]@{ Key = "A"; Value = "1" }
)
$actual = $DifferenceRender.CalculateHtmlTableRowSpan($table, "Key")
$actual | Should -BeArray @(1)
}
It "Different cells" {
$table = @(
[PSCustomObject]@{ Key = "A"; Value = "1" }
[PSCustomObject]@{ Key = "B"; Value = "2" }
[PSCustomObject]@{ Key = "B"; Value = "3" }
[PSCustomObject]@{ Key = "C"; Value = "4" }
[PSCustomObject]@{ Key = "C"; Value = "5" }
[PSCustomObject]@{ Key = "C"; Value = "6" }
[PSCustomObject]@{ Key = "D"; Value = "7" }
[PSCustomObject]@{ Key = "E"; Value = "8" }
[PSCustomObject]@{ Key = "E"; Value = "9" }
[PSCustomObject]@{ Key = "F"; Value = "10" }
)
$actual = $DifferenceRender.CalculateHtmlTableRowSpan($table, "Key")
$actual | Should -BeArray @(1, 2, 0, 3, 0, 0, 1, 2, 0, 1)
}
}
Context "RenderCategory" {
It "With line separator" {
$actual = $DifferenceRender.RenderCategory(@("Header 1", "Header 2", "Header 3"), $true)
$actual | Should -Be "Header 2 ><br> Header 3"
}
It "Without line separator" {
$actual = $DifferenceRender.RenderCategory(@("Header 1", "Header 2", "Header 3"), $false)
$actual | Should -Be "Header 2 > Header 3"
}
It "One header" {
$actual = $DifferenceRender.RenderCategory(@("Header 1"), $false)
$actual | Should -Be ""
}
It "Empty headers" {
$actual = $DifferenceRender.RenderCategory(@(), $false)
$actual | Should -Be ""
}
}
Context "RenderToolName" {
It "Clear tool name" {
$actual = $DifferenceRender.RenderToolName("My Tool 1")
$actual | Should -Be "My Tool 1"
}
It "Name with colon symbol" {
$actual = $DifferenceRender.RenderToolName("My Tool 1:")
$actual | Should -Be "My Tool 1"
}
}
Context "StrikeTableRow" {
It "Simple row" {
$actual = $DifferenceRender.StrikeTableRow("Test1|Test2|Test3")
$actual | Should -Be "~~Test1~~|~~Test2~~|~~Test3~~"
}
It "Row with spaces" {
$actual = $DifferenceRender.StrikeTableRow("Test 1|Test 2|Test 3")
$actual | Should -Be "~~Test 1~~|~~Test 2~~|~~Test 3~~"
}
}
Context "RenderHtmlTable" {
It "Simple table" {
$table = @(
[PSCustomObject]@{ "Category" = "A"; "Tool name" = "My Tool 1"; "Version" = "1.0" },
[PSCustomObject]@{ "Category" = "B"; "Tool name" = "My Tool 2"; "Version" = "2.0" },
[PSCustomObject]@{ "Category" = "C"; "Tool name" = "My Tool 3"; "Version" = "3.0" }
)
$renderedTable = $DifferenceRender.RenderHtmlTable($table, "Category")
$renderedTable | Should -Be @'
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Version</th>
</thead>
<tbody>
<tr>
<td rowspan="1">A</td>
<td>My Tool 1</td>
<td>1.0</td>
</tr>
<tr>
<td rowspan="1">B</td>
<td>My Tool 2</td>
<td>2.0</td>
</tr>
<tr>
<td rowspan="1">C</td>
<td>My Tool 3</td>
<td>3.0</td>
</tr>
</tbody>
</table>
'@
}
It "Table with the same category" {
$table = @(
[PSCustomObject]@{ "Category" = "A"; "Tool name" = "My Tool 1"; "Version" = "1.0" },
[PSCustomObject]@{ "Category" = "A"; "Tool name" = "My Tool 2"; "Version" = "2.0" },
[PSCustomObject]@{ "Category" = "A"; "Tool name" = "My Tool 3"; "Version" = "3.0" },
[PSCustomObject]@{ "Category" = "B"; "Tool name" = "My Tool 4"; "Version" = "4.0" }
)
$renderedTable = $DifferenceRender.RenderHtmlTable($table, "Category")
$renderedTable | Should -Be @'
<table>
<thead>
<th>Category</th>
<th>Tool name</th>
<th>Version</th>
</thead>
<tbody>
<tr>
<td rowspan="3">A</td>
<td>My Tool 1</td>
<td>1.0</td>
</tr>
<tr>
<td>My Tool 2</td>
<td>2.0</td>
</tr>
<tr>
<td>My Tool 3</td>
<td>3.0</td>
</tr>
<tr>
<td rowspan="1">B</td>
<td>My Tool 4</td>
<td>4.0</td>
</tr>
</tbody>
</table>
'@
}
}
Context "RenderTableNodesDiff" {
It "Add new table" {
$previousNode = $null
$currentNode = [TableNode]::new("Name|Value", @("A|1", "B|2"))
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ---- | ----- |
| A | 1 |
| B | 2 |
'@
}
It "Remove existing table" {
$previousNode = [TableNode]::new("Name|Value", @("A|1", "B|2"))
$currentNode = $null
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ----- | ----- |
| ~~A~~ | ~~1~~ |
| ~~B~~ | ~~2~~ |
'@
}
It "Add new rows to existing table" {
$previousNode = [TableNode]::new("Name|Value", @("A|1", "B|2"))
$currentNode = [TableNode]::new("Name|Value", @("A|1", "B|2", "C|3", "D|4"))
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ---- | ----- |
| C | 3 |
| D | 4 |
'@
}
It "Remove rows from existing table" {
$previousNode = [TableNode]::new("Name|Value", @("A|1", "B|2", "C|3", "D|4"))
$currentNode = [TableNode]::new("Name|Value", @("C|3", "D|4"))
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ----- | ----- |
| ~~A~~ | ~~1~~ |
| ~~B~~ | ~~2~~ |
'@
}
It "Row is changed in existing table" {
$previousNode = [TableNode]::new("Name|Value", @("A|1", "B|2"))
$currentNode = [TableNode]::new("Name|Value", @("A|1", "B|3"))
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ----- | ----- |
| ~~B~~ | ~~2~~ |
| B | 3 |
'@
}
It "Row is changed, added and removed at the same time in existing table" {
$previousNode = [TableNode]::new("Name|Value", @("A|1", "B|2", "C|3", "D|4"))
$currentNode = [TableNode]::new("Name|Value", @("B|2", "C|4", "D|4", "E|5"))
$reportItem = [ReportDifferenceItem]::new($previousNode, $currentNode, @("Header 1", "Header 2", "Header 3"))
$actual = $DifferenceRender.RenderTableNodesDiff($reportItem)
$actual | Should -Be @'
#### Header 2 > Header 3
| Name | Value |
| ----- | ----- |
| ~~A~~ | ~~1~~ |
| ~~C~~ | ~~3~~ |
| C | 4 |
| E | 5 |
'@
}
}
}

View File

@@ -0,0 +1,93 @@
using module ../SoftwareReport.psm1
using module ../SoftwareReport.Nodes.psm1
Describe "SoftwareReport.E2E" {
Context "Report example 1" {
BeforeEach {
$softwareReport = [SoftwareReport]::new("macOS 11")
$softwareReport.Root.AddToolVersion("OS Version:", "macOS 11.7 (20G817)")
$softwareReport.Root.AddToolVersion("Image Version:", "20220918.1")
$installedSoftware = $softwareReport.Root.AddHeader("Installed Software")
$languagesAndRuntimes = $installedSoftware.AddHeader("Language and Runtime")
$languagesAndRuntimes.AddToolVersion("Bash", "5.1.16(1)-release")
$languagesAndRuntimes.AddToolVersionsListInline(".NET Core SDK", @("1.2.100", "1.2.200", "3.1.414"), "^\d+\.\d+\.\d")
$languagesAndRuntimes.AddNode([ToolVersionNode]::new("Perl", "5.34.0"))
$cachedTools = $installedSoftware.AddHeader("Cached Tools")
$cachedTools.AddToolVersionsList("Ruby", @("2.7.3", "2.8.1", "3.1.2"), "^\d+\.\d+")
$cachedTools.AddToolVersionsList("Node.js", @("14.8.0", "15.1.0", "16.4.2"), "^\d+")
$javaSection = $installedSoftware.AddHeader("Java")
$javaSection.AddTable(@(
[PSCustomObject] @{ Version = "8.0.125"; Vendor = "My Vendor"; "Environment Variable" = "JAVA_HOME_8_X64" },
[PSCustomObject] @{ Version = "11.3.103"; Vendor = "My Vendor"; "Environment Variable" = "JAVA_HOME_11_X64" }
))
$sqlSection = $installedSoftware.AddHeader("MySQL")
$sqlSection.AddToolVersion("MySQL", "6.1.0")
$sqlSection.AddNote("MySQL service is disabled by default.`nUse the following command as a part of your job to start the service: 'sudo systemctl start mysql.service'")
$expectedMarkdown = @'
# macOS 11
- OS Version: macOS 11.7 (20G817)
- Image Version: 20220918.1
## Installed Software
### Language and Runtime
- Bash 5.1.16(1)-release
- .NET Core SDK: 1.2.100, 1.2.200, 3.1.414
- Perl 5.34.0
### Cached Tools
#### Ruby
- 2.7.3
- 2.8.1
- 3.1.2
#### Node.js
- 14.8.0
- 15.1.0
- 16.4.2
### Java
| Version | Vendor | Environment Variable |
| -------- | --------- | -------------------- |
| 8.0.125 | My Vendor | JAVA_HOME_8_X64 |
| 11.3.103 | My Vendor | JAVA_HOME_11_X64 |
### MySQL
- MySQL 6.1.0
```
MySQL service is disabled by default.
Use the following command as a part of your job to start the service: 'sudo systemctl start mysql.service'
```
'@
}
It "ToMarkdown" {
$softwareReport.ToMarkdown() | Should -Be $expectedMarkdown
}
It "Serialization + Deserialization" {
$json = $softwareReport.ToJson()
$deserializedReport = [SoftwareReport]::FromJson($json)
$deserializedReport.ToMarkdown() | Should -Be $expectedMarkdown
}
}
Context "GetImageVersion" {
It "Image version exists" {
$softwareReport = [SoftwareReport]::new("MyReport")
$softwareReport.Root.AddToolVersion("Image Version:", "123.4")
$softwareReport.GetImageVersion() | Should -Be "123.4"
}
It "Empty report" {
$softwareReport = [SoftwareReport]::new("MyReport")
$softwareReport.GetImageVersion() | Should -Be "Unknown version"
}
}
}

View File

@@ -0,0 +1,511 @@
using module ../SoftwareReport.Nodes.psm1
BeforeDiscovery {
Import-Module $(Join-Path $PSScriptRoot "TestHelpers.psm1") -DisableNameChecking
}
Describe "Nodes.UnitTests" {
Context "ToolVersionNode" {
It "ToMarkdown" {
$node = [ToolVersionNode]::new("MyTool", "2.1.3")
$node.ToMarkdown() | Should -Be "- MyTool 2.1.3"
}
It "GetValue" {
$node = [ToolVersionNode]::new("MyTool", "2.1.3")
$node.GetValue() | Should -Be "2.1.3"
}
It "Serialization" {
$node = [ToolVersionNode]::new("MyTool", "2.1.3")
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "ToolVersionNode"
$json.ToolName | Should -Be "MyTool"
$json.Version | Should -Be "2.1.3"
}
It "Deserialization" {
{ [ToolVersionNode]::FromJsonObject(@{ NodeType = "ToolVersionNode"; ToolName = ""; Version = "2.1.3" }) } | Should -Throw '*Exception setting "ToolName": "The argument is null or empty.*'
{ [ToolVersionNode]::FromJsonObject(@{ NodeType = "ToolVersionNode"; ToolName = "MyTool"; Version = "" }) } | Should -Throw '*Exception setting "Version": "The argument is null or empty.*'
{ [ToolVersionNode]::FromJsonObject(@{ NodeType = "ToolVersionNode"; ToolName = "MyTool"; Version = "2.1.3" }) } | Should -Not -Throw
}
It "Serialization + Deserialization" {
$node = [ToolVersionNode]::new("MyTool", "2.1.3")
$json = $node.ToJsonObject()
$node2 = [ToolVersionNode]::FromJsonObject($json)
$json2 = $node2.ToJsonObject()
$($json | ConvertTo-Json) | Should -Be $($json2 | ConvertTo-Json)
}
It "IsSimilarTo" {
[ToolVersionNode]::new("MyTool", "2.1.3").IsSimilarTo([ToolVersionNode]::new("MyTool", "2.1.3")) | Should -BeTrue
[ToolVersionNode]::new("MyTool", "2.1.3").IsSimilarTo([ToolVersionNode]::new("MyTool", "1.0.0")) | Should -BeTrue
[ToolVersionNode]::new("MyTool", "2.1.3").IsSimilarTo([ToolVersionNode]::new("MyTool2", "2.1.3")) | Should -BeFalse
}
It "IsIdenticalTo" {
[ToolVersionNode]::new("MyTool", "2.1.3").IsIdenticalTo([ToolVersionNode]::new("MyTool", "2.1.3")) | Should -BeTrue
[ToolVersionNode]::new("MyTool", "2.1.3").IsIdenticalTo([ToolVersionNode]::new("MyTool", "1.0.0")) | Should -BeFalse
[ToolVersionNode]::new("MyTool", "2.1.3").IsIdenticalTo([ToolVersionNode]::new("MyTool2", "2.1.3")) | Should -BeFalse
}
}
Context "ToolVersionsListNode" {
It "ToMarkdown - List" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "List")
$expected = @(
"",
"# MyTool"
"- 2.7.7"
"- 3.0.5"
"- 3.1.3"
) -join "`n"
$node.ToMarkdown() | Should -Be $expected
}
It "ToMarkdown - Inline" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "Inline")
$node.ToMarkdown() | Should -Be "- MyTool: 2.7.7, 3.0.5, 3.1.3"
}
It "GetValue" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "List")
$node.GetValue() | Should -Be "2.7.7, 3.0.5, 3.1.3"
}
It "Serialization - List" {
$node = [ToolVersionsListNode]::new("Ruby", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "List")
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "ToolVersionsListNode"
$json.ToolName | Should -Be "Ruby"
$json.Versions | Should -BeArray @("2.7.7", "3.0.5", "3.1.3")
$json.MajorVersionRegex | Should -Be "^.+"
$json.ListType | Should -Be "List"
}
It "Serialization - Inline" {
$node = [ToolVersionsListNode]::new("Ruby", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "Inline")
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "ToolVersionsListNode"
$json.ToolName | Should -Be "Ruby"
$json.Versions | Should -BeArray @("2.7.7", "3.0.5", "3.1.3")
$json.MajorVersionRegex | Should -Be "^.+"
$json.ListType | Should -Be "Inline"
}
It "Deserialization" {
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = ""; Versions = @("2.1.3", "3.1.4"); MajorVersionRegex = "^\d+"; ListType = "List" }) } | Should -Throw '*Exception setting "ToolName": "The argument is null or empty.*'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; MajorVersionRegex = "^\d+"; ListType = "List" }) } | Should -Throw '*Exception setting "Versions": "The argument is null or empty.*'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @(); MajorVersionRegex = "^\d+"; ListType = "List" }) } | Should -Throw '*Exception setting "Versions": "The argument is null, empty,*'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @("2.1.3", '2.2.4'); MajorVersionRegex = "^\d+"; ListType = "List" }) } | Should -Throw 'Multiple versions from list * return the same result from regex *'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @("2.1.3", "3.1.4"); MajorVersionRegex = ""; ListType = "List" }) } | Should -Throw 'Version * doesn''t match regex *'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @("2.1.3", "3.1.4"); MajorVersionRegex = "^\d+"; ListType = "Fake" }) } | Should -Throw '*Exception setting "ListType": "The argument * does not belong to the set*'
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @("2.1.3", "3.1.4"); MajorVersionRegex = "^\d+"; ListType = "List" }) } | Should -Not -Throw
{ [ToolVersionsListNode]::FromJsonObject(@{ NodeType = "ToolVersionsListNode"; ToolName = "MyTool"; Versions = @("2.1.3", "3.1.4"); MajorVersionRegex = "^\d+"; ListType = "Inline" }) } | Should -Not -Throw
}
It "Serialization + Deserialization" {
$node = [ToolVersionsListNode]::new("Ruby", @("2.7.7", "3.0.5", "3.1.3"), "^.+", "List")
$json = $node.ToJsonObject()
$node2 = [ToolVersionsListNode]::FromJsonObject($json)
$json2 = $node2.ToJsonObject()
$($json | ConvertTo-Json) | Should -Be $($json2 | ConvertTo-Json)
}
It "IsSimilarTo" {
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsSimilarTo(
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List")
) | Should -BeTrue
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsSimilarTo(
[ToolVersionsListNode]::new("MyTool", @("2.1.5", "5.0.0"), "^.+", "List")
) | Should -BeTrue
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsSimilarTo(
[ToolVersionsListNode]::new("MyTool2", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List")
) | Should -BeFalse
}
It "IsIdenticalTo" {
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsIdenticalTo(
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List")
) | Should -BeTrue
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsIdenticalTo(
[ToolVersionsListNode]::new("MyTool", @("2.1.5", "5.0.0"), "^.+", "List")
) | Should -BeFalse
[ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List").IsIdenticalTo(
[ToolVersionsListNode]::new("MyTool2", @("2.1.3", "3.1.5", "4.0.0"), "^.+", "List")
) | Should -BeFalse
}
It "ExtractMajorVersion" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^\d+\.\d+", "List")
$node.ExtractMajorVersion("2.1.3") | Should -Be "2.1"
$node.ExtractMajorVersion("3.1.5") | Should -Be "3.1"
$node.ExtractMajorVersion("4.0.0") | Should -Be "4.0"
}
Context "ValidateMajorVersionRegex" {
It "Major version regex - unique versions" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "4.0.0"), "^\d+", "List")
$node.Versions | Should -BeArray @("2.1.3", "3.1.5", "4.0.0")
}
It "Major version regex - non-unique versions" {
{ [ToolVersionsListNode]::new("MyTool", @("2.1.3", "3.1.5", "3.2.0", "4.0.0"), "^\d+", "List") } | Should -Throw "Multiple versions from list * return the same result from regex *"
}
It "Minor version regex - unique versions" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.1.3", "2.4.0", "3.1.2"), "^\d+\.\d+", "List")
$node.Versions | Should -BeArray @("2.1.3", "2.4.0", "3.1.2")
}
It "Minor version regex - non-unique versions" {
{ [ToolVersionsListNode]::new("MyTool", @("2.1.3", "2.1.4", "3.1.2"), "^\d+\.\d+", "List") } | Should -Throw "Multiple versions from list * return the same result from regex *"
}
It "Patch version regex - unique versions" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.1.3", "2.1.4", "2.1.5"), "^\d+\.\d+\.\d+", "List")
$node.Versions | Should -BeArray @("2.1.3", "2.1.4", "2.1.5")
}
It "Patch version regex - non-unique versions" {
{ [ToolVersionsListNode]::new("MyTool", @("2.1.3", "2.1.4", "2.1.4"), "^\d+\.\d+\.\d+", "List") } | Should -Throw "Multiple versions from list * return the same result from regex *"
}
It ".NET Core version regex - unique versions" {
$node = [ToolVersionsListNode]::new("MyTool", @("2.1.100", "2.1.205", "2.1.303"), "^\d+\.\d+\.\d", "List")
$node.Versions | Should -BeArray @("2.1.100", "2.1.205", "2.1.303")
}
It ".NET Core version regex - non-unique versions" {
{ [ToolVersionsListNode]::new("MyTool", @("2.1.100", "2.1.205", "2.1.230", "3.1.0"), "^\d+\.\d+\.\d", "List") } | Should -Throw "Multiple versions from list * return the same result from regex *"
}
}
}
Context "TableNode" {
Context "ToMarkdown" {
It "Simple table" {
$node = [TableNode]::new("Name|Value", @("A|B", "C|D"))
$node.ToMarkdown() | Should -Be @'
| Name | Value |
| ---- | ----- |
| A | B |
| C | D |
'@
}
It "Wide cells" {
$node = [TableNode]::new("Name|Value", @("Very long value here|B", "C|And very long value here too"))
$node.ToMarkdown() | Should -Be @'
| Name | Value |
| -------------------- | ---------------------------- |
| Very long value here | B |
| C | And very long value here too |
'@
}
}
It "CalculateColumnsWidth" {
[TableNode]::new("Name|Value", @("A|B", "C|D")).CalculateColumnsWidth() | Should -BeArray @(4, 5)
[TableNode]::new("Name|Value", @("Very long value here|B", "C|And very long value here too")).CalculateColumnsWidth() | Should -BeArray @(20, 28)
}
It "Serialization" {
$node = [TableNode]::new("Name|Value", @("A|B", "C|D"))
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "TableNode"
$json.Headers | Should -Be "Name|Value"
$json.Rows | Should -BeArray @("A|B", "C|D")
}
It "Deserialization" {
{ [TableNode]::FromJsonObject(@{ NodeType = "TableNode"; Headers = ""; Rows = @("A|1", "B|2") }) } | Should -Throw 'Exception setting "Headers": "The argument is null or empty. *'
{ [TableNode]::FromJsonObject(@{ NodeType = "TableNode"; Headers = "Name|Value"; Rows = @() }) } | Should -Throw 'Exception setting "Rows": "The argument is null, empty, *'
{ [TableNode]::FromJsonObject(@{ NodeType = "TableNode"; Headers = "Name|Value"; Rows = @("A|1", "B|2|T", "C|3") }) } | Should -Throw 'Table has different number of columns in different rows'
{ [TableNode]::FromJsonObject(@{ NodeType = "TableNode"; Headers = "Name|Value"; Rows = @("A|1", "B|2") }) } | Should -Not -Throw
}
It "Serialization + Deserialization" {
$node = [TableNode]::new("Name|Value", @("A|B", "C|D"))
$json = $node.ToJsonObject()
$node2 = [TableNode]::FromJsonObject($json)
$json2 = $node2.ToJsonObject()
$($json | ConvertTo-Json) | Should -Be $($json2 | ConvertTo-Json)
}
It "IsSimilarTo" {
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsSimilarTo([TableNode]::new("Name|Value", @("A|B", "C|D"))) | Should -BeTrue
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsSimilarTo([TableNode]::new("Name|Value", @("A|B", "C|D", "F|W"))) | Should -BeTrue
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsSimilarTo([TableNode]::new("Name|Value", @("A|B", "C|E"))) | Should -BeTrue
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsSimilarTo([TableNode]::new("Name|Key", @("A|B", "C|D"))) | Should -BeTrue
}
It "IsIdenticalTo" {
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsIdenticalTo([TableNode]::new("Name|Value", @("A|B", "C|D"))) | Should -BeTrue
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsIdenticalTo([TableNode]::new("Name|Key", @("A|B", "C|D"))) | Should -BeTrue
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsIdenticalTo([TableNode]::new("Name|Value", @("A|B", "C|D", "F|W"))) | Should -BeFalse
[TableNode]::new("Name|Value", @("A|B", "C|D")).IsIdenticalTo([TableNode]::new("Name|Value", @("A|B", "C|E"))) | Should -BeFalse
}
Context "FromObjectsArray" {
It "Correct table" {
$table = @(
[PSCustomObject]@{Name = "A"; Value = "B"}
[PSCustomObject]@{Name = "C"; Value = "D"}
)
$tableNode = [TableNode]::FromObjectsArray($table)
$tableNode.Headers | Should -Be "Name|Value"
$tableNode.Rows | Should -BeArray @("A|B", "C|D")
}
It "Correct table with spaces" {
$table = @(
[PSCustomObject]@{Name = "A B"; "My Value" = "1 2"}
[PSCustomObject]@{Name = "C D"; "My Value" = "3 4"}
)
$tableNode = [TableNode]::FromObjectsArray($table)
$tableNode.Headers | Should -Be "Name|My Value"
$tableNode.Rows | Should -BeArray @("A B|1 2", "C D|3 4")
}
It "Throw on empty table" {
{ [TableNode]::FromObjectsArray(@()) } | Should -Throw "Failed to create TableNode from empty objects array"
}
It "Throw on table with different columns" {
$table = @(
[PSCustomObject]@{Name = "A"; Value = "B"}
[PSCustomObject]@{Name = "C"; Value2 = "D"}
)
{ [TableNode]::FromObjectsArray($table) } | Should -Throw "Failed to create TableNode from objects array because objects have different properties"
}
It "Throw on empty row" {
$table = @(
[PSCustomObject]@{Name = "A"; Value = "B"},
[PSCustomObject]@{},
[PSCustomObject]@{Name = "C"; Value2 = "D"}
)
{ [TableNode]::FromObjectsArray($table) } | Should -Throw "Failed to create TableNode because some objects are empty"
}
It "Throw on incorrect symbols in table column names" {
$table = @(
[PSCustomObject]@{"Name|War" = "A"; Value = "B"}
[PSCustomObject]@{"Name|War" = "C"; Value = "D"}
)
{ [TableNode]::FromObjectsArray($table) } | Should -Throw "Failed to create TableNode because some cells * contains forbidden symbol*"
}
It "Throw on incorrect symbols in table rows" {
$table = @(
[PSCustomObject]@{Name = "A"; Value = "B|AA"}
[PSCustomObject]@{Name = "C"; Value = "D"}
)
{ [TableNode]::FromObjectsArray($table) } | Should -Throw "Failed to create TableNode because some cells * contains forbidden symbol*"
}
}
}
Context "NoteNode" {
It "ToMarkdown" {
$node = [NoteNode]::new("Hello world`nGood Bye world")
$node.ToMarkdown() | Should -Be @'
```
hello world
Good Bye world
```
'@
}
It "Serialization" {
$node = [NoteNode]::new("MyContent`nMyContent2")
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "NoteNode"
$json.Content | Should -Be "MyContent`nMyContent2"
}
It "Deserialization" {
{ [NoteNode]::FromJsonObject(@{ NodeType = "NoteNode" }) } | Should -Throw '*Exception setting "Content": "The argument is null or empty.*'
{ [NoteNode]::FromJsonObject(@{ NodeType = "NoteNode"; Content = "" }) } | Should -Throw '*Exception setting "Content": "The argument is null or empty.*'
{ [NoteNode]::FromJsonObject(@{ NodeType = "NoteNode"; Content = "MyTool" }) } | Should -Not -Throw
}
It "Serialization + Deserialization" {
$node = [NoteNode]::new("MyContent`nMyContent2")
$json = $node.ToJsonObject()
$node2 = [NoteNode]::FromJsonObject($json)
$json2 = $node2.ToJsonObject()
$($json | ConvertTo-Json) | Should -Be $($json2 | ConvertTo-Json)
}
It "IsSimilarTo" {
[NoteNode]::new("MyContent").IsSimilarTo([NoteNode]::new("MyContent")) | Should -BeTrue
[NoteNode]::new("MyContent").IsSimilarTo([NoteNode]::new("MyContent2")) | Should -BeFalse
}
It "IsIdenticalTo" {
[NoteNode]::new("MyContent").IsIdenticalTo([NoteNode]::new("MyContent")) | Should -BeTrue
[NoteNode]::new("MyContent").IsIdenticalTo([NoteNode]::new("MyContent2")) | Should -BeFalse
}
}
Context "HeaderNode" {
It "ToMarkdown" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$node.ToMarkdown(1) | Should -Be @'
# MyHeader
- MyTool 2.1.3
'@
}
It "ToMarkdown (level 3)" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$node.ToMarkdown(3) | Should -Be @'
### MyHeader
- MyTool 2.1.3
'@
}
It "ToMarkdown (multiple levels)" {
$node = [HeaderNode]::new("MyHeader")
$node.AddHeader("MyHeader 2").AddHeader("MyHeader 3").AddHeader("MyHeader 4").AddToolVersion("MyTool", "2.1.3")
$node.ToMarkdown(1) | Should -Be @'
# MyHeader
## MyHeader 2
### MyHeader 3
#### MyHeader 4
- MyTool 2.1.3
'@
}
It "Serialization" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$json = $node.ToJsonObject()
$json.NodeType | Should -Be "HeaderNode"
$json.Title | Should -Be "MyHeader"
$json.Children | Should -HaveCount 1
}
It "Deserialization" {
{ [HeaderNode]::FromJsonObject(@{ NodeType = "HeaderNode" }) } | Should -Throw '*Exception setting "Title": "The argument is null or empty.*'
{ [HeaderNode]::FromJsonObject(@{ NodeType = "HeaderNode"; Title = "" }) } | Should -Throw '*Exception setting "Title": "The argument is null or empty.*'
{ [HeaderNode]::FromJsonObject(@{ NodeType = "HeaderNode"; Title = "MyHeader" }) } | Should -Not -Throw
}
It "Serialization + Deserialization" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$json = $node.ToJsonObject()
$node2 = [HeaderNode]::FromJsonObject($json)
$json2 = $node2.ToJsonObject()
$($json | ConvertTo-Json) | Should -Be $($json2 | ConvertTo-Json)
}
It "IsSimilarTo" {
[HeaderNode]::new("MyHeader").IsSimilarTo([HeaderNode]::new("MyHeader")) | Should -BeTrue
[HeaderNode]::new("MyHeader").IsSimilarTo([HeaderNode]::new("MyHeader2")) | Should -BeFalse
}
It "IsIdenticalTo" {
[HeaderNode]::new("MyHeader").IsIdenticalTo([HeaderNode]::new("MyHeader")) | Should -BeTrue
[HeaderNode]::new("MyHeader").IsIdenticalTo([HeaderNode]::new("MyHeader2")) | Should -BeFalse
}
It "FindSimilarChildNode" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$node.FindSimilarChildNode([ToolVersionNode]::new("MyTool", "1.0.0")) | Should -Not -BeNullOrEmpty
$node.FindSimilarChildNode([ToolVersionNode]::New("MyTool2", "1.0.0")) | Should -BeNullOrEmpty
}
Context "Detect node duplicates" {
It "Similar HeaderNode on the same header" {
$node = [HeaderNode]::new("MyHeader")
$node.AddHeader("MySubHeader1")
$node.AddHeader("MySubHeader2")
{ $node.AddHeader("MySubHeader1") } | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "Similar ToolVersionNode on the same header" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$node.AddToolVersion("MyTool2", "2.1.3")
{ $node.AddToolVersion("MyTool", "2.1.3") } | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "Similar ToolVersionsListNode on the same header" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersionsList("MyTool", @("2.1.3", "3.0.0"), "^\d+")
$node.AddToolVersionsListInline("MyTool2", @("2.1.3", "3.0.0"), "^\d+")
{ $node.AddToolVersionsList("MyTool", @("2.1.3", "3.0.0"), "^\d+") } | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "Similar TableNode on the same header" {
$node = [HeaderNode]::new("MyHeader")
$node.AddTable(@(
[PSCustomObject]@{Name = "Value1"},
[PSCustomObject]@{Name = "Value2"}
))
{
$node.AddTable(@(
[PSCustomObject]@{Name = "Value1"},
[PSCustomObject]@{Name = "Value2"}
))
} | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "Similar NoteNode on the same header" {
$node = [HeaderNode]::new("MyHeader")
$node.AddNote("MyContent")
$node.AddNote("MyContent2")
{ $node.AddNote("MyContent") } | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "AddNode detects duplicates" {
$node = [HeaderNode]::new("MyHeader")
$node.AddNode([ToolVersionNode]::new("MyTool", "2.1.3"))
{ $node.AddNode([ToolVersionNode]::new("MyTool", "2.1.3")) } | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "AddNodes detects duplicates" {
$node = [HeaderNode]::new("MyHeader")
$node.AddNodes(@(
[ToolVersionNode]::new("MyTool", "2.1.3"),
[ToolVersionNode]::new("MyTool2", "2.1.4")
))
{
$node.AddNodes(@(
[ToolVersionNode]::new("MyTool3", "2.1.5"),
[ToolVersionNode]::new("MyTool", "2.1.3")
))
} | Should -Throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.*"
}
It "Doesn't allow adding non-header nodes after header node" {
$node = [HeaderNode]::new("MyHeader")
$node.AddToolVersion("MyTool", "2.1.3")
$node.AddHeader("MySubHeader")
{ $node.AddToolVersion("MyTool2", "2.1.4") } | Should -Throw "It is not allowed to add the node of type * to the HeaderNode that already contains the HeaderNode children."
{ $node.AddHeader("MySubHeader2") } | Should -Not -Throw
}
}
}
}

View File

@@ -0,0 +1,34 @@
function ShouldBeArray([Array] $ActualValue, [Array]$ExpectedValue, [Switch] $Negate, [String] $Because) {
if ($Negate) {
throw "Negation is not supported for Should-BeArray"
}
if ($ExpectedValue.Count -eq 0) {
throw "Expected array cannot be empty. Use Should-BeNullOrEmpty instead."
}
$ExpectedValue | ForEach-Object {
if ($_.GetType() -notin @([String], [Int32])) {
throw "Only string or int arrays are supported in Should-BeArray"
}
}
$actualValueJson = $ActualValue | ConvertTo-Json
$expectedValueJson = $ExpectedValue | ConvertTo-Json
$succeeded = ($ActualValue.Count -eq $ExpectedValue.Count) -and ($actualValueJson -eq $expectedValueJson)
if (-not $succeeded) {
$failureMessage = "Expected array '$actualValueJson' to be equal to '$expectedValueJson'"
}
return [PSCustomObject]@{
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
Add-ShouldOperator -Name BeArray `
-InternalName 'ShouldBeArray' `
-Test ${function:ShouldBeArray} `
-SupportsArrayInput