Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(dotnet fsi *)",
"Bash(./build.cmd RunCSharpTestsFast)",
"Bash(./build.cmd Build)"
]
}
}
116 changes: 116 additions & 0 deletions .claude/skills/chart-baseline-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: chart-baseline-generation
description: Use when working in Plotly.NET tests and you need to generate or refresh expected chart output values from real chart rendering instead of inventing assertion strings. This skill helps produce candidate data/layout/html baselines, extract stable segments, and convert investigated output into test expectations.
---

# Chart Baseline Generation

Use this skill when a Plotly.NET test needs an expected string derived from actual chart output.

## Goal

Generate the real chart output first, inspect it, then copy only the stable part into the test as the expected value.

Do not hand-write large expected strings from memory.

## Prerequisites: build the dependency first

The script loads Plotly.NET assemblies from `tests/ConsoleApps/CSharpConsole/bin/Debug/net10.0/`. Before running the script, verify that directory contains `Plotly.NET.dll` and `Plotly.NET.CSharp.dll`. If it is empty or the DLLs are missing, build them first via the FAKE pipeline:

```powershell
./build.cmd Build
```

Any of the `Run*TestsFast` targets also produce these assemblies as a side effect, so if you are about to run tests anyway you can skip the explicit build step.

If you edit sources in `src/Plotly.NET` or `src/Plotly.NET.CSharp` during the investigation, rebuild before re-running the script — `dotnet fsi` caches nothing for you here and stale DLLs silently produce wrong baselines.

## Default workflow

1. Ensure the dependency DLLs exist (see Prerequisites above); build them if missing.
2. Identify the chart fixture or chart-construction expression you want to validate.
3. Prefer an existing fixture from `tests/Common/FSharpTestBase/TestCharts/`.
4. If there is no suitable fixture, put a temporary focused chart expression into `tools/chart-baseline-generation/generate-chart-markup.fsx`.
5. Always use that script for both F# tests and C# tests.
6. For C# wrapper baselines, call `Plotly.NET.CSharp.Chart...` inside the F# script.
7. Keep `UseDefaults = false` on the chart to avoid noisy default template output.
8. Generate output with the same renderer the test uses:
- `GenericChart.toChartHTML` for shared chart html
- `GenericChart.toEmbeddedHTML` when the test is specifically about embedded output
9. Let the script print the stable sections you care about directly: `data`, `layout`, `config`, or `plotly-call`.
10. Inspect the generated section output and decide which part is stable enough to assert.
11. Copy the investigated value into the test.
12. Delete any temporary helper code before finishing.

## Where to generate output

Always use `tools/chart-baseline-generation/generate-chart-markup.fsx` as the investigation harness. Do not create or edit console app projects for this workflow.

Edit `createChart()` in `tools/chart-baseline-generation/generate-chart-markup.fsx`, run the script for the section you need, inspect the generated output, then revert the temporary chart expression when finished.

## How to run the script

Examples:

```powershell
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- data
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- layout
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- html
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- data --write-html temp/chart.html
```

By default, the script prints extracted stable sections to stdout and does not create temporary files.

Use `--write-html <output-path>` only when you explicitly want the full generated html on disk.

Pick the smallest local loop that matches the test you are editing:

- C# wrapper tests: `./build.cmd RunCSharpTestsFast`
- Core F# tests: `./build.cmd RunTestsCoreFast`
- Extension library tests: `./build.cmd RunTestsExtensionLibsFast`

Use the full `./build.cmd runTestsAll` before committing.

## Recommended temporary pattern

For a one-off investigation, edit `tools/chart-baseline-generation/generate-chart-markup.fsx` so it generates the chart you need, then run the script with the section you want to inspect.

Prefer temporary F# script code like:

```fsharp
let html = GenericChart.toChartHTML chart
```

For C# wrapper baselines, still use the same script and create the chart with `Plotly.NET.CSharp.Chart...`, then render it with:

```fsharp
let html = GenericChart.toChartHTML chart
```

Do not leave exploratory printouts or file dumps in committed script code.

Do not create extra helper files for this workflow unless there is a strong reason. Prefer modifying `tools/chart-baseline-generation/generate-chart-markup.fsx` directly and then reverting the temporary code.

