test: remove ambient timing from double-click contracts
This commit is contained in:
parent
3684e7b5e7
commit
c8c764a40e
5 changed files with 151 additions and 40 deletions
|
|
@ -6,9 +6,9 @@
|
|||
Parses tracked C# files under tests/ with the Roslyn assemblies bundled in
|
||||
the active .NET SDK. The report is evidence for the R3 test-truth audit: it
|
||||
records test attributes and traits, static skips, empty-return sites,
|
||||
assertion/throw signals (including same-file helper calls), diagnostic
|
||||
output signals, wall-clock waits, environment-variable dependencies, and
|
||||
source-text reads.
|
||||
prerequisite gates reached through same-file helper calls, assertion/throw
|
||||
signals (including same-file helper calls), diagnostic output signals,
|
||||
wall-clock waits, environment-variable dependencies, and source-text reads.
|
||||
|
||||
This is a candidate generator, not a semantic proof. In particular, an
|
||||
output-only candidate can call a failure-capable helper declared in another
|
||||
|
|
@ -107,6 +107,35 @@ function Get-ReturnGateKind {
|
|||
return $null
|
||||
}
|
||||
|
||||
function Get-EmptyReturnSites {
|
||||
param(
|
||||
[Parameter(Mandatory)]$Tree,
|
||||
[Parameter(Mandatory)]$Method
|
||||
)
|
||||
|
||||
$sites = [Collections.Generic.List[object]]::new()
|
||||
foreach ($returnNode in @($Method.DescendantNodes() | Where-Object {
|
||||
$_.GetType().Name -eq 'ReturnStatementSyntax' -and
|
||||
$null -eq $_.Expression
|
||||
})) {
|
||||
$condition = '<unconditional>'
|
||||
$cursor = $returnNode.Parent
|
||||
while ($null -ne $cursor -and $cursor -ne $Method) {
|
||||
if ($cursor.GetType().Name -eq 'IfStatementSyntax') {
|
||||
$condition = $cursor.Condition.ToString()
|
||||
break
|
||||
}
|
||||
$cursor = $cursor.Parent
|
||||
}
|
||||
$sites.Add([ordered]@{
|
||||
Line = Get-NodeLine $Tree $returnNode
|
||||
Condition = $condition
|
||||
GateKind = Get-ReturnGateKind $condition
|
||||
})
|
||||
}
|
||||
return @($sites)
|
||||
}
|
||||
|
||||
function Get-InvocationName {
|
||||
param([Parameter(Mandatory)]$Invocation)
|
||||
|
||||
|
|
@ -188,6 +217,44 @@ function Test-RecursiveSignal {
|
|||
return $false
|
||||
}
|
||||
|
||||
function Get-RecursivePrerequisiteGateSites {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$MethodKey,
|
||||
[Parameter(Mandatory)][hashtable]$MethodMap,
|
||||
[Parameter(Mandatory)][hashtable]$GateMap,
|
||||
[Parameter(Mandatory)][hashtable]$CallMap,
|
||||
[Parameter(Mandatory)][hashtable]$Visited
|
||||
)
|
||||
|
||||
if ($Visited.ContainsKey($MethodKey)) {
|
||||
return @()
|
||||
}
|
||||
$Visited[$MethodKey] = $true
|
||||
|
||||
$sites = [Collections.Generic.List[object]]::new()
|
||||
foreach ($calledName in @($CallMap[$MethodKey])) {
|
||||
foreach ($candidateKey in @($MethodMap.Keys | Where-Object {
|
||||
$_.EndsWith("::$calledName", [StringComparison]::Ordinal)
|
||||
})) {
|
||||
foreach ($gate in @($GateMap[$candidateKey] | Where-Object {
|
||||
$null -ne $_.GateKind
|
||||
})) {
|
||||
$sites.Add([ordered]@{
|
||||
Helper = $candidateKey
|
||||
Line = $gate.Line
|
||||
Condition = $gate.Condition
|
||||
GateKind = $gate.GateKind
|
||||
})
|
||||
}
|
||||
foreach ($nestedSite in @(Get-RecursivePrerequisiteGateSites `
|
||||
$candidateKey $MethodMap $GateMap $CallMap $Visited)) {
|
||||
$sites.Add($nestedSite)
|
||||
}
|
||||
}
|
||||
}
|
||||
return @($sites | Sort-Object Helper, Line, Condition -Unique)
|
||||
}
|
||||
|
||||
$trackedFiles = @(& git -C $repoRoot ls-files tests | Where-Object {
|
||||
$_.EndsWith('.cs', [StringComparison]::OrdinalIgnoreCase)
|
||||
})
|
||||
|
|
@ -214,6 +281,7 @@ foreach ($relativePath in $trackedFiles) {
|
|||
$methodMap = @{}
|
||||
$failureMap = @{}
|
||||
$outputMap = @{}
|
||||
$gateMap = @{}
|
||||
$callMap = @{}
|
||||
|
||||
foreach ($method in $allMethods) {
|
||||
|
|
@ -222,6 +290,7 @@ foreach ($relativePath in $trackedFiles) {
|
|||
$methodMap[$key] = $method
|
||||
$failureMap[$key] = Test-DirectFailureSignal $method
|
||||
$outputMap[$key] = Test-DirectOutputSignal $method
|
||||
$gateMap[$key] = @(Get-EmptyReturnSites $tree $method)
|
||||
$callMap[$key] = @($method.DescendantNodes() |
|
||||
Where-Object { $_.GetType().Name -eq 'InvocationExpressionSyntax' } |
|
||||
ForEach-Object { Get-InvocationName $_ } |
|
||||
|
|
@ -247,26 +316,9 @@ foreach ($relativePath in $trackedFiles) {
|
|||
$hasOutputSignal = Test-RecursiveSignal `
|
||||
$key $methodMap $outputMap $callMap @{}
|
||||
|
||||
$emptyReturns = [Collections.Generic.List[object]]::new()
|
||||
foreach ($returnNode in @($method.DescendantNodes() | Where-Object {
|
||||
$_.GetType().Name -eq 'ReturnStatementSyntax' -and
|
||||
$null -eq $_.Expression
|
||||
})) {
|
||||
$condition = '<unconditional>'
|
||||
$cursor = $returnNode.Parent
|
||||
while ($null -ne $cursor -and $cursor -ne $method) {
|
||||
if ($cursor.GetType().Name -eq 'IfStatementSyntax') {
|
||||
$condition = $cursor.Condition.ToString()
|
||||
break
|
||||
}
|
||||
$cursor = $cursor.Parent
|
||||
}
|
||||
$emptyReturns.Add([ordered]@{
|
||||
Line = Get-NodeLine $tree $returnNode
|
||||
Condition = $condition
|
||||
GateKind = Get-ReturnGateKind $condition
|
||||
})
|
||||
}
|
||||
$emptyReturns = @($gateMap[$key])
|
||||
$helperPrerequisiteReturns = @(Get-RecursivePrerequisiteGateSites `
|
||||
$key $methodMap $gateMap $callMap @{})
|
||||
|
||||
$traits = [Collections.Generic.List[string]]::new()
|
||||
$staticSkip = $null
|
||||
|
|
@ -315,9 +367,11 @@ foreach ($relativePath in $trackedFiles) {
|
|||
Traits = @($traits)
|
||||
StaticSkip = $staticSkip
|
||||
EmptyReturns = @($emptyReturns)
|
||||
HelperPrerequisiteReturns = @($helperPrerequisiteReturns)
|
||||
PrerequisiteReturnCandidate = @($emptyReturns | Where-Object {
|
||||
$null -ne $_.GateKind
|
||||
}).Count -gt 0
|
||||
HelperPrerequisiteReturnCandidate = $helperPrerequisiteReturns.Count -gt 0
|
||||
HasFailureSignal = $hasFailureSignal
|
||||
HasOutputSignal = $hasOutputSignal
|
||||
OutputOnlyCandidate = $hasOutputSignal -and -not $hasFailureSignal
|
||||
|
|
@ -347,6 +401,15 @@ $summary = [ordered]@{
|
|||
PrerequisiteReturnCandidates = @($orderedRecords | Where-Object {
|
||||
$_.PrerequisiteReturnCandidate
|
||||
}).Count
|
||||
HelperPrerequisiteReturnCandidates = @($orderedRecords | Where-Object {
|
||||
$_.HelperPrerequisiteReturnCandidate
|
||||
}).Count
|
||||
HelperPrerequisiteReturnSites = @($orderedRecords |
|
||||
ForEach-Object { $_.HelperPrerequisiteReturns }).Count
|
||||
AnyPrerequisiteReturnCandidates = @($orderedRecords | Where-Object {
|
||||
$_.PrerequisiteReturnCandidate -or
|
||||
$_.HelperPrerequisiteReturnCandidate
|
||||
}).Count
|
||||
OutputOnlyCandidates = @($orderedRecords | Where-Object { $_.OutputOnlyCandidate }).Count
|
||||
DiagnosticMethods = @($orderedRecords | Where-Object {
|
||||
$_.Traits -contains 'Purpose, Diagnostic'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue