Skip to content

Commit 9d3fa7e

Browse files
committed
WIP: Add new test from KiCad demo projects
1 parent 1639141 commit 9d3fa7e

6 files changed

Lines changed: 103006 additions & 72 deletions

File tree

src/kiutils/items/brditems.py

Lines changed: 90 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -477,22 +477,22 @@ class PlotSettings():
477477
478478
Available and required since KiCad v7"""
479479

480-
disableApertMacros: str = "no"
481-
"""The ``disableApertMacros`` token defines if aperture macros are to be used in gerber plots"""
480+
disableApertMacros: Optional[bool] = None
481+
"""The optional ``disableApertMacros`` token defines if aperture macros are to be used in gerber plots"""
482482

483-
useGerberExtensions: str = "no"
484-
"""The ``useGerberExtensions`` token defines if the Protel layer file name extensions are to
483+
useGerberExtensions: Optional[bool] = None
484+
"""The optional ``useGerberExtensions`` token defines if the Protel layer file name extensions are to
485485
be used in gerber plots"""
486486

487-
useGerberAttributes: str = "no"
488-
"""The ``useGerberAttributes`` token defines if the X2 extensions are used in gerber plots"""
487+
useGerberAttributes: Optional[bool] = None
488+
"""The optional ``useGerberAttributes`` token defines if the X2 extensions are used in gerber plots"""
489489

490-
useGerberAdvancedAttributes: str = "no"
491-
"""The ``useGerberAdvancedAttributes`` token defines if the netlist information should be
490+
useGerberAdvancedAttributes: Optional[bool] = None
491+
"""The optional ``useGerberAdvancedAttributes`` token defines if the netlist information should be
492492
included in gerber plots"""
493493

494-
createGerberJobFile: str = "no"
495-
"""The ``createGerberJobFile`` token defines if a job file should be created when plotting
494+
createGerberJobFile: Optional[bool] = None
495+
"""The optional ``createGerberJobFile`` token defines if a job file should be created when plotting
496496
gerber files"""
497497

498498
# FIXME: Where is the docu of this token?
@@ -520,18 +520,18 @@ class PlotSettings():
520520
521521
Required until KiCad v6, removed since KiCad v7"""
522522

523-
plotFameRef: str = "no"
524-
"""The ``plotFameRef`` token defines if the border and title block should be plotted"""
523+
plotFameRef: Optional[bool] = None
524+
"""The optional ``plotFameRef`` token defines if the border and title block should be plotted"""
525525

526-
viasOnMask: str = "no"
527-
"""The ``viasOnMask`` token defines if the vias are to be tented"""
526+
viasOnMask: Optional[bool] = None
527+
"""The optional ``viasOnMask`` token defines if the vias are to be tented"""
528528

529529
mode: int = 1
530530
"""The ``mode`` token defines the plot mode. An attribute of 1 plots in the normal
531531
mode and an attribute of 2 plots in the outline (sketch) mode."""
532532

533-
useAuxOrigin: str = "no"
534-
"""The ``useAuxOrigin`` token determines if all coordinates are offset by the defined user origin"""
533+
useAuxOrigin: Optional[bool] = None
534+
"""The optional ``useAuxOrigin`` token determines if all coordinates are offset by the defined user origin"""
535535

536536
hpglPenNumber: int = 0
537537
"""The ``hpglPenNumber`` token defines the integer pen number used for HPGL plots"""
@@ -542,37 +542,37 @@ class PlotSettings():
542542
hpglPenDiameter: float = 0.0
543543
"""The ``hpglPenDiameter`` token defines the floating point pen size for HPGL plots"""
544544

545-
dxfPolygonMode: str = "no"
546-
"""The ``dxfPolygonMode`` token defines if the polygon mode should be used for DXF plots"""
545+
dxfPolygonMode: Optional[bool] = None
546+
"""The optional ``dxfPolygonMode`` token defines if the polygon mode should be used for DXF plots"""
547547

548-
dxfImperialUnits: str = "no"
549-
"""The ``dxfImperialUnits`` token defines if imperial units should be used for DXF plots"""
548+
dxfImperialUnits: Optional[bool] = None
549+
"""The optional ``dxfImperialUnits`` token defines if imperial units should be used for DXF plots"""
550550

551-
dxfUsePcbnewFont: str = "no"
552-
"""The ``dxfUsePcbnewFont`` token defines if the Pcbnew font (vector font) or the default
551+
dxfUsePcbnewFont: Optional[bool] = None
552+
"""The optional ``dxfUsePcbnewFont`` token defines if the Pcbnew font (vector font) or the default
553553
font should be used for DXF plots"""
554554

