diff --git a/helpers/software-report-base/SoftwareReport.Nodes.psm1 b/helpers/software-report-base/SoftwareReport.Nodes.psm1 index 7fcb43ad4..b126afdf6 100644 --- a/helpers/software-report-base/SoftwareReport.Nodes.psm1 +++ b/helpers/software-report-base/SoftwareReport.Nodes.psm1 @@ -44,9 +44,21 @@ class HeaderNode: BaseNode { throw "This HeaderNode already contains the similar child node. It is not allowed to add the same node twice.`nFound node: $($similarNode.ToJsonObject() | ConvertTo-Json)`nNew node: $($node.ToJsonObject() | ConvertTo-Json)" } - [Array] $existingHeaderNodes = $this.Children | Where-Object { $_ -is [HeaderNode] } - if (($existingHeaderNodes.Count -gt 0) -and ($node -isnot [HeaderNode])) { - throw "It is not allowed to add the node of type '$($node.GetType().Name)' to the HeaderNode that already contains the HeaderNode children." + if (-not $this.IsNodeHasMarkdownHeader($node)) { + # If the node doesn't print own header to markdown, we should check that there is no other nodes that print header to markdown before it. + # It is done to avoid unexpected situation like this: + # + # HeaderNode A -> # A + # HeaderNode B -> ## B + # ToolVersionNode C -> - C + # ToolVersionNode D -> - D + # + # In this example, we add 'HeaderNode B" to 'HeaderNode A' and add 'ToolVersionNode C' to 'HeaderNode B'. + # Then we add 'ToolVersionNode D' to 'HeaderNode A'. + # But the result markdown will look like 'ToolVersionNode D' belongs to 'HeaderNode B' instead of 'HeaderNode A'. + $this.Children | Where-Object { $this.IsNodeHasMarkdownHeader($_) } | ForEach-Object { + throw "It is not allowed to add the non-header node after the header node. Consider adding the separate HeaderNode for this node" + } } $this.Children.Add($node) @@ -130,6 +142,18 @@ class HeaderNode: BaseNode { return $null } + + hidden [Boolean] IsNodeHasMarkdownHeader([BaseNode] $node) { + if ($node -is [HeaderNode]) { + return $true + } + + if (($node -is [ToolVersionsListNode]) -and ($node.ListType -eq "List")) { + return $true + } + + return $false + } } class ToolVersionNode: BaseToolNode { diff --git a/helpers/software-report-base/tests/SoftwareReport.Difference.E2E.Tests.ps1 b/helpers/software-report-base/tests/SoftwareReport.Difference.E2E.Tests.ps1 index 8025e4736..1e76e2478 100644 --- a/helpers/software-report-base/tests/SoftwareReport.Difference.E2E.Tests.ps1 +++ b/helpers/software-report-base/tests/SoftwareReport.Difference.E2E.Tests.ps1 @@ -520,6 +520,39 @@ Describe "Comparer.E2E" { | EE | 66 | +'@ + } + + It "Reports are identical" { + # 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("ToolA", "1.0.0") + $prevTools.AddToolVersion("ToolB", "3.0.1") + + # 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("ToolA", "1.0.0") + $nextTools.AddToolVersion("ToolB", "3.0.1") + + # 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? + + '@ } } \ No newline at end of file diff --git a/helpers/software-report-base/tests/SoftwareReport.Nodes.Unit.Tests.ps1 b/helpers/software-report-base/tests/SoftwareReport.Nodes.Unit.Tests.ps1 index 58f57d397..94bcf3a74 100644 --- a/helpers/software-report-base/tests/SoftwareReport.Nodes.Unit.Tests.ps1 +++ b/helpers/software-report-base/tests/SoftwareReport.Nodes.Unit.Tests.ps1 @@ -184,26 +184,24 @@ Describe "Nodes.UnitTests" { } Context "TableNode" { - Context "ToMarkdown" { - It "Simple table" { - $node = [TableNode]::new("Name|Value", @("A|B", "C|D")) - $node.ToMarkdown() | Should -Be @' + It "ToMarkdown (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 @' + It "ToMarkdown (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" { @@ -453,7 +451,7 @@ Good Bye world It "Similar ToolVersionsListNode on the same header" { $node = [HeaderNode]::new("MyHeader") - $node.AddToolVersionsList("MyTool", @("2.1.3", "3.0.0"), "^\d+") + $node.AddToolVersionsListInline("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.*" } @@ -501,10 +499,12 @@ Good Bye world 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.AddToolVersion("MyTool", "2.1.3") } | Should -Not -Throw + { $node.AddHeader("MySubHeader") } | Should -Not -Throw + { $node.AddToolVersion("MyTool2", "2.1.4") } | Should -Throw "It is not allowed to add the non-header node after the header node. Consider adding the separate HeaderNode for this node" { $node.AddHeader("MySubHeader2") } | Should -Not -Throw + { $node.AddToolVersionsListInline("MyTool3", @("2.1.4", "2.1.5"), "^.+") } | Should -Throw "It is not allowed to add the non-header node after the header node. Consider adding the separate HeaderNode for this node" + { $node.AddToolVersionsList("MyTool4", @("2.1.4", "2.1.5"), "^.+") } | Should -Not -Throw } } }