KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_footprint_rescue_layer.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <footprint.h>
23#include <layer_ids.h>
24#include <layer_utils.h>
25#include <lset.h>
26#include <pad.h>
27#include <pcb_shape.h>
29
38BOOST_AUTO_TEST_SUITE( FootprintRescueLayer )
39
40
41BOOST_AUTO_TEST_CASE( OrphanLayerCheckIgnoresRescue )
42{
43 // Default allowed custom user layer set used by the Footprint Properties dialog when
44 // "Custom Layers" is off.
45 const LSET defaultCustomLayers =
47
48 // A footprint with only "clean" items on copper/tech layers must report no orphans.
49 {
50 FOOTPRINT footprint( nullptr );
51
52 PCB_SHAPE* shape = new PCB_SHAPE( &footprint );
53 shape->SetLayer( F_SilkS );
54 footprint.Add( shape );
55
56 LSET orphans = LAYER_UTILS::GetOrphanedFootprintLayers( footprint, defaultCustomLayers );
57 BOOST_TEST( orphans.none() );
58 }
59
60 // A footprint with an item on Rescue must NOT be reported as an orphan (it is handled
61 // by library-parity DRC, not by the properties dialog).
62 {
63 FOOTPRINT footprint( nullptr );
64
65 PCB_SHAPE* rescueShape = new PCB_SHAPE( &footprint );
66 rescueShape->SetLayer( Rescue );
67 footprint.Add( rescueShape );
68
69 LSET allLayers = LAYER_UTILS::GetAllFootprintLayers( footprint );
70 BOOST_TEST( allLayers.test( Rescue ) );
71
72 LSET orphans = LAYER_UTILS::GetOrphanedFootprintLayers( footprint, defaultCustomLayers );
73 BOOST_TEST( orphans.none() );
74 }
75
76 // An inner copper layer used by a footprint item is still correctly reported as an
77 // orphan when the custom user layer set excludes it.
78 {
79 FOOTPRINT footprint( nullptr );
80
81 PCB_SHAPE* copperShape = new PCB_SHAPE( &footprint );
82 copperShape->SetLayer( In1_Cu );
83 footprint.Add( copperShape );
84
85 LSET restrictive = LSET{ F_Cu, B_Cu };
86 LSET orphans = LAYER_UTILS::GetOrphanedFootprintLayers( footprint, restrictive );
87
88 BOOST_TEST( orphans.test( In1_Cu ) );
89 }
90
91 // Multi-layer items (PTH pads span all copper layers plus their masks) must be
92 // fully aggregated by GetAllFootprintLayers rather than collapsed to a single
93 // layer.
94 {
95 FOOTPRINT footprint( nullptr );
96
97 PAD* pthPad = new PAD( &footprint );
99 footprint.Add( pthPad );
100
101 LSET padLayers = pthPad->GetLayerSet();
102 LSET allLayers = LAYER_UTILS::GetAllFootprintLayers( footprint );
103
104 BOOST_TEST( ( allLayers & padLayers ) == padLayers );
105 }
106}
107
108
118BOOST_AUTO_TEST_CASE( OrphanLayerCheckAllowsAllUserLayers )
119{
120 FOOTPRINT footprint( nullptr );
121
122 // User_9 is well beyond the first four user-defined layers.
123 PCB_SHAPE* userShape = new PCB_SHAPE( &footprint );
124 userShape->SetLayer( User_9 );
125 footprint.Add( userShape );
126
127 // The hard-coded "first four user layers" set wrongly excludes User_9, demonstrating the
128 // defect that the dialog guard now avoids by skipping the check entirely in default mode.
129 const LSET truncatedUserLayers =
131 LSET wrongOrphans = LAYER_UTILS::GetOrphanedFootprintLayers( footprint, truncatedUserLayers );
132 BOOST_TEST( wrongOrphans.test( User_9 ) );
133
134 // The correct default set permits every user-defined layer, so nothing is orphaned.
135 const LSET fullUserLayers =
137 LSET orphans = LAYER_UTILS::GetOrphanedFootprintLayers( footprint, fullUserLayers );
138 BOOST_TEST( orphans.none() );
139}
140
141
142BOOST_AUTO_TEST_CASE( Issue24045Footprint )
143{
144 // Load the exact footprint from the issue report. It contains graphic items on the
145 // Rescue layer. Loading must succeed and the orphan-layer validator must pass.
146 const std::string fpPath = KI_TEST::GetPcbnewTestDataDir() + "issue24045/"
147 + "QFN-24_L4.0-W4.0-P0.50-BL-EP2.6.kicad_mod";
148
149 std::unique_ptr<FOOTPRINT> fp = KI_TEST::ReadFootprintFromFileOrStream( fpPath );
150 BOOST_REQUIRE( fp );
151
152 LSET allLayers = LAYER_UTILS::GetAllFootprintLayers( *fp );
153 BOOST_TEST( allLayers.test( Rescue ),
154 "Issue footprint must exercise the Rescue layer for this test to be meaningful" );
155
156 const LSET defaultCustomLayers =
158
159 LSET orphans = LAYER_UTILS::GetOrphanedFootprintLayers( *fp, defaultCustomLayers );
160 BOOST_TEST( orphans.none(),
161 "Footprint properties dialog must not block saving when only Rescue items orphan" );
162}
163
164
General utilities for PCB file IO for QA programs.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
Definition lset.cpp:700
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition lset.cpp:573
Definition pad.h:61
void SetAttribute(PAD_ATTRIB aAttribute)
Definition pad.cpp:1615
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition pad.h:552
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
@ B_Cu
Definition layer_ids.h:61
@ User_9
Definition layer_ids.h:128
@ F_SilkS
Definition layer_ids.h:96
@ In1_Cu
Definition layer_ids.h:62
@ Rescue
Definition layer_ids.h:117
@ F_Cu
Definition layer_ids.h:60
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
std::unique_ptr< FOOTPRINT > ReadFootprintFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
LSET GetAllFootprintLayers(const FOOTPRINT &aFootprint)
Return the union of layers referenced by every item inside the footprint (including graphic items,...
LSET GetOrphanedFootprintLayers(const FOOTPRINT &aFootprint, const LSET &aCustomUserLayers)
Compute the set of footprint-used layers that would be orphaned if the footprint's allowed layer set ...
@ PTH
Plated through hole pad.
Definition padstack.h:98
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(OrphanLayerCheckIgnoresRescue)
Regression test for https://gitlab.com/kicad/code/kicad/-/issues/24045.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)