## What to assert

Prefer the smallest stable assertion that proves the behavior:

- full `var data = ...;` block when validating trace serialization
- full `var layout = ...;` block when validating layout generation
- a small but meaningful substring only when the full block is too brittle

Avoid asserting volatile values such as generated DOM ids.

The unified script can print sections by label:

- `data`
- `layout`
- `config`
- `plotly-call`

## Investigation rules

- Treat generated output as a candidate baseline, not automatically correct truth.
- Compare the output with the API intent and nearby F# tests before adopting it.
- If the output looks surprising, stop and investigate the chart construction rather than locking in a wrong baseline.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#load "../../../../tools/chart-baseline-generation/generate-chart-markup.fsx"
116 changes: 116 additions & 0 deletions .codex/skills/chart-baseline-generation/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: chart-baseline-generation
description: Use when working in Plotly.NET tests and you need to generate or refresh expected chart output values from real chart rendering instead of inventing assertion strings. This skill helps agents produce candidate data/layout/html baselines, extract stable segments, and convert investigated output into test expectations.
---

# Chart Baseline Generation

Use this skill when a Plotly.NET test needs an expected string derived from actual chart output.

## Goal

Generate the real chart output first, inspect it, then copy only the stable part into the test as the expected value.

Do not hand-write large expected strings from memory.

## Prerequisites: build the dependency first

The script loads Plotly.NET assemblies from `tests/ConsoleApps/CSharpConsole/bin/Debug/net10.0/`. Before running the script, verify that directory contains `Plotly.NET.dll` and `Plotly.NET.CSharp.dll`. If it is empty or the DLLs are missing, build them first via the FAKE pipeline:

```powershell
./build.cmd Build
```

Any of the `Run*TestsFast` targets also produce these assemblies as a side effect, so if you are about to run tests anyway you can skip the explicit build step.

If you edit sources in `src/Plotly.NET` or `src/Plotly.NET.CSharp` during the investigation, rebuild before re-running the script — `dotnet fsi` caches nothing for you here and stale DLLs silently produce wrong baselines.

## Default workflow

1. Ensure the dependency DLLs exist (see Prerequisites above); build them if missing.
2. Identify the chart fixture or chart-construction expression you want to validate.
3. Prefer an existing fixture from `tests/Common/FSharpTestBase/TestCharts/`.
4. If there is no suitable fixture, put a temporary focused chart expression into `tools/chart-baseline-generation/generate-chart-markup.fsx`.
5. Always use that script for both F# tests and C# tests.
6. For C# wrapper baselines, call `Plotly.NET.CSharp.Chart...` inside the F# script.
7. Keep `UseDefaults = false` on the chart to avoid noisy default template output.
8. Generate output with the same renderer the test uses:
- `GenericChart.toChartHTML` for shared chart html
- `GenericChart.toEmbeddedHTML` when the test is specifically about embedded output
9. Let the script print the stable sections you care about directly: `data`, `layout`, `config`, or `plotly-call`.
10. Inspect the generated section output and decide which part is stable enough to assert.
11. Copy the investigated value into the test.
12. Delete any temporary helper code before finishing.

## Where to generate output

Always use `tools/chart-baseline-generation/generate-chart-markup.fsx` as the investigation harness. Do not create or edit console app projects for this workflow.

Edit `createChart()` in `tools/chart-baseline-generation/generate-chart-markup.fsx`, run the script for the section you need, inspect the generated output, then revert the temporary chart expression when finished.

## How to run the script

Examples:

```powershell
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- data
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- layout
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- html
dotnet fsi tools/chart-baseline-generation/generate-chart-markup.fsx -- data --write-html temp/chart.html
```

By default, the script prints extracted stable sections to stdout and does not create temporary files.

Use `--write-html <output-path>` only when you explicitly want the full generated html on disk.

Pick the smallest local loop that matches the test you are editing:

- C# wrapper tests: `./build.cmd RunCSharpTestsFast`
- Core F# tests: `./build.cmd RunTestsCoreFast`
- Extension library tests: `./build.cmd RunTestsExtensionLibsFast`