555-
psNegative: str = "no"
556-
"""The ``psNegative`` token defines if the output should be the negative for PostScript plots"""
555+
psNegative: Optional[bool] = None
556+
"""The optional ``psNegative`` token defines if the output should be the negative for PostScript plots"""
557557

558-
psA4Output: str = "no"
559-
"""The ``psA4Output`` token defines if the A4 page size should be used for PostScript plots"""
558+
psA4Output: Optional[bool] = None
559+
"""The optional ``psA4Output`` token defines if the A4 page size should be used for PostScript plots"""
560560

561-
plotReference: str = "no"
562-
"""The ``plotReference`` token defines if hidden reference field text should be plotted"""
561+
plotReference: Optional[bool] = None
562+
"""The optional ``plotReference`` token defines if hidden reference field text should be plotted"""
563563

564-
plotValue: str = "no"
565-
"""The ``plotValue`` token defines if hidden value field text should be plotted"""
564+
plotValue: Optional[bool] = None
565+
"""The optional ``plotValue`` token defines if hidden value field text should be plotted"""
566566

567-
plotInvisibleText: str = "no"
568-
"""The ``plotInvisibleText`` token defines if hidden text other than the reference and
567+
plotInvisibleText: Optional[bool] = None
568+
"""The optional ``plotInvisibleText`` token defines if hidden text other than the reference and
569569
value fields should be plotted"""
570570

571-
sketchPadsOnFab: str = "no"
572-
"""The ``sketchPadsOnFab`` token defines if pads should be plotted in the outline (sketch) mode"""
571+
sketchPadsOnFab: Optional[bool] = None
572+
"""The optional ``sketchPadsOnFab`` token defines if pads should be plotted in the outline (sketch) mode"""
573573

574-
subtractMaskFromSilk: str = "no"
575-
"""The ``subtractMaskFromSilk`` token defines if the solder mask layers should be subtracted from
574+
subtractMaskFromSilk: Optional[bool] = None
575+
"""The optional ``subtractMaskFromSilk`` token defines if the solder mask layers should be subtracted from
576576
the silk screen layers for gerber plots"""
577577

