Source/Public/Compare-ObjectGraph.ps1
<#
.SYNOPSIS Compare Object Graph .DESCRIPTION Deep compares two Object Graph and lists the differences between them. .PARAMETER InputObject The input object that will be compared with the reference object (see: [-Reference] parameter). > [!NOTE] > Multiple input object might be provided via the pipeline. > The common PowerShell behavior is to unroll any array (aka list) provided by the pipeline. > To avoid a list of (root) objects to unroll, use the **comma operator**: ,$InputObject | Compare-ObjectGraph $Reference. .PARAMETER Reference The reference that is used to compared with the input object (see: [-InputObject] parameter). .PARAMETER PrimaryKey If supplied, dictionaries (including PSCustomObject or Component Objects) in a list are matched based on the values of the `-PrimaryKey` supplied. .PARAMETER IsEqual If set, the cmdlet will return a boolean (`$true` or `$false`). As soon a Discrepancy is found, the cmdlet will immediately stop comparing further properties. .PARAMETER MatchCase Unless the `-MatchCase` switch is provided, string values are considered case insensitive. > [!NOTE] > Dictionary keys are compared based on the `$Reference`. > if the `$Reference` is an object (PSCustomObject or component object), the key or name comparison > is case insensitive otherwise the comparer supplied with the dictionary is used. .PARAMETER MatchType Unless the `-MatchType` switch is provided, a loosely (inclusive) comparison is done where the `$Reference` object is leading. Meaning `$Reference -eq $InputObject`: '1.0' -eq 1.0 # $false 1.0 -eq '1.0' # $true (also $false if the `-MatchType` is provided) .PARAMETER IgnoreLisOrder By default, items in a list are matched independent of the order (meaning by index position). If the `-IgnoreListOrder` switch is supplied, any list in the `$InputObject` is searched for a match with the reference. > [!NOTE] > Regardless the list order, any dictionary lists are matched by the primary key (if supplied) first. .PARAMETER MatchMapOrder By default, items in dictionary (including properties of an PSCustomObject or Component Object) are matched by their key name (independent of the order). If the `-MatchMapOrder` switch is supplied, each entry is also validated by the position. > [!NOTE] > A `[HashTable]` type is unordered by design and therefore, regardless the `-MatchMapOrder` switch, the order of the `[HashTable]` (defined by the `$Reference`) are always ignored. .PARAMETER MaxDepth The maximal depth to recursively compare each embedded property (default: 10). #> function Compare-ObjectGraph { [CmdletBinding(HelpUri='https://github.com/iRon7/ObjectGraphTools/blob/main/Docs/Compare-ObjectGraph.md')] param( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)] $InputObject, [Parameter(Mandatory = $true, Position=0)] $Reference, [String[]]$PrimaryKey, [Switch]$IsEqual, [Switch]$MatchCase, [Switch]$MatchType, [Switch]$IgnoreListOrder, [Switch]$MatchMapOrder, [Alias('Depth')][int]$MaxDepth = [PSNode]::DefaultMaxDepth ) begin { $ObjectComparison = [ObjectComparison]0 [ObjectComparison].GetEnumNames().foreach{ if ($PSBoundParameters.ContainsKey($_) -and $PSBoundParameters[$_]) { $ObjectComparison = $ObjectComparison -bor [ObjectComparison]$_ } } $ObjectComparer = [ObjectComparer]@{ PrimaryKey = $PrimaryKey; ObjectComparison = $ObjectComparison } $Node1 = [PSNode]::ParseInput($Reference, $MaxDepth) } process { $Node2 = [PSNode]::ParseInput($InputObject, $MaxDepth) if ($IsEqual) { $ObjectComparer.IsEqual($Node1, $Node2) } else { $ObjectComparer.Report($Node1, $Node2) } } } |