Skip to content
Merged

Dev #291

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
130 changes: 130 additions & 0 deletions .agents/skills/duc-fixtures/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
name: duc-fixtures
description: >
Use this skill whenever fetching, referencing, or adding test fixtures and binary assets from
the ducflair/fixtures repository. Triggers when using CDN/raw GitHub fallback utilities, loading
sample files (.pdf, .ifc, .dxf, .stp, .jpg, .png, .duc) in tests or examples, or managing assets
in the monorepo's assets/testing directory.
---

# Using Fixtures from `ducflair/fixtures`

The `ducflair/fixtures` repository ([github.com/ducflair/fixtures](https://github.com/ducflair/fixtures)) hosts binary test assets (PDFs, 3D CAD models, images, sample `.duc` databases) to avoid bloating the core `duc` monorepo git history.

---

## 1. Asset Storage & Path Structure

Fixtures live under the `src/` directory of `ducflair/fixtures`, organized by file category:

```
ducflair/fixtures/src/
├── pdf-files/
│ └── test.pdf
├── ifc-files/
│ └── NVW_DCR-LOD100_Arch.ifc
├── dxf-files/
│ └── columns_R2007.dxf
├── step-files/
│ └── cis/MainSteel_structural.stp
├── png-files/
│ ├── thumbnail.png
│ └── infinite-zoom-math.png
├── jpeg-files/
│ └── test.jpg
└── duc-files/
└── universal.duc
```

---

## 2. CDN & Fallback Resolution Strategy

When loading remote fixtures dynamically:

1. **Primary CDN (jsDelivr)**:
`https://cdn.jsdelivr.net/gh/ducflair/fixtures@main/src/<path>`
Fast, edge-cached delivery for general test runs, demos, and examples.
2. **Fallback (GitHub Raw)**:
`https://raw.githubusercontent.com/ducflair/fixtures/main/src/<path>`
Used automatically if jsDelivr returns a non-2xx status or an error response (such as jsDelivr's HTTP 200 text response for files exceeding 20 MB).
3. **Local Cache (`assets/testing/`)**:
Local monorepo tests check for relative paths under `duc/assets/testing/<path>` first before falling back to network fetch (`prefer_local=True`).

---

## 3. Usage in Python (`ducpy`)

In `ducpy`, import helper utilities from `_dev.dev_utils`:

```python
from _dev.dev_utils import (
get_asset_bytes, # Prefers local assets/testing/<path>, falls back to CDN
download_fixture_from_cdn, # Downloads directly from CDN with GitHub raw fallback
)

# Fetch binary content:
pdf_bytes = download_fixture_from_cdn("pdf-files/test.pdf")
ifc_bytes = get_asset_bytes("ifc-files/NVW_DCR-LOD100_Arch.ifc", prefer_local=True)
```

In `pytest` suites (`conftest.py`), use the `load_test_asset` fixture:

```python
def test_my_feature(load_test_asset):
pdf_bytes = load_test_asset("pdf-files/test.pdf")
...
```

---

## 4. Usage in TypeScript / JavaScript & Rust

### TypeScript (`ducjs` / `ducpdf` / `ducsvg`)

For local monorepo integration tests:
```ts
import { join } from "path";
const fixturePath = join(__dirname, "../../../assets/testing/duc-files/universal.duc");
```

For dynamic fetch in runtime environments:
```ts
async function fetchFixture(relativePath: string): Promise<Uint8Array> {
const primaryUrl = `https://cdn.jsdelivr.net/gh/ducflair/fixtures@main/src/${relativePath}`;
const rawUrl = `https://raw.githubusercontent.com/ducflair/fixtures/main/src/${relativePath}`;

try {
const res = await fetch(primaryUrl);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buf = await res.arrayBuffer();
const textPrefix = new TextDecoder().decode(buf.slice(0, 30));
if (textPrefix.startsWith("File size exceeded") || textPrefix.startsWith("Package size exceeded")) {
const rawRes = await fetch(rawUrl);
return new Uint8Array(await rawRes.arrayBuffer());
}
return new Uint8Array(buf);
} catch {
const rawRes = await fetch(rawUrl);
return new Uint8Array(await rawRes.arrayBuffer());
}
}
```

### Rust (`ducrs`)

For local monorepo integration tests:
```rust
use std::path::PathBuf;

let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../assets/testing/duc-files/universal.duc");
```

---

## 5. Adding New Fixtures

1. Push your test asset to the `ducflair/fixtures` repository under `src/<type>-files/<name>`.
2. Once merged to `main`, the file is immediately available via jsDelivr CDN and raw GitHub.
3. If needed for offline test suites, copy key fixtures into `assets/testing/<type>-files/<name>` inside the `duc` monorepo. For multi-gigabyte `.duc` fixtures, stream external-file revisions into chunk rows instead of using an in-memory serializer; verify element/file/revision counts, revision and chunk byte totals, foreign keys, SQLite integrity, and the final gzip container.
1 change: 1 addition & 0 deletions .agents/skills/duc-schema-changes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ If the schema itself changed (new columns, tables, type modifications), create a
5. When repairing a migration that may already have failed in the field, clean up its known partial DDL artifacts and test retrying from that partial state
6. If existing readers cannot open the new file format or a published API is removed, evaluate a major schema version rather than a patch increment
7. When promoting a prerelease schema to a major version, retain its natural sequential migration, add a final explicit major-version bridge, and scan checked-in fixtures for every represented `user_version`
8. Keep registry tests for a unique contiguous forward path and transactional `user_version` updates, and migrate checked-in `.duc` fixtures through both session and byte-buffer open paths

```bash
ls -1 duc/schema/migrations/ | sort | tail -5 # see last migrations
Expand Down
Loading
Loading