KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_cross_probe_selection.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
22
23#include <algorithm>
24#include <memory>
25
26#include <api/api_pcb_utils.h>
27#include <api/api_utils.h>
28#include <board.h>
29#include <footprint.h>
30#include <kiid.h>
31#include <pad.h>
33
34using kiapi::common::commands::SelectionSpec;
35using kiapi::common::commands::SyncSelection;
36
37
38// The two hierarchical sheets of the complex_hierarchy demo. Both instantiate ampli_ht.kicad_sch
39// and carry 29 footprints; ten more sit on the root sheet and four are board-only
40static const wxString c_verticalSheet = wxS( "00000000-0000-0000-0000-00004b3a1333" );
41static const wxString c_horizontalSheet = wxS( "00000000-0000-0000-0000-00004b3a13a4" );
42
43static const std::size_t c_footprintsPerSheet = 29;
44static const std::size_t c_footprintsOnBoard = 72;
45
46
48{
50 {
51 KI_TEST::LoadBoard( m_settingsManager, wxS( "complex_hierarchy" ), m_board );
52 }
53
55 KIID_PATH SchematicPath( const KIID& aRoot, const wxString& aSheet ) const
56 {
58 path.push_back( aRoot );
59 path.push_back( KIID( aSheet ) );
60
61 return path;
62 }
63
64 std::size_t CountOnSheet( const KIID_PATH& aSheetPath ) const
65 {
66 return static_cast<std::size_t>(
67 std::ranges::count_if( m_board->Footprints(),
68 [&]( const FOOTPRINT* aFootprint )
69 {
70 return aFootprint->IsWithinSchematicSheet( aSheetPath );
71 } ) );
72 }
73
74 std::vector<BOARD_ITEM*> Resolve( const SyncSelection& aRequest ) const
75 {
76 return kiapi::board::FindItemsFromSyncSelection( m_board.get(), aRequest.items() );
77 }
78
80 std::unique_ptr<BOARD> m_board;
81};
82
83
84BOOST_FIXTURE_TEST_SUITE( CrossProbeSelection, CROSS_PROBE_SELECTION_FIXTURE )
85
86
87BOOST_AUTO_TEST_CASE( SheetSelectionFindsItsFootprints )
88{
89 BOOST_REQUIRE( m_board );
90 BOOST_REQUIRE_EQUAL( m_board->Footprints().size(), c_footprintsOnBoard );
91
92 BOOST_CHECK_EQUAL( CountOnSheet( SchematicPath( KIID(), c_verticalSheet ) ), c_footprintsPerSheet );
93 BOOST_CHECK_EQUAL( CountOnSheet( SchematicPath( KIID(), c_horizontalSheet ) ), c_footprintsPerSheet );
94}
95
96
97BOOST_AUTO_TEST_CASE( SiblingSheetsDoNotOverlap )
98{
99 // Both sheets instantiate ampli_ht.kicad_sch, so only the sheet UUID tells their symbols apart
100 KIID_PATH vertical = SchematicPath( KIID(), c_verticalSheet );
101 KIID_PATH horizontal = SchematicPath( KIID(), c_horizontalSheet );
102 std::size_t matched = 0;
103
104 for( FOOTPRINT* footprint : m_board->Footprints() )
105 {
106 bool onVertical = footprint->IsWithinSchematicSheet( vertical );
107 bool onHorizontal = footprint->IsWithinSchematicSheet( horizontal );
108
109 BOOST_CHECK( !( onVertical && onHorizontal ) );
110
111 if( onVertical || onHorizontal )
112 matched++;
113 }
114
116}
117
118
119BOOST_AUTO_TEST_CASE( RootSheetUuidIsIgnored )
120{
121 // The root sheet UUID is regenerated on load and never recorded in a footprint's path, so
122 // two schematic sessions must cross-probe to the same footprints
123 KIID_PATH firstSession = SchematicPath( KIID(), c_verticalSheet );
124 KIID_PATH secondSession = SchematicPath( KIID(), c_verticalSheet );
125
126 BOOST_REQUIRE( firstSession.front() != secondSession.front() );
127 BOOST_CHECK_EQUAL( CountOnSheet( firstSession ), CountOnSheet( secondSession ) );
128 BOOST_CHECK_EQUAL( CountOnSheet( firstSession ), c_footprintsPerSheet );
129}
130
131
132BOOST_AUTO_TEST_CASE( RootSheetSelectsTheWholeBoard )
133{
134 KIID_PATH rootOnly;
135 rootOnly.push_back( KIID() );
136
137 BOOST_CHECK_EQUAL( CountOnSheet( rootOnly ), c_footprintsOnBoard );
138 BOOST_CHECK_EQUAL( CountOnSheet( KIID_PATH() ), 0 );
139}
140
141
142BOOST_AUTO_TEST_CASE( PinSpecResolvesToItsPad )
143{
144 SyncSelection request;
145 SelectionSpec* spec = request.add_items();
146 spec->mutable_pad()->set_reference( "C4" );
147 spec->mutable_pad()->set_number( "2" );
148
149 std::vector<BOARD_ITEM*> items = Resolve( request );
150
151 BOOST_REQUIRE_EQUAL( items.size(), 1 );
152 BOOST_REQUIRE_EQUAL( items[0]->Type(), PCB_PAD_T );
153
154 PAD* pad = static_cast<PAD*>( items[0] );
155
156 BOOST_CHECK_EQUAL( pad->GetNumber(), wxS( "2" ) );
157 BOOST_CHECK_EQUAL( pad->GetParentFootprint()->GetReference(), wxS( "C4" ) );
158}
159
160
161BOOST_AUTO_TEST_CASE( SheetSpecResolvesThroughTheApi )
162{
163 SyncSelection request;
164 kiapi::common::PackSheetPath( *request.add_items()->mutable_sheet_path(),
165 SchematicPath( KIID(), c_verticalSheet ) );
166
167 BOOST_CHECK_EQUAL( Resolve( request ).size(), c_footprintsPerSheet );
168}
169
170
171BOOST_AUTO_TEST_CASE( SpecsResolveInRequestOrder )
172{
173 SyncSelection request;
174 request.add_items()->mutable_footprint()->set_reference( "C5" );
175 request.add_items()->mutable_footprint()->set_reference( "C3" );
176
177 std::vector<BOARD_ITEM*> items = Resolve( request );
178
179 BOOST_REQUIRE_EQUAL( items.size(), 2 );
180 BOOST_CHECK_EQUAL( static_cast<FOOTPRINT*>( items[0] )->GetReference(), wxS( "C5" ) );
181 BOOST_CHECK_EQUAL( static_cast<FOOTPRINT*>( items[1] )->GetReference(), wxS( "C3" ) );
182}
183
184
Definition kiid.h:46
Definition pad.h:61
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
std::vector< BOARD_ITEM * > FindItemsFromSyncSelection(const BOARD *aBoard, const google::protobuf::RepeatedPtrField< kiapi::common::commands::SelectionSpec > &aItems)
Resolve a cross-probe selection request against a board.
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
std::size_t CountOnSheet(const KIID_PATH &aSheetPath) const
std::vector< BOARD_ITEM * > Resolve(const SyncSelection &aRequest) const
KIID_PATH SchematicPath(const KIID &aRoot, const wxString &aSheet) const
Build the sheet path the schematic editor cross-probes with when a sheet is clicked.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
static const wxString c_verticalSheet
static const wxString c_horizontalSheet
BOOST_AUTO_TEST_CASE(SheetSelectionFindsItsFootprints)
static const std::size_t c_footprintsOnBoard
static const std::size_t c_footprintsPerSheet
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79