# How to Test Components in ArcKit: Complete Guide to the Paperclip Test Suite

> Learn how to test components in ArcKit using the Paperclip test suite. Generate artifacts with converter.py and run pytest to validate command objects against the schema.

- Repository: [tractorjuice/arc-kit](https://github.com/tractorjuice/arc-kit)
- Tags: how-to-guide
- Published: 2026-04-19

---

**Run `python scripts/converter.py` to generate the Paperclip artifacts, then execute `pytest` to validate the 68 command objects against the schema in [`tests/paperclip/test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/paperclip/test_commands_json.py).**

Testing components in ArcKit ensures that the AI‑assistant command pipeline produces valid, consistent outputs across different formats. The repository maintains a focused test suite that validates the **Paperclip** generation workflow—the core conversion logic shared by all ArcKit targets.

## Understanding the ArcKit Test Architecture

ArcKit’s testing strategy centers on artifact validation rather than heavy unit testing. The suite verifies that the converter script correctly transforms Claude‑specific markdown sources into generic JSON commands.

### The Paperclip Generation Pipeline

The **converter** ([`scripts/converter.py`](https://github.com/tractorjuice/arc-kit/blob/main/scripts/converter.py)) drives the testing workflow. It processes markdown files in `arckit-claude/commands/`, strips Claude‑only front‑matter, rewrites paths such as `${CLAUDE_PLUGIN_ROOT}` to Paperclip‑compatible locations, and injects **handoffs** that define command chaining. The output lands in [`arckit-paperclip/src/data/commands.json`](https://github.com/tractorjuice/arc-kit/blob/main/arckit-paperclip/src/data/commands.json).

### Test File Location and Structure

The only test file resides at [`tests/paperclip/test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/paperclip/test_commands_json.py). It contains **eleven test functions** that load the generated JSON and assert structural integrity. The test expects exactly **68 command objects**, each conforming to a strict schema required by all AI‑assistant formats.

## How to Test ArcKit Components Step‑by‑Step

Executing the test suite requires regenerating the Paperclip artifacts first, then running the validation.

### Generate the Paperclip JSON Artifacts

Before testing, ensure the converter has built the latest command definitions:

```bash

# From the repository root

python scripts/converter.py

```

This invokes `build_agent_map()` to index all `arckit-*.md` files, `extract_frontmatter_and_prompt()` to parse metadata, `rewrite_paths()` to neutralize Claude‑specific placeholders, and `render_handoffs_section()` to add command‑chaining metadata. The final `format_json_entry()` call writes the array to [`arckit-paperclip/src/data/commands.json`](https://github.com/tractorjuice/arc-kit/blob/main/arckit-paperclip/src/data/commands.json).

### Execute the Test Suite

With the JSON in place, run the validation using **pytest**:

```bash

# Install pytest if not already present

pip install pytest

# Run the suite

pytest

```

The runner discovers [`tests/paperclip/test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/paperclip/test_commands_json.py) and executes all eleven assertions. Successful output appears as:

```

============================= test session starts ==============================
collected 1 item

tests/paperclip/test_commands_json.py .                              [100%]

============================== 1 passed in X.XXs ==============================

```

### Verify Individual Command Objects

For manual inspection of a specific command, load the JSON directly:

```python
import json
import pathlib
import pprint

cmds_path = pathlib.Path('arckit-paperclip/src/data/commands.json')
commands = json.load(cmds_path.open())

# Inspect the "arckit-requirements" command

req = next(c for c in commands if c['name'] == 'arckit-requirements')
pprint.pprint(req)

```

This reveals the rewritten **prompt** paths, the **template** field, and the **handoffs** array containing command suggestions with `arckit-` prefixes.

## What the Test Suite Validates

The assertions in [`test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/test_commands_json.py) enforce the contract between ArcKit’s converter and downstream AI assistants:

- **File existence**: Verifies `os.path.isfile(COMMANDS_JSON_PATH)` ensures the conversion step produced output.
- **Command count**: Asserts `len(commands) == 68` to confirm the full toolkit is present.
- **Schema compliance**: Checks that each object contains the mandatory fields `name`, `description`, `prompt`, `template`, and `handoffs`.
- **Naming conventions**: Validates that every `name` starts with `arckit-` and that names are unique.
- **Content integrity**: Ensures descriptions and prompts are non‑empty strings.
- **Placeholder removal**: Confirms that `${CLAUDE_PLUGIN_ROOT}` does not remain in the prompt after conversion.
- **Handoff structure**: Verifies each handoff entry includes a `command` (prefixed with `arckit-`) and a `description`.

## Continuous Integration Setup

ArcKit automates testing via **GitHub Actions**. The workflow defined in [`.github/workflows/lint-markdown.yml`](https://github.com/tractorjuice/arc-kit/blob/main/.github/workflows/lint-markdown.yml) triggers on every push, regenerating the Paperclip JSON and executing `pytest` to ensure continuous correctness. Adding new tests for additional components—such as CLI initialization logic—follows the same pattern: create a module under `tests/`, import the target logic, and assert its behavior.

## Summary

- **Run `python scripts/converter.py`** to generate the Paperclip JSON artifacts before testing.
- **Execute `pytest`** to validate the 68 command objects in [`tests/paperclip/test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/paperclip/test_commands_json.py).
- The test enforces **schema compliance**, **naming conventions** (`arckit-` prefix), and **placeholder removal** (`${CLAUDE_PLUGIN_ROOT}`).
- **CI/CD integration** via [`.github/workflows/lint-markdown.yml`](https://github.com/tractorjuice/arc-kit/blob/main/.github/workflows/lint-markdown.yml) ensures tests run automatically on every push.

## Frequently Asked Questions

### What is the Paperclip format in ArcKit?

**Paperclip** is ArcKit’s generic JSON representation of slash commands, designed to work across multiple AI assistants. The format strips Claude‑specific metadata and rewrites paths so that commands can be consumed by Paperclip‑compatible hosts. The converter script generates this format in [`arckit-paperclip/src/data/commands.json`](https://github.com/tractorjuice/arc-kit/blob/main/arckit-paperclip/src/data/commands.json).

### How do I add new tests for ArcKit components?

Create a Python file under `tests/` that imports your component logic and uses `pytest` assertions. For example, to test CLI initialization, add [`tests/cli/test_init.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/cli/test_init.py) and assert that `arckit init` produces the expected directory structure. The existing `tests/paperclip/` module serves as a reference for schema‑validation patterns.

### Why does the test check for exactly 68 command objects?

The number **68** represents the complete set of slash commands shipped with ArcKit. This assertion acts as a regression guard: if the converter produces fewer or more commands, it signals that a command file was accidentally omitted or duplicated during the build process.

### Can I run tests without generating the JSON first?

**No.** The test file [`tests/paperclip/test_commands_json.py`](https://github.com/tractorjuice/arc-kit/blob/main/tests/paperclip/test_commands_json.py) imports and inspects [`arckit-paperclip/src/data/commands.json`](https://github.com/tractorjuice/arc-kit/blob/main/arckit-paperclip/src/data/commands.json) directly. If the JSON is missing or stale, the test fails immediately with a file‑not‑found error. Always run `python scripts/converter.py` before `pytest` to ensure the test data reflects the current command definitions.