Use the full `./build.cmd runTestsAll` before committing.

## Recommended temporary pattern

For a one-off investigation, edit `tools/chart-baseline-generation/generate-chart-markup.fsx` so it generates the chart you need, then run the script with the section you want to inspect.

Prefer temporary F# script code like:

```fsharp
let html = GenericChart.toChartHTML chart
```

For C# wrapper baselines, still use the same script and create the chart with `Plotly.NET.CSharp.Chart...`, then render it with:

```fsharp
let html = GenericChart.toChartHTML chart
```

Do not leave exploratory printouts or file dumps in committed script code.

Do not create extra helper files for this workflow unless there is a strong reason. Prefer modifying `tools/chart-baseline-generation/generate-chart-markup.fsx` directly and then reverting the temporary code.

## What to assert

Prefer the smallest stable assertion that proves the behavior:

- full `var data = ...;` block when validating trace serialization
- full `var layout = ...;` block when validating layout generation
- a small but meaningful substring only when the full block is too brittle

Avoid asserting volatile values such as generated DOM ids.

The unified script can print sections by label:

- `data`
- `layout`
- `config`
- `plotly-call`

## Investigation rules

- Treat generated output as a candidate baseline, not automatically correct truth.
- Compare the output with the API intent and nearby F# tests before adopting it.
- If the output looks surprising, stop and investigate the chart construction rather than locking in a wrong baseline.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#load "../../../../tools/chart-baseline-generation/generate-chart-markup.fsx"
37 changes: 37 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generic devcontainer base; .NET 10 SDK is layered on via the dotnet feature
# in devcontainer.json (the dedicated dotnet:10.0 devcontainer image isn't
# published yet — pinned via global.json rollForward once installed).
FROM mcr.microsoft.com/devcontainers/base:bookworm

# System deps for Plotly.NET.ImageExport tests (PuppeteerSharp downloads its own
# Chromium at runtime, but needs these shared libraries and fonts to launch it).
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libexpat1 \
libgbm1 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
xdg-utils \
&& rm -rf /var/lib/apt/lists/*
39 changes: 39 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "Plotly.NET agent sandbox",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/dotnet:2": {
"version": "10.0",
"installUsingApt": false
},
"ghcr.io/devcontainers/features/node:1": {
"version": "lts"
},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"remoteUser": "vscode",
"containerEnv": {
"DOTNET_CLI_TELEMETRY_OPTOUT": "1",
"DOTNET_NOLOGO": "1",
"NUGET_XMLDOC_MODE": "skip",
"PUPPETEER_SKIP_CHROMIUM_DOWNLOAD": "true"
},
"postCreateCommand": "bash .devcontainer/postCreate.sh",
"mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.claude,target=/home/vscode/.claude,type=bind,consistency=cached",
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.claude.json,target=/home/vscode/.claude.json,type=bind,consistency=cached",
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.codex,target=/home/vscode/.codex,type=bind,consistency=cached"
],
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.csdevkit",
"ionide.ionide-fsharp",
"anthropic.claude-code",
"openai.chatgpt"
]
}
}
}
30 changes: 30 additions & 0 deletions .devcontainer/postCreate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail

echo "==> Restoring dotnet local tools (fantomas, fsdocs)"
dotnet tool restore

echo "==> Warming up NuGet restore for the main solution"
dotnet restore Plotly.NET.sln || true

echo "==> Installing agent CLIs globally (Claude Code + Codex)"
npm install -g \
@anthropic-ai/claude-code \
@openai/codex \
opencode-ai@latest

echo "==> Aliasing agent CLIs to skip approvals (sandbox is the devcontainer itself)"
cat >> ~/.bashrc <<'EOF'

# devcontainer: agent CLIs skip approvals since the container IS the sandbox
alias claude='claude --dangerously-skip-permissions'
alias codex='codex --dangerously-bypass-approvals-and-sandbox'
EOF

chmod +x build.sh

echo "==> Done. Verify with:"
echo " ./build.sh # default build target"
echo " ./build.sh RunTestsAllFast"
echo " claude --version"
echo " codex --version"
Loading
Loading