Skip to content

Commit bd246f3

Browse files
committed
perf: speed up Views rendering and add render verification
1 parent db39df6 commit bd246f3

122 files changed

Lines changed: 16006 additions & 291 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ Src/LexText/ParserCore/ParserCoreTests/**/*.txt -whitespace
3434
Src/Utilities/pcpatrflex/DisambiguateInFLExDB/DisambiguateInFLExDBTests/TestData/*.* -whitespace
3535
Src/Utilities/pcpatrflex/PcPatrBrowserDll/Transforms/*.* -whitespace
3636
Src/Utilities/HCSynthByGloss/HCSynthByGloss/TestData/*.txt -whitespace
37+
38+
# Verify snapshot testing
39+
*.verified.png binary

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ _UpgradeReport_Files/
100100
/Release/
101101
Output/
102102
Output
103+
Output/RenderBenchmarks/
104+
Output/RenderBenchmarks/**
103105
Output_i686/
104106
Output_x86_64/
105107
__pycache__/
@@ -186,6 +188,7 @@ CrashLog.txt
186188
# VSTest Artifacts
187189
TestResults/
188190
*.trx
191+
TestResult.xml
189192

190193
# WPF markup compilation temp projects
191194
*_wpftmp.csproj
@@ -201,3 +204,8 @@ FLExInstaller/wix6/cabcache/*
201204

202205
# Claude Code worktrees
203206
.claude/worktrees/*
207+
208+
# Verify snapshot testing - received files are transient
209+
*.received.png
210+
*.diff.png
211+
DataTreeTimingBaselines.json

.vscode/tasks.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,23 @@
8585
}
8686
],
8787
"tasks": [
88+
{
89+
"label": "Test: RenderBaselineTests",
90+
"type": "shell",
91+
"command": ".\\test.ps1 -TestProject \"RootSiteTests\" -TestFilter \"FullyQualifiedName~RenderBaselineTests\"",
92+
"options": {
93+
"shell": {
94+
"executable": "powershell.exe",
95+
"args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command"]
96+
}
97+
},
98+
"problemMatcher": [],
99+
"group": "test",
100+
"presentation": {
101+
"reveal": "always",
102+
"panel": "shared"
103+
}
104+
},
88105
// ==================== Setup Tasks ====================
89106
{
90107
"label": "Setup: Colorize Worktree",

Build/Agent/Run-AllRenders.ps1

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<#
2+
.SYNOPSIS
3+
Runs the render-focused test suites for FieldWorks.
4+
5+
.DESCRIPTION
6+
Executes the DetailControls render tests and the RootSite render tests sequentially.
7+
This script is intentionally outside the product project graph so developers can use a
8+
single entrypoint without introducing a meta test project into the repository architecture.
9+
10+
.PARAMETER Scope
11+
Which render suites to run. Default is All.
12+
13+
.PARAMETER Configuration
14+
The build configuration to test. Default is Debug.
15+
16+
.PARAMETER NoBuild
17+
Skip building before running tests.
18+
19+
.PARAMETER Verbosity
20+
Test output verbosity: quiet, minimal, normal, detailed.
21+
22+
.PARAMETER SkipDependencyCheck
23+
Skip dependency preflight checks inside test.ps1.
24+
#>
25+
[CmdletBinding()]
26+
param(
27+
[ValidateSet('All', 'DetailControls', 'RootSite')]
28+
[string]$Scope = 'All',
29+
[string]$Configuration = 'Debug',
30+
[switch]$NoBuild,
31+
[ValidateSet('quiet', 'minimal', 'normal', 'detailed', 'q', 'm', 'n', 'd')]
32+
[string]$Verbosity = 'normal',
33+
[switch]$SkipDependencyCheck
34+
)
35+
36+
Set-StrictMode -Version Latest
37+
$ErrorActionPreference = 'Stop'
38+
39+
$repoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..'))
40+
$buildScript = Join-Path $repoRoot 'build.ps1'
41+
$testScript = Join-Path $repoRoot 'test.ps1'
42+
43+
if (-not (Test-Path $buildScript)) {
44+
throw "build.ps1 not found at $buildScript"
45+
}
46+
47+
if (-not (Test-Path $testScript)) {
48+
throw "test.ps1 not found at $testScript"
49+
}
50+
51+
$requestedScopes = switch ($Scope) {
52+
'All' { @('DetailControls', 'RootSite') }
53+
default { @($Scope) }
54+
}
55+
56+
function Invoke-RenderSuite {
57+
param(
58+
[Parameter(Mandatory = $true)]
59+
[string]$Name,
60+
[Parameter(Mandatory = $true)]
61+
[string]$BuildProject,
62+
[Parameter(Mandatory = $true)]
63+
[string]$TestProject,
64+
[Parameter(Mandatory = $true)]
65+
[string[]]$TestFilters
66+
)
67+
68+
if (-not $NoBuild) {
69+
Write-Output "Building $Name render tests..."
70+
71+
$buildArgs = @{
72+
Configuration = $Configuration
73+
Project = $BuildProject
74+
Verbosity = $Verbosity
75+
}
76+
77+
if ($SkipDependencyCheck) {
78+
$buildArgs['SkipDependencyCheck'] = $true
79+
}
80+
81+
& $buildScript @buildArgs
82+
if ($LASTEXITCODE -ne 0) {
83+
throw "$Name render build failed with exit code $LASTEXITCODE."
84+
}
85+
}
86+
87+
foreach ($testFilter in $TestFilters) {
88+
Write-Output "Running $Name render tests with filter '$testFilter'..."
89+
90+
$testArgs = @{
91+
Configuration = $Configuration
92+
TestProject = $TestProject
93+
TestFilter = $testFilter
94+
Verbosity = $Verbosity
95+
NoBuild = $true
96+
SkipDependencyCheck = $true
97+
}
98+
99+
& $testScript @testArgs
100+
if ($LASTEXITCODE -ne 0) {
101+
throw "$Name render tests failed with exit code $LASTEXITCODE for filter '$testFilter'."
102+
}
103+
}
104+
105+
Write-Output "[OK] $Name render tests passed."
106+
}
107+
108+
foreach ($requestedScope in $requestedScopes) {
109+
switch ($requestedScope) {
110+
'DetailControls' {
111+
Invoke-RenderSuite `
112+
-Name 'DetailControls' `
113+
-BuildProject 'Src/Common/Controls/DetailControls/DetailControlsTests/DetailControlsTests.csproj' `
114+
-TestProject 'Src/Common/Controls/DetailControls/DetailControlsTests' `
115+
-TestFilters 'FullyQualifiedName~DataTreeRenderTests'
116+
}
117+
'RootSite' {
118+
Invoke-RenderSuite `
119+
-Name 'RootSite' `
120+
-BuildProject 'Src/Common/RootSite/RootSiteTests/RootSiteTests.csproj' `
121+
-TestProject 'Src/Common/RootSite/RootSiteTests' `
122+
-TestFilters @(
123+
'FullyQualifiedName~RenderBaselineTests',
124+
'FullyQualifiedName~RenderTimingSuiteTests',
125+
'FullyQualifiedName~RenderVerifyTests'
126+
)
127+
}
128+
}
129+
}
130+
131+
Write-Output 'All requested render suites passed.'

FieldWorks.sln

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DetailControls", "Src\Commo
1818
EndProject
1919
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DetailControlsTests", "Src\Common\Controls\DetailControls\DetailControlsTests\DetailControlsTests.csproj", "{36F2A7A6-C7F9-5D3D-87D7-B4C0D5C51C0E}"
2020
EndProject
21+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderTestInfrastructure", "Src\Common\RenderTestInfrastructure\RenderTestInfrastructure.csproj", "{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}"
22+
EndProject
23+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderVerification", "Src\Common\RenderVerification\RenderVerification.csproj", "{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}"
24+
EndProject
2125
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discourse", "Src\LexText\Discourse\Discourse.csproj", "{A51BAFC3-1649-584D-8D25-101884EE9EAA}"
2226
EndProject
2327
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscourseTests", "Src\LexText\Discourse\DiscourseTests\DiscourseTests.csproj", "{1CE6483D-5D10-51AD-B2A7-FD7F82CCBAB2}"
@@ -335,6 +339,18 @@ Global
335339
{36F2A7A6-C7F9-5D3D-87D7-B4C0D5C51C0E}.Debug|x64.Build.0 = Debug|x64
336340
{36F2A7A6-C7F9-5D3D-87D7-B4C0D5C51C0E}.Release|x64.ActiveCfg = Release|x64
337341
{36F2A7A6-C7F9-5D3D-87D7-B4C0D5C51C0E}.Release|x64.Build.0 = Release|x64
342+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Bounds|x64.ActiveCfg = Release|x64
343+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Bounds|x64.Build.0 = Release|x64
344+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Debug|x64.ActiveCfg = Debug|x64
345+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Debug|x64.Build.0 = Debug|x64
346+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Release|x64.ActiveCfg = Release|x64
347+
{B53C715F-2F97-4E2B-9C10-5BFF1C04A446}.Release|x64.Build.0 = Release|x64
348+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Bounds|x64.ActiveCfg = Release|x64
349+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Bounds|x64.Build.0 = Release|x64
350+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Debug|x64.ActiveCfg = Debug|x64
351+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Debug|x64.Build.0 = Debug|x64
352+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Release|x64.ActiveCfg = Release|x64
353+
{6F7A4D9C-5B44-4D0E-ABAA-8D6F38F30C6A}.Release|x64.Build.0 = Release|x64
338354
{A51BAFC3-1649-584D-8D25-101884EE9EAA}.Bounds|x64.ActiveCfg = Release|x64
339355
{A51BAFC3-1649-584D-8D25-101884EE9EAA}.Bounds|x64.Build.0 = Release|x64
340356
{A51BAFC3-1649-584D-8D25-101884EE9EAA}.Debug|x64.ActiveCfg = Debug|x64

0 commit comments

Comments
 (0)