Tests/Copy-ElmModel.Tests.ps1
|
BeforeAll { . $PSScriptRoot/../Private/Core/Copy-ElmModel.ps1 } Describe 'Copy-ElmModel' -Tag 'Unit', 'P1' { Context 'When given a flat PSCustomObject' { BeforeAll { $original = [PSCustomObject]@{ Name = 'Alice'; Count = 42 } $copy = Copy-ElmModel -Model $original } It 'Should return an object with equal property values' { $copy.Name | Should -Be $original.Name $copy.Count | Should -Be $original.Count } It 'Should return a distinct reference (not the same object)' { [object]::ReferenceEquals($copy, $original) | Should -BeFalse } } Context 'When given a nested PSCustomObject' { BeforeAll { $original = [PSCustomObject]@{ Outer = [PSCustomObject]@{ Inner = 'value' } } $copy = Copy-ElmModel -Model $original } It 'Should have equal nested property values' { $copy.Outer.Inner | Should -Be $original.Outer.Inner } It 'Should return a distinct reference for nested objects' { [object]::ReferenceEquals($copy.Outer, $original.Outer) | Should -BeFalse } } Context 'When the model has an array property' { BeforeAll { $original = [PSCustomObject]@{ Items = @('a', 'b', 'c') } $copy = Copy-ElmModel -Model $original } It 'Should copy the array values' { $copy.Items | Should -Be $original.Items } It 'Should return an independent array (mutating copy does not affect original)' { $copy.Items = @('x', 'y') $original.Items | Should -Be @('a', 'b', 'c') } } Context 'When given $null' { It 'Should throw a terminating error' { { Copy-ElmModel -Model $null } | Should -Throw } } Context 'When given a hashtable' { BeforeAll { $original = @{ Key = 'val'; Num = 7 } $copy = Copy-ElmModel -Model $original } It 'Should return an object with equivalent property values' { $copy.Key | Should -Be $original.Key $copy.Num | Should -Be $original.Num } } Context 'When the model has an array of PSCustomObjects with string properties' { # Regression: Copy-ElmModel must preserve string types on nested PSCustomObject # items inside arrays. Callers must not need to cast [string] to call .Substring etc. It 'Should preserve string type on Name property of each item' { $original = [PSCustomObject]@{ Rows = @( [PSCustomObject]@{ Name = 'alpha'; Value = 1 } [PSCustomObject]@{ Name = 'beta'; Value = 2 } ) } $copy = Copy-ElmModel -Model $original $copy.Rows[0].Name | Should -BeOfType [string] $copy.Rows[1].Name | Should -BeOfType [string] } It 'Should preserve string value on Name property of each item' { $original = [PSCustomObject]@{ Rows = @( [PSCustomObject]@{ Name = 'alpha'; Value = 1 } [PSCustomObject]@{ Name = 'beta'; Value = 2 } ) } $copy = Copy-ElmModel -Model $original $copy.Rows[0].Name | Should -Be 'alpha' $copy.Rows[1].Name | Should -Be 'beta' } It 'Should allow calling string methods on copied Name without explicit cast' { $original = [PSCustomObject]@{ Rows = @( [PSCustomObject]@{ Name = 'hello-world'; Value = 0 } ) } $copy = Copy-ElmModel -Model $original { $copy.Rows[0].Name.Substring(0, 5) } | Should -Not -Throw $copy.Rows[0].Name.Substring(0, 5) | Should -Be 'hello' } It 'Should deep-clone each item in the array independently' { $item = [PSCustomObject]@{ Name = 'original'; Value = 99 } $original = [PSCustomObject]@{ Rows = @($item) } $copy = Copy-ElmModel -Model $original [object]::ReferenceEquals($copy.Rows[0], $item) | Should -BeFalse } It 'Should preserve numeric types on PSCustomObject items in arrays' { $original = [PSCustomObject]@{ Rows = @( [PSCustomObject]@{ Name = 'proc'; CpuSec = 3.14; MemMB = 128.5; Threads = 4 } ) } $copy = Copy-ElmModel -Model $original $copy.Rows[0].CpuSec | Should -Be 3.14 $copy.Rows[0].MemMB | Should -Be 128.5 $copy.Rows[0].Threads | Should -Be 4 } } } |