param([Parameter(Mandatory)][string]$EvidenceDir) $ErrorActionPreference='Stop' New-Item -ItemType Directory -Path $EvidenceDir -Force|Out-Null $source=Get-Content -LiteralPath (Join-Path $PSScriptRoot 'exercise-final-progression.ps1') $statements=@{} foreach($name in @('conserves-all-ids','actual-success','both-tutorials-persisted-once')){$statements[$name]=@($source|Where-Object {$_-match'^\s*Check '-and$_.Contains($name)})[0].Trim();if(!$statements[$name]){throw "Missing actual source assertion: $name"}} $results=[Collections.Generic.List[object]]::new() function Check([string]$Id,[bool]$Passed,[string]$Actual){if(!$Passed){throw "Actual source assertion rejected: $Id"}} function Counts($Board){return (@($Board.groups|ForEach-Object {$_.ballIds.Count}|Sort-Object)-join',')} function Board($State,[int]$Stage){return @($State.puzzleStates|Where-Object stageId -eq $Stage)[0]} foreach($case in @('valid-ids','wrong-ids','valid-target','wrong-target','missing-completion','valid-tutorials','missing-tutorial','duplicate-tutorial')){ $stage=13;$expected='2,3' $original=[pscustomobject]@{balls=@([pscustomobject]@{id='a'},[pscustomobject]@{id='b'})} $free=[pscustomobject]@{sourceStageId=13;balls=@([pscustomobject]@{id='b'},[pscustomobject]@{id='a'});groups=@([pscustomobject]@{ballIds=@('a','b')},[pscustomobject]@{ballIds=@('c','d','e')})} $success=[pscustomobject]@{completedStageIds=@(1..13);puzzleStates=@();latestFreePlay=$free} $complete=[pscustomobject]@{seenTutorialIds=@('split','merge')} $kind=if($case.Contains('ids')){'conserves-all-ids'}elseif($case.Contains('tutorial')){'both-tutorials-persisted-once'}else{'actual-success'} switch($case){'wrong-ids'{$free.balls[1].id='different'}'wrong-target'{$free.groups[1].ballIds=@('c','d')}'missing-completion'{$success.completedStageIds=@(1..12)}'missing-tutorial'{$complete.seenTutorialIds=@('merge')}'duplicate-tutorial'{$complete.seenTutorialIds=@('merge','split','split')}} $expectedPass=$case.StartsWith('valid-');$actualPass=$false;$errorText=$null try{& ([scriptblock]::Create($statements[$kind]));$actualPass=$true}catch{$errorText=$_.Exception.Message} $results.Add(@{case=$case;sourceStatement=$statements[$kind];expectedPass=$expectedPass;actualPass=$actualPass;passed=($actualPass-eq$expectedPass);error=$errorText}) } $passed=@($results|Where-Object passed -ne $true).Count-eq0 @{passed=$passed;sourceCommit=(& git rev-parse HEAD);checks=$results.ToArray()}|ConvertTo-Json -Depth 5|Set-Content -LiteralPath (Join-Path $EvidenceDir 'assertions-result.json') if(!$passed){exit 1} exit 0