Skip to content

Commit e8d0e80

Browse files
committed
Add new tests from KiCad demo projects
1 parent 1639141 commit e8d0e80

10 files changed

Lines changed: 171972 additions & 88 deletions

File tree

src/kiutils/footprint.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class Attributes():
6767
dnp: Optional[bool] = None
6868
"""The optional ``dnp`` token indicates that the footprint will not be populated"""
6969

70+
allow_soldermask_bridges: Optional[bool] = None
71+
"""The optional ``allow_soldermask_bridges`` token indicates that soldermask bridges are allowed"""
72+
7073
@classmethod
7174
def from_sexpr(cls, exp: list) -> Attributes:
7275
"""Convert the given S-Expresstion into a Attributes object
@@ -94,6 +97,7 @@ def from_sexpr(cls, exp: list) -> Attributes:
9497
elif is_bool_key(item, 'exclude_from_bom'): object.excludeFromBom = parse_bool(item, 'exclude_from_bom')
9598
elif is_bool_key(item, 'allow_missing_courtyard'): object.allowMissingCourtyard = parse_bool(item, 'allow_missing_courtyard')
9699
elif is_bool_key(item, 'dnp'): object.dnp = parse_bool(item, 'dnp')
100+
elif is_bool_key(item, 'allow_soldermask_bridges'): object.allow_soldermask_bridges = parse_bool(item, 'allow_soldermask_bridges')
97101
elif item in ['through_hole', 'smd']: object.type = item
98102
else:
99103
raise ValueError(f"Unrecognized property key: {item[0]}. Full expression: {item}")
@@ -108,6 +112,8 @@ def to_sexpr(self, indent=0, newline=False) -> str:
108112
- ``excludeFromBom``: False
109113
- ``excludeFromPosFiles``: False
110114
- ``allowMissingCourtyard``: False
115+
- ``dnp``: None
116+
- ``allow_soldermask_bridges``: None
111117
112118
KiCad won't add the ``(attr ..)`` token to a footprint when this combination is selected.
113119
@@ -118,11 +124,9 @@ def to_sexpr(self, indent=0, newline=False) -> str:
118124
Returns:
119125
- str: S-Expression of this object
120126
"""
121-
if (self.type is None
122-
and self.boardOnly == False
123-
and self.excludeFromBom == False
124-
and self.excludeFromPosFiles == False
125-
and self.allowMissingCourtyard == False):
127+
if self.type is None and all([prop == False for prop in [
128+
self.boardOnly, self.excludeFromBom, self.excludeFromPosFiles,
129+
self.allowMissingCourtyard, self.dnp, self.allow_soldermask_bridges]]):
126130
return ''
127131

128132
raw_expr = self._to_sexpr_raw()
@@ -143,6 +147,8 @@ def _to_sexpr_raw(self):
143147
expr.append('allow_missing_courtyard')
144148
if self.dnp:
145149
expr.append('dnp')
150+
if self.allow_soldermask_bridges:
151+
expr.append('allow_soldermask_bridges')
146152

147153
return expr
148154

@@ -818,6 +824,11 @@ def libId(self, symbol_id: str):
818824
"""The optional ``solderPasteMargin`` token defines the solder paste distance from all pads in
819825
the footprint. If not set, the board solder_paste_margin setting is used."""
820826

827+
solderPasteMarginRatio: Optional[float] = None
828+
"""The optional ``solderPasteMarginRatio`` token defines the ratio applied to the solder paste
829+
margin for all pads in the footprint. It scales the board's solder_paste_margin value by this ratio.
830+
If not set, the board ``solder_paste_margin_ratio`` setting is used."""
831+
821832
solderPasteRatio: Optional[float] = None
822833
"""The optional ``solderPasteRatio`` token defines the percentage of the pad size used to define
823834
the solder paste for all pads in the footprint. If not set, the board solder_paste_ratio setting
@@ -945,6 +956,7 @@ def from_sexpr(cls, exp: list) -> Footprint:
945956
elif item[0] == 'autoplace_cost180': object.autoplaceCost180 = item[1]
946957
elif item[0] == 'solder_mask_margin': object.solderMaskMargin = item[1]
947958
elif item[0] == 'solder_paste_margin': object.solderPasteMargin = item[1]
959+
elif item[0] == 'solder_paste_margin_ratio': object.solderPasteMarginRatio = item[1]
948960
elif item[0] == 'solder_paste_ratio': object.solderPasteRatio = item[1]
949961
elif item[0] == 'clearance': object.clearance = item[1]
950962
elif item[0] == 'zone_connect': object.zoneConnect = item[1]
@@ -1142,6 +1154,9 @@ def _to_sexpr_raw(self):
11421154

11431155
if self.solderPasteMargin is not None:
11441156
expr.append(['solder_paste_margin', self.solderPasteMargin])
1157+
1158+
if self.solderPasteMarginRatio is not None:
1159+
expr.append(['solder_paste_margin_ratio', self.solderPasteMarginRatio])
11451160

11461161
if self.solderPasteRatio is not None:
11471162
expr.append(['solder_paste_ratio', self.solderPasteRatio])

src/kiutils/items/brditems.py

Lines changed: 101 additions & 75 deletions
Large diffs are not rendered by default.

src/kiutils/items/common.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,11 @@ def from_sexpr(cls, exp: list) -> PageSettings:
751751

752752
object.width = exp[2]
753753
object.height = exp[3]
754-
else:
755-
for item in exp[2:]:
756-
if not isinstance(item, list):
757-
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
758-
elif item[0] == 'portrait': object.portrait = True
759-
else:
760-
raise ValueError(f"Unrecognized property key: {item[0]}. Full expression: {item}")
754+
755+
for item in exp[2:]:
756+
if item == 'portrait': object.portrait = True
757+
else:
758+
raise ValueError(f"Unrecognized property key: {item}. Full expression: {exp}")
761759

762760
return object
763761

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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ 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+
68+
def test_StickHub(self):
69+
"""Tests the behavior when creating and exporting StickHub demo board"""
70+
self.testData.pathToTestFile = Path(BOARD_DEMO) / 'StickHub'
71+
board = Board().from_file(self.testData.pathToTestFile)
72+
self.assertTrue(to_file_and_compare(board, self.testData))
73+
6274
class Tests_Board(unittest.TestCase):
6375
"""Test cases for Boards"""
6476

tests/test_schematic.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ 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+
69+
def test_StickHub(self):
70+
"""Tests the behavior when creating and exporting StickHub demo schematic"""
71+
self.testData.pathToTestFile = Path(SCHEMATIC_DEMO) / 'StickHub'
72+
schematic = Schematic().from_file(self.testData.pathToTestFile)
73+
self.assertTrue(to_file_and_compare(schematic, self.testData))
74+
6375

6476
class Tests_Schematic(unittest.TestCase):
6577
"""Test cases for Schematics"""

0 commit comments

Comments
 (0)