AnasSarkiz/magnetic-shutter-remote-r8

A USB‑C rechargeable battery-powered ESP32‑C3 wireless controller with Li‑ion charging, protected 3.3‑V buck‑boost regulation, thermal/safety monitoring, status LEDs, buttons, programming UART, crystal clock, and 2.4‑GHz antenna matching network.

Version
0.4.0-prototype
License
unset
Stars
0

tests/r9-bare-chip.test.ts

import { expect, test } from "bun:test";
import { any_circuit_element } from "circuit-json";
import { auditBareChip } from "../scripts/audit-r9-circuit";
const circuit = any_circuit_element
	.array()
	.parse(await Bun.file("dist/index/circuit.json").json());

test("bare chip retains independent pin, supply, boot and programmer contracts", () => {
	expect(auditBareChip(circuit)).toMatchObject({
		stage: "schematic-only",
		fittedReferences: 63,
		chipPads: 33,
		physicalQualification: "pending",
	});
});

test("internal flash supply cannot be shorted to external 3V3", () => {
	const modified = structuredClone(circuit);
	const chip = modified.find(
		(e) => e.type === "source_component" && e.name === "U1",
	);
	if (!chip || chip.type !== "source_component") throw new Error("Missing U1");
	const flash = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 18,
	);
	const supply = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 17,
	);
	if (
		!flash ||
		flash.type !== "source_port" ||
		!supply ||
		supply.type !== "source_port"
	)
		throw new Error("Missing power pins");
	flash.subcircuit_connectivity_map_key =
		supply.subcircuit_connectivity_map_key;
	expect(() => auditBareChip(modified)).toThrow("U1.pin18: expected FLASH_VDD");
});

test("reserved in-package flash pins cannot be marked available", () => {
	const modified = structuredClone(circuit);
	const chip = modified.find(
		(e) => e.type === "source_component" && e.name === "U1",
	);
	if (!chip || chip.type !== "source_component") throw new Error("Missing U1");
	const pin = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 22,
	);
	if (!pin || pin.type !== "source_port") throw new Error("Missing SPICLK");
	pin.do_not_connect = false;
	expect(() => auditBareChip(modified)).toThrow(
		"U1.pin22: reserved/unused pin must remain unconnected",
	);
});

test("UART RX/TX cannot be swapped at the chip", () => {
	const modified = structuredClone(circuit);
	const chip = modified.find(
		(e) => e.type === "source_component" && e.name === "U1",
	);
	if (!chip || chip.type !== "source_component") throw new Error("Missing U1");
	const rx = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 27,
	);
	const tx = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 28,
	);
	if (!rx || rx.type !== "source_port" || !tx || tx.type !== "source_port")
		throw new Error("Missing UART");
	[rx.subcircuit_connectivity_map_key, tx.subcircuit_connectivity_map_key] = [
		tx.subcircuit_connectivity_map_key,
		rx.subcircuit_connectivity_map_key,
	];
	expect(() => auditBareChip(modified)).toThrow("U1.pin27: expected UART_RX");
});

test("every external supply pin must carry the datasheet power metadata", () => {
	const modified = structuredClone(circuit);
	const chip = modified.find(
		(e) => e.type === "source_component" && e.name === "U1",
	);
	if (!chip || chip.type !== "source_component") throw new Error("Missing U1");
	const pin = modified.find(
		(e) =>
			e.type === "source_port" &&
			e.source_component_id === chip.source_component_id &&
			e.pin_number === 11,
	);
	if (!pin || pin.type !== "source_port") throw new Error("Missing RTC power");
	pin.requires_power = false;
	expect(() => auditBareChip(modified)).toThrow(
		"U1.pin11: power metadata missing",
	);
});