circuit-json-to-lbrn 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,10 @@ test("lga-interconnect", async () => {
12
12
 
13
13
  const project = convertCircuitJsonToLbrn(circuitJson)
14
14
 
15
+ Bun.write("debug-output/lga-interconnect.lbrn2", project.getString(), {
16
+ createPath: true,
17
+ })
18
+
15
19
  const lbrnSvg = await generateLightBurnSvg(project)
16
20
 
17
21
  expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
@@ -0,0 +1,67 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson, SourceTrace } from "circuit-json"
7
+
8
+ /**
9
+ * This test demonstrates a bug where standalone traces (traces not connected
10
+ * to any ports/nets) are not being converted to cut shapes in the LightBurn output.
11
+ *
12
+ * Expected: The trace should appear as a cut shape in the bottom SVG
13
+ * Actual: The trace is missing from the LightBurn output (only CutSetting is present)
14
+ *
15
+ * Root cause: addPcbTrace gets netId=undefined for unconnected traces, and
16
+ * netGeoms.get(undefined) returns undefined, so the trace polygon is never added.
17
+ */
18
+ test("single-trace", async () => {
19
+ const circuitJson = [
20
+ {
21
+ type: "pcb_board",
22
+ pcb_board_id: "board_1",
23
+ width: 20,
24
+ height: 20,
25
+ center: { x: 0, y: 0 },
26
+ },
27
+ {
28
+ type: "pcb_trace",
29
+ pcb_trace_id: "trace_1",
30
+ source_trace_id: "trace_1",
31
+ route: [
32
+ {
33
+ x: -5,
34
+ y: -5,
35
+ width: 0.5,
36
+ layer: "top",
37
+ },
38
+ {
39
+ x: 5,
40
+ y: 5,
41
+ width: 0.5,
42
+ layer: "top",
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ type: "source_trace",
48
+ source_trace_id: "trace_2",
49
+ connected_source_net_ids: [],
50
+ connected_source_port_ids: [],
51
+ } as SourceTrace,
52
+ ] as CircuitJson
53
+
54
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
55
+
56
+ const project = convertCircuitJsonToLbrn(circuitJson)
57
+
58
+ Bun.write("debug-output/single-trace.lbrn2", project.getString(), {
59
+ createPath: true,
60
+ })
61
+
62
+ const lbrnSvg = await generateLightBurnSvg(project)
63
+
64
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
65
+ import.meta.filename,
66
+ )
67
+ })
@@ -1 +1 @@
1
- import "bun-match-svg"
1
+ import "bun-match-svg"
package/tests/svg.test.ts CHANGED
@@ -1,12 +1,11 @@
1
- import { expect, test } from "bun:test"
2
-
3
- const testSvg = `<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
1
+ import { expect, test } from "bun:test"
2
+
3
+ const testSvg = `<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
4
4
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
5
- </svg>`
6
-
7
- test("svg snapshot example", async () => {
8
- // First run will create the snapshot
9
- // Subsequent runs will compare against the saved snapshot
10
- await expect(testSvg).toMatchSvgSnapshot(import.meta.path)
11
- })
12
-
5
+ </svg>`
6
+
7
+ test("svg snapshot example", async () => {
8
+ // First run will create the snapshot
9
+ // Subsequent runs will compare against the saved snapshot
10
+ await expect(testSvg).toMatchSvgSnapshot(import.meta.path)
11
+ })
@@ -1,9 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(bun pm:*)"
5
- ],
6
- "deny": [],
7
- "ask": []
8
- }
9
- }
@@ -1,70 +0,0 @@
1
- import { test, expect } from "bun:test"
2
- import { convertCircuitJsonToLbrn } from "../lib/index"
3
- import type { CircuitJson } from "circuit-json"
4
-
5
- test("plated hole generates circular path", () => {
6
- const circuitJson: CircuitJson = [
7
- {
8
- type: "pcb_board",
9
- pcb_board_id: "test_board",
10
- width: 100,
11
- height: 100,
12
- center: { x: 0, y: 0 },
13
- thickness: 1.6,
14
- num_layers: 2,
15
- material: "fr4",
16
- },
17
- {
18
- type: "pcb_plated_hole",
19
- shape: "circle",
20
- pcb_plated_hole_id: "test_hole",
21
- outer_diameter: 2,
22
- hole_diameter: 1,
23
- x: 10,
24
- y: 20,
25
- layers: ["top"],
26
- },
27
- ]
28
-
29
- const project = convertCircuitJsonToLbrn(circuitJson)
30
-
31
- // Should have 1 CutSetting and 1 ShapePath
32
- expect(project.children.length).toBe(2)
33
-
34
- // First child should be CutSetting
35
- const cutSetting = project.children.find(
36
- (child) => child.token === "CutSetting",
37
- )!
38
- expect(cutSetting.token).toBe("CutSetting")
39
-
40
- // Second child should be ShapePath (the plated hole)
41
- const shapePath = project.children.find(
42
- (child) => child.token === "Shape.Path",
43
- )!
44
- expect(shapePath.token).toBe("Shape.Path")
45
-
46
- // Verify the shape path has the expected properties
47
- if (shapePath.token === "Shape.Path") {
48
- expect((shapePath as any).isClosed).toBe(true)
49
- expect((shapePath as any).cutIndex).toBe(0)
50
- expect((shapePath as any).verts).toBeDefined()
51
- expect((shapePath as any).prims).toBeDefined()
52
-
53
- // Should have 5 vertices (4 bezier curve points + 1 to close)
54
- const vertsLength = (shapePath as any).verts?.length
55
- const primsLength = (shapePath as any).prims?.length
56
- expect(vertsLength).toBe(5)
57
- expect(primsLength).toBe(4)
58
-
59
- // Verify all primitives are bezier curves
60
- const prims = (shapePath as any).prims || []
61
- for (const prim of prims) {
62
- expect(prim.type).toBe(1) // 1 = BezierTo
63
- }
64
-
65
- // Verify the circle is centered at (10, 20) with radius 1
66
- const firstVert = (shapePath as any).verts?.[0]
67
- expect(firstVert?.x).toBeCloseTo(11, 5) // 10 + 1 (radius)
68
- expect(firstVert?.y).toBeCloseTo(20, 5)
69
- }
70
- })