578578
outputFormat: int = 0
@@ -584,8 +584,8 @@ class PlotSettings():
584584
- 4: HPGL
585585
- 5: PDF"""
586586

587-
mirror: str = "no"
588-
"""The ``mirror`` token defines if the plot should be mirrored"""
587+
mirror: Optional[bool] = None
588+
"""The optional ``mirror`` token defines if the plot should be mirrored"""
589589

590590
drillShape: int = 0
591591
"""The ``drillShape`` token defines the type of drill marks used for drill files"""
@@ -672,25 +672,25 @@ def from_sexpr(cls, exp: list) -> PlotSettings:
672672
elif item[0] == 'svguseinch' : object.svgUseInch = item[1]
673673
elif item[0] == 'svgprecision' : object.svgPrecision = item[1]
674674
elif item[0] == 'excludeedgelayer' : object.excludeEdgeLayer = item[1]
675-
elif item[0] == 'plotframeref' : object.plotFameRef = item[1]
676-
elif item[0] == 'viasonmask' : object.viasOnMask = item[1]
675+
elif item[0] == 'plotframeref' : object.plotFameRef = parse_bool(item, 'plotframeref')
676+
elif item[0] == 'viasonmask' : object.viasOnMask = parse_bool(item, 'viasonmask')
677677
elif item[0] == 'mode' : object.mode = item[1]
678-
elif item[0] == 'useauxorigin' : object.useAuxOrigin = item[1]
678+
elif item[0] == 'useauxorigin' : object.useAuxOrigin = parse_bool(item, 'useauxorigin')
679679
elif item[0] == 'hpglpennumber' : object.hpglPenNumber = item[1]
680680
elif item[0] == 'hpglpenspeed' : object.hpglPenSpeed = item[1]
681681
elif item[0] == 'hpglpendiameter' : object.hpglPenDiameter = item[1]
682-
elif item[0] == 'dxfpolygonmode' : object.dxfPolygonMode = item[1]
683-
elif item[0] == 'dxfimperialunits' : object.dxfImperialUnits = item[1]
684-
elif item[0] == 'dxfusepcbnewfont' : object.dxfUsePcbnewFont = item[1]
685-
elif item[0] == 'psnegative' : object.psNegative = item[1]
686-
elif item[0] == 'psa4output' : object.psA4Output = item[1]
687-
elif item[0] == 'plotreference' : object.plotReference = item[1]
688-
elif item[0] == 'plotvalue' : object.plotValue = item[1]
689-
elif item[0] == 'plotinvisibletext' : object.plotInvisibleText = item[1]
690-
elif item[0] == 'sketchpadsonfab' : object.sketchPadsOnFab = item[1]
691-
elif item[0] == 'subtractmaskfromsilk' : object.subtractMaskFromSilk = item[1]
682+
elif item[0] == 'dxfpolygonmode' : object.dxfPolygonMode = parse_bool(item, 'dxfpolygonmode')
683+
elif item[0] == 'dxfimperialunits' : object.dxfImperialUnits = parse_bool(item, 'dxfimperialunits')
684+
elif item[0] == 'dxfusepcbnewfont' : object.dxfUsePcbnewFont = parse_bool(item, 'dxfusepcbnewfont')
685+
elif item[0] == 'psnegative' : object.psNegative = parse_bool(item, 'psnegative')
686+
elif item[0] == 'psa4output' : object.psA4Output = parse_bool(item, 'psa4output')
687+
elif item[0] == 'plotreference' : object.plotReference = parse_bool(item, 'plotreference')
688+
elif item[0] == 'plotvalue' : object.plotValue = parse_bool(item, 'plotvalue')
689+
elif item[0] == 'plotinvisibletext' : object.plotInvisibleText = parse_bool(item, 'plotinvisibletext')
690+
elif item[0] == 'sketchpadsonfab' : object.sketchPadsOnFab = parse_bool(item, 'sketchpadsonfab')
691+
elif item[0] == 'subtractmaskfromsilk' : object.subtractMaskFromSilk = parse_bool(item, 'subtractmaskfromsilk')
692692
elif item[0] == 'outputformat' : object.outputFormat = item[1]
693-
elif item[0] == 'mirror' : object.mirror = item[1]
693+
elif item[0] == 'mirror' : object.mirror = parse_bool(item, 'mirror')
694694
elif item[0] == 'drillshape' : object.drillShape = item[1]
695695
elif item[0] == 'scaleselection' : object.scaleSelection = item[1]
696696
elif item[0] == 'outputdirectory' : object.outputDirectory = item[1]
@@ -747,13 +747,17 @@ def _to_sexpr_raw(self):
747747
if self.excludeEdgeLayer is not None:
748748
expr.append(['excludeedgelayer', self.excludeEdgeLayer])
749749

750-
expr.append(['plotframeref', self.plotFameRef])
750+
if self.plotFameRef is not None:
751+
expr.append(format_bool('plotframeref', self.plotFameRef, yesno=True))
751752

752-
if self.viasOnMask == 'yes':
753-
expr.append(['viasonmask', self.viasOnMask])
753+
if self.viasOnMask is not None:
754+
expr.append(format_bool('viasonmask', self.viasOnMask, yesno=True))
754755

755756
expr.append(['mode', self.mode])
756-
expr.append(['useauxorigin', self.useAuxOrigin])
757+
758+
if self.useAuxOrigin is not None:
759+
expr.append(format_bool('useauxorigin', self.useAuxOrigin, yesno=True))
760+
757761
expr.append(['hpglpennumber', self.hpglPenNumber])
758762
expr.append(['hpglpenspeed', self.hpglPenSpeed])
759763
expr.append(['hpglpendiameter', (f"{self.hpglPenDiameter:.6f}")])
@@ -770,16 +774,29 @@ def _to_sexpr_raw(self):
770774
if self.pdf_single_document is not None:
771775
expr.append(format_bool('pdf_single_document', self.pdf_single_document, yesno=True))
772776

773-
expr.append(['dxfpolygonmode', self.dxfPolygonMode])
774-
expr.append(['dxfimperialunits', self.dxfImperialUnits])
775-
expr.append(['dxfusepcbnewfont', self.dxfUsePcbnewFont])
776-
expr.append(['psnegative', self.psNegative])
777-
expr.append(['psa4output', self.psA4Output])
777+
if self.dxfPolygonMode is not None:
778+
expr.append(format_bool('dxfpolygonmode', self.dxfPolygonMode, yesno=True))
779+
780+
if self.dxfImperialUnits is not None:
781+
expr.append(format_bool('dxfimperialunits', self.dxfImperialUnits, yesno=True))
782+
783+
if self.dxfUsePcbnewFont is not None:
784+
expr.append(format_bool('dxfusepcbnewfont', self.dxfUsePcbnewFont, yesno=True))
785+
786+
if self.psNegative is not None:
787+
expr.append(format_bool('psnegative', self.psNegative, yesno=True))
788+
789+
if self.psA4Output is not None:
790+
expr.append(format_bool('psa4output', self.psA4Output, yesno=True))
778791

779792
if self.plot_black_and_white is not None:
780793
expr.append(format_bool('plot_black_and_white', self.plot_black_and_white, yesno=True))
781794

782-
expr.append(['sketchpadsonfab', self.sketchPadsOnFab])
795+
if self.plotInvisibleText is not None:
796+
expr.append(format_bool('plotinvisibletext', self.plotInvisibleText, yesno=True))
797+
798+
if self.sketchPadsOnFab is not None:
799+
expr.append(format_bool('sketchpadsonfab', self.sketchPadsOnFab, yesno=True))
783800

784801
if self.plot_pad_numbers is not None:
785802
expr.append(format_bool('plotpadnumbers', self.plot_pad_numbers, yesno=True))
@@ -792,19 +809,21 @@ def _to_sexpr_raw(self):
792809

793810
if self.crossout_dnp_on_fab is not None:
794811
expr.append(format_bool('crossoutdnponfab', self.crossout_dnp_on_fab, yesno=True))
812+
813+
if self.plotReference is not None:
814+
expr.append(format_bool('plotreference', self.plotReference, yesno=True))
815+
816+
if self.plotValue is not None:
817+
expr.append(format_bool('plotvalue', self.plotValue, yesno=True))
795818

796-
if self.plotReference == 'yes':
797-
expr.append(['plotreference', self.plotReference])
819+
if self.subtractMaskFromSilk is not None:
820+
expr.append(format_bool('subtractmaskfromsilk', self.subtractMaskFromSilk, yesno=True))
798821

799-
if self.plotValue == 'yes':
800-
expr.append(['plotvalue', self.plotValue])
822+
expr.append(['outputformat', self.outputFormat])
801823

802-
if self.plotInvisibleText == 'yes':
803-
expr.append(['plotinvisibletext', self.plotInvisibleText])
824+
if self.mirror is not None:
825+
expr.append(format_bool('mirror', self.mirror, yesno=True))
804826

805-
expr.append(['subtractmaskfromsilk', self.subtractMaskFromSilk])
806-
expr.append(['outputformat', self.outputFormat])
807-
expr.append(['mirror', self.mirror])
808827
expr.append(['drillshape', self.drillShape])
809828
expr.append(['scaleselection', self.scaleSelection])
810829
expr.append(['outputdirectory', escape_and_quote(self.outputDirectory)])

src/kiutils/items/schitems.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def from_sexpr(cls, exp: list) -> Junction:
7373
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
7474
elif item[0] == 'at': object.position = Position().from_sexpr(item)
7575
elif item[0] == 'color': object.color = ColorRGBA().from_sexpr(item)
76-
elif item[0] == 'diameter': object.color = item[1]
76+
elif item[0] == 'diameter': object.diameter = item[1]
7777
elif item[0] == 'uuid': object.uuid = item[1]
7878
else:
7979
raise ValueError(f"Unrecognized property key: {item[0]}. Full expression: {item}")

tests/test_board.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ def setUp(self):
5959
# board = Board().from_file(self.testData.pathToTestFile)
6060
# self.assertTrue(to_file_and_compare(board, self.testData))
6161

62+
def test_KitDevColdfireXilinx_5213(self):
63+
"""Tests the behavior when creating and exporting KitDevColdfireXilinx_5213 demo board"""
64+
self.testData.pathToTestFile = Path(BOARD_DEMO) / 'KitDevColdfireXilinx_5213'
65+
board = Board().from_file(self.testData.pathToTestFile)
66+
self.assertTrue(to_file_and_compare(board, self.testData))
67+
6268
class Tests_Board(unittest.TestCase):
6369
"""Test cases for Boards"""
6470

tests/test_schematic.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ def test_RoyalBlue54LFeather(self):
6060
schematic = Schematic().from_file(self.testData.pathToTestFile)
6161
self.assertTrue(to_file_and_compare(schematic, self.testData))
6262

63+
def test_KitDevColdfireXilinx_5213(self):
64+
"""Tests the behavior when creating and exporting KitDevColdfireXilinx_5213 demo schematic"""
65+
self.testData.pathToTestFile = Path(SCHEMATIC_DEMO) / 'KitDevColdfireXilinx_5213'
66+
schematic = Schematic().from_file(self.testData.pathToTestFile)
67+
self.assertTrue(to_file_and_compare(schematic, self.testData))
68+
6369

6470
class Tests_Schematic(unittest.TestCase):
6571
"""Test cases for Schematics"""

0 commit comments

Comments
 (0)