Files
dotnet__skills/tests/dotnet-blazor/support-prerendering/eval.vally.yaml
Javier Calvarro Nelson 9ed853bffc Port dotnet-blazor evals to Vally format (#843)
Adds eval.vally.yaml for all 9 dotnet-blazor skills, converted from the legacy skill-validator eval.yaml specs, and registers a dotnet-blazor suite in .vally.yaml so the shadow Vally pipeline discovers them.

Conversion preserves prompts, assertions, and rubric verbatim. Legacy setup blocks map to Vally environment config: 'dotnet new' scaffolding commands become environment.commands. Verified end-to-end by running the author-component eval (baseline + skilled + adapt), which passed the shadow threshold.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 10:03:31 -07:00

82 lines
3.8 KiB
YAML

name: support-prerendering
description: Evaluates the dotnet-blazor/support-prerendering skill
type: capability
config:
timeout: 10m
stimuli:
- name: Equipment inventory loaded once
prompt: |
I have an existing Blazor Web App with Interactive Server (per-page).
I need an interactive /inventory page that shows a table of equipment items
(Id, Name, Location, LastInspected date). The data comes from an EquipmentService
you should create (just return fake data, 5-10 items).
The page should show "Loading inventory..." until data is ready, then display
the table. The important thing is that when the page first loads I see the HTML
instantly (fast initial paint), but the equipment data should NOT be fetched
twice — once during the initial server render and again when the page becomes
interactive. It should only call the service once and carry that data across.
graders:
- type: file-exists
config:
path: '**/Inventory.razor'
- type: file-contains
config:
path: '**/Inventory.razor'
value: PersistentState
- type: file-contains
config:
path: '**/Inventory.razor'
value: InteractiveServer
- type: file-contains
config:
path: '**/Inventory.razor'
value: '??='
- type: prompt
- type: pairwise
rubric:
- Data persists across the prerender-to-interactive handoff — uses state persistence ([PersistentState] or PersistentComponentState) with ??= pattern to avoid duplicate data fetches
- Component correctly shows loading state when data is null, then displays the equipment table when loaded
- Does NOT disable prerendering — preserves the fast initial HTML response while avoiding duplicate loads
- Creates a proper EquipmentService registered in DI, not inline data generation
- name: Notifications page with live polling
prompt: |
I have an existing Blazor Web App with Interactive Server (per-page).
I need an interactive /notifications page that:
- Loads an initial set of notifications from a NotificationService (create it with fake data)
- After the page becomes interactive, starts a background polling loop that
checks for new notifications every 5 seconds and updates the UI
- Shows a notification count badge and a list of notification messages
Important constraints:
- The initial notifications should appear in the fast server-rendered HTML
and NOT be fetched again when the page becomes interactive
- The polling loop must not run during the initial server render — only after
the page is live and interactive in the browser
- When the user navigates away, the polling should stop cleanly (no leaked tasks)
graders:
- type: file-exists
config:
path: '**/Notifications.razor'
- type: file-contains
config:
path: '**/Notifications.razor'
value: RendererInfo.IsInteractive
- type: file-contains
config:
path: '**/Notifications.razor'
value: PersistentState
- type: file-contains
config:
path: '**/Notifications.razor'
value: InteractiveServer
- type: prompt
- type: pairwise
rubric:
- Guards the polling loop so it only runs when the component is interactive — not during prerendering
- Persists initial notification data across the prerender-to-interactive handoff so the service is not called twice
- Polling uses an async loop with CancellationTokenSource, cancelled in DisposeAsync — not System.Threading.Timer
- Component implements IAsyncDisposable and cancels the polling token in DisposeAsync to prevent resource leaks