tscircuit/ti
ti tscircuit library
- Version
- 1.0.191
- License
- unset
- Stars
- 0
tests/PowerSupply_WindowModule.test.tsx
/// <reference types="bun-types" />
import { expect, setDefaultTimeout, test } from "bun:test";
import { Circuit } from "@tscircuit/core";
import type { AnyCircuitElement } from "circuit-json";
import type { ReactElement } from "react";
import "tscircuit";
import { PowerSupply_WindowModule } from "../lib/subcircuits/PowerSupply_WindowModule.circuit.tsx";
import { ReverseBatteryProtection_TLV1805_SQJ461EP } from "../lib/subcircuits/ReverseBatteryProtection_TLV1805_SQJ461EP.circuit.tsx";
import { SupervisorWatchdog_TPS3850 } from "../lib/subcircuits/SupervisorWatchdog_TPS3850.circuit.tsx";
import { VoltageRegulator_LM73605 } from "../lib/subcircuits/VoltageRegulator_LM73605.circuit.tsx";
setDefaultTimeout(30_000);
type CircuitElement = AnyCircuitElement & Record<string, unknown>;
const render = async (element: ReactElement): Promise<CircuitElement[]> => {
const originalError = console.error;
const originalWarn = console.warn;
const circuit = new Circuit({
platform: {
pcbDisabled: true,
routingDisabled: true,
partsEngineDisabled: true,
},
});
console.error = () => {};
console.warn = () => {};
try {
circuit.add(element);
await circuit.renderUntilSettled();
return circuit.getCircuitJson() as CircuitElement[];
} finally {
console.error = originalError;
console.warn = originalWarn;
}
};
const component = (circuitJson: CircuitElement[], name: string) => {
const matches = circuitJson.filter(
(element) => element.type === "source_component" && element.name === name,
);
expect(matches, `source component ${name}`).toHaveLength(1);
return matches[0];
};
const schematicComponentFor = (
circuitJson: CircuitElement[],
componentName: string,
) => {
const sourceComponent = component(circuitJson, componentName);
const match = circuitJson.find(
(element) =>
element.type === "schematic_component" &&
element.source_component_id === sourceComponent.source_component_id,
);
expect(match, `schematic component ${componentName}`).toBeDefined();
return match!;
};
const port = (
circuitJson: CircuitElement[],
componentName: string,
pinNumber: number,
) => {
const sourceComponent = component(circuitJson, componentName);
const match = circuitJson.find(
(element) =>
element.type === "source_port" &&
element.source_component_id === sourceComponent.source_component_id &&
element.pin_number === pinNumber,
);
expect(match, `${componentName}.${pinNumber}`).toBeDefined();
return match!;
};
const schematicPort = (
circuitJson: CircuitElement[],
componentName: string,
pinNumber: number,
schematicComponentName = componentName,
) => {
const schematicComponent = schematicComponentFor(
circuitJson,
schematicComponentName,
);
const sourcePortId = port(
circuitJson,
componentName,
pinNumber,
).source_port_id;
const match = circuitJson.find(
(element) =>
element.type === "schematic_port" &&
element.schematic_component_id ===
schematicComponent.schematic_component_id &&
element.source_port_id === sourcePortId,
);
expect(
match,
`schematic port ${schematicComponentName}.${pinNumber}`,
).toBeDefined();
return match!;
};
const subcircuitPort = (
circuitJson: CircuitElement[],
subcircuitName: string,
portName: string,
) => {
const sourceGroup = circuitJson.find(
(element) =>
element.type === "source_group" && element.name === subcircuitName,
);
expect(sourceGroup, `source group ${subcircuitName}`).toBeDefined();
const match = circuitJson.find(
(element) =>
element.type === "source_port" &&
(element.source_component_id === null ||
element.source_component_id === undefined) &&
element.subcircuit_id === sourceGroup!.subcircuit_id &&
element.name === portName,
);
expect(match, `${subcircuitName}.${portName}`).toBeDefined();
return match!;
};
const assertSubcircuitTrace = (
circuitJson: CircuitElement[],
from: [subcircuitName: string, portName: string],
to: [subcircuitName: string, portName: string],
) => {
const fromPort = subcircuitPort(circuitJson, ...from);
const toPort = subcircuitPort(circuitJson, ...to);
const fromPortId = String(fromPort.source_port_id);
const toPortId = String(toPort.source_port_id);
const match = circuitJson.find(
(element) =>
element.type === "source_trace" &&
Array.isArray(element.connected_source_port_ids) &&
element.connected_source_port_ids.includes(fromPortId) &&
element.connected_source_port_ids.includes(toPortId),
);
expect(match, `${from[0]}.${from[1]} to ${to[0]}.${to[1]}`).toBeDefined();
};
const assertSubcircuitPortNet = (
circuitJson: CircuitElement[],
subcircuitName: string,
portName: string,
netName: string,
) => {
const groupPort = subcircuitPort(circuitJson, subcircuitName, portName);
const sourceNet = circuitJson.find(
(element) =>
element.type === "source_net" &&
element.name === netName &&
element.subcircuit_id === groupPort.subcircuit_id,
);
expect(sourceNet, `${subcircuitName} net ${netName}`).toBeDefined();
const groupPortId = String(groupPort.source_port_id);
const sourceNetId = String(sourceNet!.source_net_id);
const portTraces = circuitJson.filter(
(element) =>
element.type === "source_trace" &&
Array.isArray(element.connected_source_port_ids) &&
element.connected_source_port_ids.includes(groupPortId),
);
const netTraces = circuitJson.filter(
(element) =>
element.type === "source_trace" &&
Array.isArray(element.connected_source_net_ids) &&
element.connected_source_net_ids.includes(sourceNetId),
);
const sharedPortId = portTraces.some((portTrace) => {
const portSourceIds = portTrace.connected_source_port_ids as string[];
return netTraces.some((netTrace) => {
const netSourceIds = netTrace.connected_source_port_ids as string[];
return portSourceIds.some((sourcePortId) =>
netSourceIds.includes(sourcePortId),
);
});
});
expect(
sharedPortId,
`${subcircuitName}.${portName} to local ${netName}`,
).toBe(true);
};
const assertNet = (
circuitJson: CircuitElement[],
netName: string,
endpoints: Array<[componentName: string, pinNumber: number]>,
) => {
const firstPort = port(circuitJson, ...endpoints[0]);
const sourceNet = circuitJson.find(
(element) =>
element.type === "source_net" &&
element.name === netName &&
element.subcircuit_id === firstPort.subcircuit_id,
);
const namedTrace = circuitJson.find(
(element) =>
element.type === "source_trace" &&
element.name === netName &&
element.subcircuit_id === firstPort.subcircuit_id,
);
const expectedConnectivityKey =
sourceNet?.subcircuit_connectivity_map_key ??
namedTrace?.subcircuit_connectivity_map_key ??
firstPort.subcircuit_connectivity_map_key;
for (const endpoint of endpoints) {
expect(
port(circuitJson, ...endpoint).subcircuit_connectivity_map_key,
`${endpoint[0]}.${endpoint[1]} on ${netName}`,
).toBe(expectedConnectivityKey);
}
};
const expectNoCircuitErrors = (circuitJson: CircuitElement[]) => {
const errors = circuitJson.filter((element) =>
String(element.type).endsWith("_error"),
);
expect(errors).toEqual([]);
expect(
circuitJson.filter(
(element) =>
(element.type === "schematic_net_label" ||
element.type === "schematic_text") &&
element.text === "\u200B",
),
"zero-width placeholder labels",
).toEqual([]);
};
test("reverse-battery child preserves the TIDA-050008 sheet-2 netlist", async () => {
const circuitJson = await render(
<ReverseBatteryProtection_TLV1805_SQJ461EP name="reverseBattery" />,
);
expectNoCircuitErrors(circuitJson);
assertNet(circuitJson, "VBATT_PCH", [
["P1", 1],
["TP2", 1],
["Q1", 5],
["R1", 2],
["D2", 1],
["D1", 1],
["C24", 2],
]);
assertNet(circuitJson, "LED_RETURN", [
["D2", 2],
["R14", 2],
]);
assertNet(circuitJson, "EMI_CAP_MID", [
["C24", 1],
["C25", 1],
]);
assertNet(circuitJson, "VIN2", [
["Q1", 1],
["Q1", 2],
["Q1", 3],
["R4", 1],
["C4", 1],
["D5", 1],
["U1", 4],
["U1", 6],
["D6", 1],
["CF1", 1],
["C1", 1],
["C2", 1],
["FB1", 1],
]);
assertNet(circuitJson, "P_Gate", [
["Q1", 4],
["R4", 2],
["R2", 2],
]);
assertNet(circuitJson, "BATT_SENS_PCH", [
["R1", 1],
["D3", 1],
["U1", 3],
]);
assertNet(circuitJson, "FLT_GND_P", [
["D3", 2],
["C4", 2],
["D5", 2],
["U1", 2],
["U1", 5],
["D4", 2],
]);
assertNet(circuitJson, "CMP_OUT_PCH", [
["U1", 1],
["R2", 1],
]);
assertNet(circuitJson, "D4_R3", [
["D4", 1],
["R3", 2],
]);
assertNet(circuitJson, "FILTER_MID", [
["FB1", 2],
["CF2", 1],
["C3", 1],
["C8", 1],
["LF1", 1],
]);
assertNet(circuitJson, "GND", [
["P2", 1],
["TP7", 1],
["R14", 1],
["D1", 2],
["C25", 2],
["R3", 1],
["D6", 2],
["CF1", 2],
["C1", 2],
["C2", 2],
["CF2", 2],
["C3", 2],
["C8", 2],
]);
assertNet(circuitJson, "VIN1", [["LF1", 2]]);
expect(component(circuitJson, "Q1").manufacturer_part_number).toBe(
"SQJ461EP",
);
expect(component(circuitJson, "U1").manufacturer_part_number).toBe(
"TLV1805QDBVRQ1",
);
const q1Projection = component(circuitJson, "Q1_SCHEMATIC");
const q1Schematic = schematicComponentFor(circuitJson, "Q1_SCHEMATIC");
expect(q1Schematic.source_component_id).toBe(
q1Projection.source_component_id,
);
expect(q1Schematic?.symbol_name).toBe(
"p_channel_e_mosfet_transistor_gate_top_drain_left",
);
const u1Schematic = schematicComponentFor(circuitJson, "U1");
expect(u1Schematic?.is_box_with_pins).toBe(false);
const u1Size = u1Schematic.size as { width: number; height: number };
expect(u1Size.width).toBeLessThanOrEqual(1.5);
expect(u1Size.height).toBeLessThanOrEqual(1);
const u1Path = circuitJson.find(
(element) =>
element.type === "schematic_path" &&
element.schematic_component_id === u1Schematic?.schematic_component_id,
);
expect(u1Path).toBeDefined();
const pathPoints = u1Path!.points as Array<{ x: number; y: number }>;
const expectStemOnEdge = (
pinNumber: number,
edge: [{ x: number; y: number }, { x: number; y: number }],
) => {
const schematicPort = circuitJson.find(
(element) =>
element.type === "schematic_port" &&
element.schematic_component_id === u1Schematic.schematic_component_id &&
element.pin_number === pinNumber,
)!;
const center = schematicPort.center as { x: number; y: number };
const stem = circuitJson.find(
(element) =>
element.type === "schematic_line" &&
element.schematic_component_id === u1Schematic.schematic_component_id &&
element.x1 === center.x &&
element.y1 === center.y,
)!;
const [a, b] = edge;
const cross =
(Number(stem.x2) - a.x) * (b.y - a.y) -
(Number(stem.y2) - a.y) * (b.x - a.x);
expect(
Math.abs(cross),
`U1 pin ${pinNumber} stem touches body`,
).toBeLessThan(0.002);
};
expectStemOnEdge(6, [pathPoints[0], pathPoints[1]]);
expectStemOnEdge(2, [pathPoints[1], pathPoints[2]]);
const u1SourceComponent = component(circuitJson, "U1");
const u1SchematicPorts = circuitJson.filter(
(element) =>
element.type === "schematic_port" &&
element.schematic_component_id === u1Schematic.schematic_component_id,
);
const schematicTraces = circuitJson.filter(
(element) => element.type === "schematic_trace",
);
const schematicNetLabels = circuitJson.filter(
(element) => element.type === "schematic_net_label",
);
const floatingU1Pins = u1SchematicPorts
.filter((schematicPort) => {
const center = schematicPort.center as { x: number; y: number };
const traceTerminatesAtPort = schematicTraces.some((trace) =>
(
trace.edges as Array<{
from: { x: number; y: number };
to: { x: number; y: number };
}>
).some(
(edge) =>
(Math.abs(edge.from.x - center.x) < 1e-6 &&
Math.abs(edge.from.y - center.y) < 1e-6) ||
(Math.abs(edge.to.x - center.x) < 1e-6 &&
Math.abs(edge.to.y - center.y) < 1e-6),
),
);
const displayLabelTerminatesAtPort = schematicNetLabels.some((label) => {
const anchor = label.anchor_position as { x: number; y: number };
return (
Math.abs(anchor.x - center.x) < 1e-6 &&
Math.abs(anchor.y - center.y) < 1e-6
);
});
return !traceTerminatesAtPort && !displayLabelTerminatesAtPort;
})
.map((schematicPort) =>
circuitJson.find(
(element) =>
element.type === "source_port" &&
element.source_component_id ===
u1SourceComponent.source_component_id &&
element.source_port_id === schematicPort.source_port_id,
),
)
.map((sourcePort) => sourcePort?.pin_number);
expect(
floatingU1Pins,
"all U1 traces or inline labels terminate at their ports",
).toEqual([]);
const allSchematicNetLabels = circuitJson.filter(
(element) => element.type === "schematic_net_label",
);
const renderedNetLabels = allSchematicNetLabels.map(
(element) => element.text,
);
expect(renderedNetLabels).toContain("P_Gate");
expect(
circuitJson.some(
(element) =>
element.type === "source_trace" && element.name === "VIN2_D6_pin1",
),
"D6 VIN2 uses a named native trace instead of a manual net label",
).toBe(true);
expect(renderedNetLabels).not.toContain("LOAD_SENS_PCH");
expect(renderedNetLabels).not.toContain("D2_A");
const expectedNativeSymbols = {
D1: "avalanche_diode_down",
D2: "led_down",
D5: "zener_diode_vert",
R1: "boxresistor_left",
R3: "boxresistor_up",
R4: "boxresistor_up",
R14: "boxresistor_up",
} as const;
for (const [componentName, symbolName] of Object.entries(
expectedNativeSymbols,
)) {
expect(schematicComponentFor(circuitJson, componentName).symbol_name).toBe(
symbolName,
);
}
const d3Schematic = schematicComponentFor(circuitJson, "D3_SCHEMATIC");
const d4Schematic = schematicComponentFor(circuitJson, "D4_SCHEMATIC");
expect(d3Schematic.symbol_name).toBe("schottky_diode_up");
expect(d4Schematic.symbol_name).toBe("schottky_diode_down");
const d3SchematicId = String(d3Schematic.schematic_component_id);
const d4SchematicId = String(d4Schematic.schematic_component_id);
const pinCenter = (
componentName: string,
pinNumber: number,
schematicComponentName = componentName,
) =>
schematicPort(circuitJson, componentName, pinNumber, schematicComponentName)
.center as { x: number; y: number };
const expectAlignedX = (
label: string,
pins: Array<
[
componentName: string,
pinNumber: number,
schematicComponentName?: string,
]
>,
) => {
const xCoordinates = pins.map(([name, pinNumber, schematicName]) =>
pinCenter(name, pinNumber, schematicName).x.toFixed(6),
);
expect(new Set(xCoordinates).size, label).toBe(1);
};
const expectHorizontalExit = (
label: string,
from: [componentName: string, pinNumber: number],
to: [componentName: string, pinNumber: number],
) => {
const fromPort = schematicPort(circuitJson, ...from);
const toPort = schematicPort(circuitJson, ...to);
const fromPortId = String(fromPort.schematic_port_id);
const toPortId = String(toPort.schematic_port_id);
const trace = circuitJson.find(
(element) =>
element.type === "schematic_trace" &&
String(element.source_trace_id).includes(fromPortId) &&
String(element.source_trace_id).includes(toPortId),
);
expect(trace, label).toBeDefined();
const fromCenter = fromPort.center as { x: number; y: number };
const attachedEdge = (
trace!.edges as Array<{
from: { x: number; y: number };
to: { x: number; y: number };
}>
).find(
(edge) =>
(Math.abs(edge.from.x - fromCenter.x) < 1e-6 &&
Math.abs(edge.from.y - fromCenter.y) < 1e-6) ||
(Math.abs(edge.to.x - fromCenter.x) < 1e-6 &&
Math.abs(edge.to.y - fromCenter.y) < 1e-6),
);
expect(attachedEdge, `${label} reaches the test point`).toBeDefined();
expect(
Math.abs(Number(attachedEdge!.from.y) - Number(attachedEdge!.to.y)),
`${label} leaves the test point horizontally`,
).toBeLessThan(1e-6);
};
expectAlignedX("TP2/C24/C25/TP7 vertical column", [
["TP2", 1],
["C24", 2],
["C24", 1],
["C25", 1],
["C25", 2],
["TP7", 1],
]);
expect(
schematicPort(circuitJson, "TP2", 1).facing_direction,
"upper VBATT test point faces the trace column",
).toBe("down");
expect(
schematicPort(circuitJson, "TP7", 1).facing_direction,
"lower GND test point faces the trace column",
).toBe("up");
expect(
schematicPort(circuitJson, "P1", 1).facing_direction,
"left VBATT test point faces its outgoing trace",
).toBe("right");
expect(
schematicPort(circuitJson, "P2", 1).facing_direction,
"left GND test point faces its outgoing trace",
).toBe("right");
expectHorizontalExit("P1 to VBATT trace", ["P1", 1], ["D2", 1]);
expectHorizontalExit("P2 to GND trace", ["P2", 1], ["R14", 1]);
expectAlignedX("D2 and R14", [
["D2", 2],
["R14", 2],
]);
expect(pinCenter("R1", 1).y, "R1 to U1 pin 3").toBeCloseTo(
pinCenter("U1", 3).y,
6,
);
expect(pinCenter("U1", 1).y, "U1 pin 1 to R2").toBeCloseTo(
pinCenter("R2", 1).y,
6,
);
expectAlignedX("U1/D4/R3 vertical stack", [
["U1", 2],
["D4", 1, "D4_SCHEMATIC"],
["D4", 2, "D4_SCHEMATIC"],
["R3", 2],
["R3", 1],
]);
const schematicPinY = (
componentName: string,
schematicComponentId: string,
pinNumber: number,
): number => {
const sourcePortId = port(
circuitJson,
componentName,
pinNumber,
).source_port_id;
return (
circuitJson.find(
(element) =>
element.type === "schematic_port" &&
element.schematic_component_id === schematicComponentId &&
element.source_port_id === sourcePortId,
)!.center as { y: number }
).y;
};
expect(
schematicPinY("D3", d3SchematicId, 1),
"D3 cathode pin 1 is above anode pin 2 in TI's Altium source",
).toBeGreaterThan(schematicPinY("D3", d3SchematicId, 2));
expect(
schematicPinY("D4", d4SchematicId, 1),
"D4 cathode pin 1 is below anode pin 2 in TI's Altium source",
).toBeLessThan(schematicPinY("D4", d4SchematicId, 2));
});
test("regulator child preserves the TIDA-050008 sheet-2 netlist", async () => {
const circuitJson = await render(
<VoltageRegulator_LM73605 name="regulator" />,
);
expectNoCircuitErrors(circuitJson);
assertNet(circuitJson, "VIN1", [
["Cbulk1", 1],
["CI1", 2],
["CI2", 2],
["CI3", 1],
["CI4", 1],
["U2", 18],
["U2", 20],
["U2", 21],
["U2", 22],
]);
assertNet(circuitJson, "SW", [
["U2", 1],
["U2", 2],
["U2", 3],
["U2", 4],
["U2", 5],
["CB", 2],
["L1", 1],
]);
assertNet(circuitJson, "CBOOT_NET", [
["U2", 6],
["CB", 1],
]);
assertNet(circuitJson, "VCC", [
["U2", 7],
["CVCC", 1],
]);
assertNet(circuitJson, "BIAS", [
["U2", 8],
["Cbias1", 1],
["Rbias1", 1],
]);
assertNet(circuitJson, "RT", [
["U2", 9],
["RT", 1],
]);
assertNet(circuitJson, "SS_TRK", [
["U2", 10],
["CSS", 1],
]);
assertNet(circuitJson, "FB1", [
["U2", 11],
["CFF", 2],
["RFBT", 1],
["RFBB", 2],
["R20", 2],
]);
assertNet(circuitJson, "PGOOD_NET", [
["U2", 16],
["RPG", 1],
]);
assertNet(circuitJson, "V3_3", [
["L1", 2],
["CO", 2],
["CO1", 1],
["CO2", 1],
["CO3", 1],
["CO4", 1],
["CO5", 1],
["RPG", 2],
["CFF", 1],
["RFBT", 2],
["Rbias1", 2],
["TP18", 1],
["P3", 1],
]);
assertNet(circuitJson, "V_CTRL1", [
["R20", 1],
["TP5", 1],
]);
assertNet(circuitJson, "AGND", [
["U2", 19],
["CSS", 2],
["RFBB", 1],
["NTGND1", 2],
]);
assertNet(circuitJson, "GND", [
["Cbulk1", 2],
["CI1", 1],
["CI2", 1],
["CI3", 2],
["CI4", 2],
["U2", 12],
["U2", 13],
["U2", 14],
["U2", 15],
["U2", 17],
["U2", 23],
["U2", 24],
["U2", 25],
["U2", 26],
["U2", 27],
["U2", 28],
["U2", 29],
["U2", 30],
["U2", 31],
["CO", 1],
["CO1", 2],
["CO2", 2],
["CO3", 2],
["CO4", 2],
["CO5", 2],
["CVCC", 2],
["RT", 2],
["Cbias1", 2],
["NTGND1", 1],
["TP19", 1],
["P4", 1],
]);
expect(component(circuitJson, "U2").manufacturer_part_number).toBe(
"LM73605QRNPRQ1",
);
});
test("supervisor/watchdog child preserves the TIDA-050008 sheet-3 netlist", async () => {
const circuitJson = await render(
<SupervisorWatchdog_TPS3850 name="supervisorWatchdog" />,
);
expectNoCircuitErrors(circuitJson);
assertNet(circuitJson, "V3_3", [
["U3", 1],
["U3", 3],
["U3", 10],
["C11", 1],
["C13", 1],
["J1", 1],
["R21", 2],
["R5", 2],
["R16", 1],
["R6", 2],
["R15", 1],
]);
assertNet(circuitJson, "CWD", [
["U3", 2],
["C12", 1],
]);
assertNet(circuitJson, "SET1", [
["U3", 6],
["J1", 2],
]);
assertNet(circuitJson, "CRST", [
["U3", 4],
["R21", 1],
]);
assertNet(circuitJson, "WDI", [
["U3", 7],
["TP1", 1],
]);
assertNet(circuitJson, "WDO", [
["U3", 8],
["R5", 1],
["D9", 1],
["TP8", 1],
]);
assertNet(circuitJson, "WDO_LED_A", [
["R16", 2],
["D9", 2],
]);
assertNet(circuitJson, "RESET_3V3", [
["U3", 9],
["R6", 1],
["D8", 1],
["TP6", 1],
]);
assertNet(circuitJson, "RESET_LED_A", [
["R15", 2],
["D8", 2],
]);
assertNet(circuitJson, "GND", [
["U3", 5],
["U3", 11],
["C11", 2],
["C13", 2],
["J1", 3],
["C12", 2],
]);
expect(
circuitJson
.filter((element) => element.type === "source_trace")
.map((trace) => trace.name)
.filter((name) => name?.startsWith("V3_3_"))
.sort(),
"V3_3 endpoints use named native traces",
).toEqual([
"V3_3_C11_pin1",
"V3_3_C13_pin1",
"V3_3_R21_pin2",
"V3_3_R5_pin2",
"V3_3_R6_pin2",
]);
expect(
circuitJson
.filter((element) => element.type === "source_trace")
.map((trace) => trace.name)
.filter((name) => name?.startsWith("GND_"))
.sort(),
"ground endpoints use named native traces",
).toEqual([
"GND_C11_pin2",
"GND_C12_pin2",
"GND_C13_pin2",
"GND_J1_pin3",
"GND_U3_pin5",
]);
const expectAlignedX = (
label: string,
first: [componentName: string, pinNumber: number],
second: [componentName: string, pinNumber: number],
) => {
const firstCenter = schematicPort(circuitJson, ...first).center as {
x: number;
};
const secondCenter = schematicPort(circuitJson, ...second).center as {
x: number;
};
expect(firstCenter.x, label).toBeCloseTo(secondCenter.x, 6);
};
expectAlignedX("R16/D9 straight vertical trace", ["R16", 2], ["D9", 2]);
expectAlignedX("R15/D8 straight vertical trace", ["R15", 2], ["D8", 2]);
expect(component(circuitJson, "U3").manufacturer_part_number).toBe(
"TPS3850H33QDRCRQ1",
);
});
test("composite joins only the shared TI sheet nets", async () => {
const circuitJson = await render(
<PowerSupply_WindowModule name="powerSupply" />,
);
expectNoCircuitErrors(circuitJson);
assertSubcircuitTrace(
circuitJson,
["reverseBattery", "VIN1"],
["regulator", "VIN1"],
);
assertSubcircuitTrace(
circuitJson,
["reverseBattery", "GND"],
["regulator", "GND"],
);
assertSubcircuitPortNet(circuitJson, "reverseBattery", "VIN1", "VIN1");
assertSubcircuitPortNet(circuitJson, "regulator", "VIN1", "VIN1");
assertSubcircuitPortNet(circuitJson, "regulator", "V3_3", "V3_3");
assertSubcircuitPortNet(circuitJson, "supervisorWatchdog", "V3_3", "V3_3");
assertSubcircuitPortNet(circuitJson, "reverseBattery", "GND", "GND");
assertSubcircuitPortNet(circuitJson, "regulator", "GND", "GND");
assertSubcircuitPortNet(circuitJson, "supervisorWatchdog", "GND", "GND");
expect(port(circuitJson, "U3", 1).subcircuit_connectivity_map_key).toBe(
port(circuitJson, "U3", 10).subcircuit_connectivity_map_key,
);
const sheets = circuitJson.filter(
(element) => element.type === "schematic_sheet",
);
expect(
sheets.map(
({
name,
display_name,
sheet_index,
sheet_size,
sheet_width,
sheet_height,
}) => ({
name,
display_name,
sheet_index,
sheet_size,
sheet_width,
sheet_height,
}),
),
).toEqual([
{
name: "main_supply",
display_name: "Main Supply",
sheet_index: 0,
sheet_size: "ansi_b",
sheet_width: 431.8,
sheet_height: 279.4,
},
{
name: "watchdog_and_vref",
display_name: "Watchdog and Vref",
sheet_index: 1,
sheet_size: "ansi_b",
sheet_width: 431.8,
sheet_height: 279.4,
},
]);
expect(
circuitJson.filter(
(element) => element.type === "schematic_element_outside_sheet_warning",
),
).toHaveLength(0);
const sheetId = (name: string) =>
sheets.find((sheet) => sheet.name === name)!.schematic_sheet_id;
expect(schematicComponentFor(circuitJson, "U1").schematic_sheet_id).toBe(
sheetId("main_supply"),
);
expect(schematicComponentFor(circuitJson, "U2").schematic_sheet_id).toBe(
sheetId("main_supply"),
);
expect(schematicComponentFor(circuitJson, "U3").schematic_sheet_id).toBe(
sheetId("watchdog_and_vref"),
);
const u1Center = schematicComponentFor(circuitJson, "U1").center as {
y: number;
};
const u2Center = schematicComponentFor(circuitJson, "U2").center as {
y: number;
};
expect(u1Center.y).toBeCloseTo(5.819, 6);
expect(
u2Center.y,
"3.3-V System Supply is packed 1.6 mm toward Reverse Battery Protection",
).toBeCloseTo(-4.392, 6);
const childGroups = circuitJson.filter(
(element) =>
element.type === "source_group" &&
["reverseBattery", "regulator", "supervisorWatchdog"].includes(
String(element.name),
),
);
expect(childGroups).toHaveLength(3);
expect(childGroups.every((group) => !group.show_as_schematic_box)).toBe(true);
expect(circuitJson.some((element) => element.type === "schematic_box")).toBe(
false,
);
});