KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_connectivity_reference.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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#include <advanced_config.h>
24#include <json_common.h>
25#include <project.h>
29#include <schematic.h>
30#include <sch_commit.h>
31#include <sch_line.h>
32#include <sch_screen.h>
33#include <sch_sheet.h>
34#include <sch_sheet_path.h>
35#include <sch_sheet_pin.h>
37#include <scoped_set_reset.h>
38#include <tool/tool_manager.h>
39
40#include <algorithm>
41#include <array>
42#include <map>
43#include <memory>
44#include <set>
45#include <string>
46#include <utility>
47#include <vector>
48
49namespace
50{
51using NET_NAMES = std::map<std::pair<std::string, std::string>, std::string>;
52
53// Legacy records each island's own driver while the engine records the whole net's winner
54void EraseDrivers( nlohmann::json& aValue )
55{
56 if( aValue.is_object() )
57 {
58 aValue.erase( "driver" );
59 aValue.erase( "driver_path" );
60 }
61
62 if( aValue.is_structured() )
63 {
64 for( auto& child : aValue )
65 EraseDrivers( child );
66 }
67}
68
69std::string UserVisible( const std::string& aDump )
70{
71 auto rows = nlohmann::json::parse( aDump );
72 EraseDrivers( rows );
73 return rows.dump( 2 );
74}
75
76std::string CommittedDump( SCHEMATIC& aSchematic )
77{
78 return UserVisible( ADVANCED_CFG::GetCfg().m_ConnectivityEngine
79 ? SCH_CONNECTIVITY::Dump( aSchematic, aSchematic.Connectivity() )
80 : SCH_CONNECTIVITY::Dump( aSchematic ) );
81}
82
83// Legacy runs compare against the engine rebuild too, so legacy stays the reference
84std::string RebuiltDump( SCHEMATIC& aSchematic )
85{
87 full.Update( aSchematic, true );
88 return UserVisible( SCH_CONNECTIVITY::Dump( aSchematic, full ) );
89}
90
91NET_NAMES NetNames( const std::string& aDump )
92{
93 NET_NAMES result;
94
95 for( const auto& row : nlohmann::json::parse( aDump ) )
96 {
97 result.emplace( std::pair{ row.at( "path" ).get<std::string>(), row.at( "item" ).get<std::string>() },
98 row.at( "name" ).get<std::string>() );
99 }
100
101 return result;
102}
103
104std::string NetName( const NET_NAMES& aNames, const KIID_PATH& aPath, const KIID& aItem )
105{
106 const auto found = aNames.find( { aPath.AsString().ToStdString( wxConvUTF8 ),
107 aItem.AsString().ToStdString( wxConvUTF8 ) } );
108 BOOST_REQUIRE_MESSAGE( found != aNames.end(),
109 "Missing row " << aPath.AsString() << " " << aItem.AsString() );
110 return found->second;
111}
112} // namespace
113
114BOOST_AUTO_TEST_SUITE( ConnectivityReference )
115
116BOOST_AUTO_TEST_CASE( NativeThreeInstancesPropagateChildShortAndRestore )
117{
118 auto& config = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
119 SCOPED_SET_RESET engine( config.m_ConnectivityEngine, config.m_ConnectivityEngine );
120 SCOPED_SET_RESET incremental( config.m_IncrementalConnectivity, true );
121
122 for( bool enabled : { false, true } )
123 {
124 BOOST_TEST_CONTEXT( "new engine " << enabled )
125 {
126 config.m_ConnectivityEngine = enabled;
127 SETTINGS_MANAGER settings;
128 std::unique_ptr<SCHEMATIC> schematic;
129 KI_TEST::LoadSchematic( settings, "netlists/issue14818/issue14818", schematic );
130 const auto hierarchy = schematic->Hierarchy();
131 BOOST_REQUIRE_EQUAL( hierarchy.size(), 4u );
132 std::vector<SCH_SHEET_PATH> children;
133
134 for( const SCH_SHEET_PATH& path : hierarchy )
135 {
136 if( path.size() == 2 )
137 children.push_back( path );
138 }
139
140 BOOST_REQUIRE_EQUAL( children.size(), 3u );
141 std::sort( children.begin(), children.end(), []( const auto& lhs, const auto& rhs )
142 {
143 return lhs.Last()->GetName() < rhs.Last()->GetName();
144 } );
145 SCH_SCREEN* screen = children.front().LastScreen();
146 SCH_LINE* bridge = nullptr;
147
148 for( SCH_ITEM* item : screen->Items().OfType( SCH_LINE_T ) )
149 {
150 BOOST_REQUIRE( !bridge );
151 bridge = static_cast<SCH_LINE*>( item );
152 }
153
154 BOOST_REQUIRE( bridge );
155 BOOST_REQUIRE( bridge->IsWire() );
156 BOOST_REQUIRE( bridge->m_Uuid == KIID( "af3971fe-9d70-4180-aec7-06849506172b" ) );
157 TOOL_MANAGER manager;
158 manager.SetEnvironment( schematic.get(), nullptr, nullptr, nullptr, nullptr );
159 schematic->SetCurrentSheet( children.front() );
160 schematic->RecalculateConnections( nullptr, GLOBAL_CLEANUP, &manager );
161 const VECTOR2I originalEnd = bridge->GetEndPoint();
162 const KIID_PATH root = hierarchy.front().Path();
163 const auto check = [&]( bool joined )
164 {
165 const std::string committed = CommittedDump( *schematic );
166 const NET_NAMES names = NetNames( committed );
167 std::array<std::string, 6> parentNets;
168
169 for( size_t index = 0; index < children.size(); ++index )
170 {
171 const auto& path = children[index];
172 BOOST_REQUIRE( path.LastScreen() == screen );
173 BOOST_REQUIRE( path.Last()->GetName() == wxString::Format( "Sub%zu", index + 1 ) );
174 BOOST_REQUIRE_EQUAL( path.Last()->GetPins().size(), 2u );
175 std::set<wxString> texts;
176
177 for( const SCH_SHEET_PIN* pin : path.Last()->GetPins() )
178 {
179 BOOST_REQUIRE( pin->GetText() == wxString( "in" ) || pin->GetText() == wxString( "out" ) );
180 BOOST_REQUIRE( texts.insert( pin->GetText() ).second );
181 const bool input = pin->GetText() == wxString( "in" );
182 const KIID child( input ? "fbac9619-48e4-4bb4-ae58-b737c341dfb7"
183 : "6b540c7f-cd51-4ae0-9753-e62094939d20" );
184 const std::string parentNet = NetName( names, root, pin->m_Uuid );
185 BOOST_CHECK( !parentNet.empty() );
186 BOOST_CHECK_EQUAL( parentNet, NetName( names, path.Path(), child ) );
187 parentNets[2 * index + !input] = parentNet;
188 }
189 }
190
191 for( size_t first = 0; first < parentNets.size(); ++first )
192 {
193 for( size_t second = first + 1; second < parentNets.size(); ++second )
194 {
195 const bool parentBridge = ( first == 1 && second == 2 ) || ( first == 3 && second == 4 );
196 BOOST_CHECK_EQUAL( parentNets[first] == parentNets[second], joined || parentBridge );
197 }
198 }
199
200 BOOST_CHECK_EQUAL( committed, RebuiltDump( *schematic ) );
201 return committed;
202 };
203 const std::string baseline = check( true );
204 const auto edit = [&]( const VECTOR2I& end )
205 {
206 SCH_COMMIT commit( &manager );
207 commit.Modify( bridge, screen );
208 bridge->SetEndPoint( end );
209 commit.Push( "Move Child Wire Endpoint", SKIP_UNDO );
210 };
211 edit( originalEnd + VECTOR2I( 0, 1270000 ) );
212 BOOST_CHECK( check( false ) != baseline );
213 edit( originalEnd );
214 BOOST_CHECK_EQUAL( check( true ), baseline );
215 }
216 }
217}
218
219
220BOOST_AUTO_TEST_CASE( NativeGlobalBridgeCommitsRefreshUnchangedSibling )
221{
222 auto& config = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
223 SCOPED_SET_RESET engine( config.m_ConnectivityEngine, config.m_ConnectivityEngine );
224 SCOPED_SET_RESET incremental( config.m_IncrementalConnectivity, true );
225
226 for( bool enabled : { false, true } )
227 {
228 BOOST_TEST_CONTEXT( "new engine " << enabled )
229 {
230 config.m_ConnectivityEngine = enabled;
231 SETTINGS_MANAGER settings;
232 std::unique_ptr<SCHEMATIC> schematic;
233 KI_TEST::LoadSchematic( settings, "netlists/issue14657/issue14657", schematic );
234 auto hierarchy = schematic->Hierarchy();
235 BOOST_REQUIRE_EQUAL( hierarchy.size(), 3u );
236 std::sort( hierarchy.begin(), hierarchy.end(), []( const auto& lhs, const auto& rhs )
237 {
238 return lhs.size() != rhs.size() ? lhs.size() < rhs.size()
239 : lhs.Last()->GetName() < rhs.Last()->GetName();
240 } );
241 BOOST_REQUIRE_EQUAL( hierarchy[0].size(), 1u );
242 BOOST_REQUIRE_EQUAL( hierarchy[1].size(), 2u );
243 BOOST_REQUIRE_EQUAL( hierarchy[2].size(), 2u );
244 BOOST_REQUIRE_EQUAL( hierarchy[1].Last()->GetName(), wxString( "subsheet1" ) );
245 BOOST_REQUIRE_EQUAL( hierarchy[2].Last()->GetName(), wxString( "subsheet2" ) );
246 SCH_SCREEN* screen = hierarchy[1].LastScreen();
247 BOOST_REQUIRE( screen != hierarchy[0].LastScreen() );
248 BOOST_REQUIRE( screen != hierarchy[2].LastScreen() );
249 BOOST_REQUIRE( hierarchy[0].LastScreen() != hierarchy[2].LastScreen() );
250 SCH_LINE* bridge = nullptr;
251
252 for( SCH_ITEM* item : screen->Items().OfType( SCH_LINE_T ) )
253 {
254 if( item->m_Uuid == KIID( "7e736d0c-601c-4f96-b4d2-138dfebf5932" ) )
255 bridge = static_cast<SCH_LINE*>( item );
256 }
257
258 BOOST_REQUIRE( bridge );
259 BOOST_REQUIRE( bridge->IsWire() );
260 TOOL_MANAGER manager;
261 manager.SetEnvironment( schematic.get(), nullptr, nullptr, nullptr, nullptr );
262 schematic->SetCurrentSheet( hierarchy[1] );
263 schematic->RecalculateConnections( nullptr, GLOBAL_CLEANUP, &manager );
264 const VECTOR2I originalEnd = bridge->GetEndPoint();
265 const KIID_PATH root = hierarchy[0].Path();
266 const KIID_PATH source = hierarchy[1].Path();
267 const KIID_PATH sibling = hierarchy[2].Path();
268 const std::vector<std::pair<KIID_PATH, KIID>> recipients{
269 { source, KIID( "24390c04-0f13-48b6-ae5a-ba48240c3289" ) },
270 { root, KIID( "2c0a5cdb-9772-4ba5-a787-71f4817b1e17" ) },
271 { root, KIID( "c87e9573-e811-44b1-99a7-05b54a8ac7d3" ) },
272 { root, KIID( "7ea56b40-7e69-4f46-899d-916eb5319378" ) },
273 { sibling, KIID( "837954e7-e02c-47dc-b569-f7787b8dce47" ) },
274 { sibling, KIID( "59996eb8-69ab-4ef2-9ed0-6da263326213" ) },
275 { sibling, KIID( "c836a852-d408-4f5b-9d40-88c91302bb01" ) },
276 { sibling, KIID( "6e69c8b0-e3b4-4882-ae1e-33126ecb39b0" ) }
277 };
278 const auto check = [&]( bool joined )
279 {
280 const std::string committed = CommittedDump( *schematic );
281 const NET_NAMES names = NetNames( committed );
282 const std::string expected = joined ? "GPIO1_14__46" : "REG_ENABLE";
283 BOOST_CHECK_EQUAL( NetName( names, source, KIID( "ab3b04ea-7320-437f-91d8-0dbd1001f3f9" ) ),
284 "GPIO1_14__46" );
285
286 for( const auto& [path, item] : recipients )
287 BOOST_CHECK_EQUAL( NetName( names, path, item ), expected );
288
289 BOOST_CHECK_EQUAL( committed, RebuiltDump( *schematic ) );
290 return committed;
291 };
292 const std::string baseline = check( true );
293 const auto edit = [&]( const VECTOR2I& end )
294 {
295 SCH_COMMIT commit( &manager );
296 commit.Modify( bridge, screen );
297 bridge->SetEndPoint( end );
298 commit.Push( "Move Global Bridge Endpoint", SKIP_UNDO );
299 };
300 edit( originalEnd - VECTOR2I( 1270000, 0 ) );
301 BOOST_CHECK( check( false ) != baseline );
302 edit( originalEnd );
303 BOOST_CHECK_EQUAL( check( true ), baseline );
304 }
305 }
306}
307
308
309BOOST_AUTO_TEST_CASE( NativeCommittedMoveOutOfRuleAreaRefreshesNetclasses )
310{
311 auto& config = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
312 SCOPED_SET_RESET engine( config.m_ConnectivityEngine, config.m_ConnectivityEngine );
313 SCOPED_SET_RESET incremental( config.m_IncrementalConnectivity, true );
314
315 for( bool enabled : { false, true } )
316 {
317 BOOST_TEST_CONTEXT( "new engine " << enabled )
318 {
319 config.m_ConnectivityEngine = enabled;
320 SETTINGS_MANAGER settings;
321 std::unique_ptr<SCHEMATIC> schematic;
322 KI_TEST::LoadSchematic( settings, "netlists/multinetclasses/multinetclasses", schematic );
323 SCH_SCREEN* screen = schematic->RootScreen();
324 const SCH_SHEET_PATH path = schematic->Hierarchy().front();
325 SCH_ITEM* stationaryArea = screen->GetConnectivityItem( KIID( "6ba20b94-0e46-4b8f-a023-c91a1d3b84ac" ) );
326 BOOST_REQUIRE( stationaryArea );
327 const VECTOR2I areaPosition = stationaryArea->GetPosition();
328 std::vector<SCH_ITEM*> netItems;
329
330 for( const char* uuid : { "47160e4c-50a1-41c1-9f26-94bda63350fa", "f1308710-8c5c-4584-a706-b3735972840b",
331 "20fe2096-2c56-4c5a-be18-dd8ed4e8c24b", "8598689f-ce4f-414f-a720-b8fa4ecb6b41",
332 "17b6ce67-6699-41d5-a096-6714796adaa3" } )
333 {
334 SCH_ITEM* item = screen->GetConnectivityItem( KIID( uuid ) );
335 BOOST_REQUIRE( item );
336 netItems.push_back( item );
337 }
338
339 TOOL_MANAGER manager;
340 manager.SetEnvironment( schematic.get(), nullptr, nullptr, nullptr, nullptr );
341 schematic->SetCurrentSheet( path );
342 schematic->RecalculateConnections( nullptr, GLOBAL_CLEANUP, &manager );
343 auto netSettings = schematic->Project().GetProjectFile().NetSettings();
344 const auto originalAssignments = netSettings->GetNetclassLabelAssignments();
345 auto movedAssignments = originalAssignments;
346 BOOST_REQUIRE_EQUAL( movedAssignments.at( wxString( "/NET_3" ) ).erase( wxString( "CLASS3" ) ), 1u );
347 BOOST_REQUIRE_EQUAL( movedAssignments.at( wxString( "/NET_3" ) ).erase( wxString( "CLASS4" ) ), 1u );
348 BOOST_REQUIRE( movedAssignments.at( wxString( "/NET_3" ) ).contains( wxString( "CLASS_COMPLETE" ) ) );
349 const auto move = [&]( const VECTOR2I& offset, const auto& assignments )
350 {
351 SCH_COMMIT commit( &manager );
352
353 for( SCH_ITEM* item : netItems )
354 {
355 commit.Modify( item, screen );
356 item->Move( offset );
357 }
358
359 commit.Push( "Move Net Out Of Rule Area", SKIP_UNDO );
360 BOOST_CHECK( stationaryArea->GetPosition() == areaPosition );
361 BOOST_CHECK( netSettings->GetNetclassLabelAssignments() == assignments );
363 full.Update( *schematic, true );
364 BOOST_CHECK_EQUAL( CommittedDump( *schematic ),
365 UserVisible( SCH_CONNECTIVITY::Dump( *schematic, full ) ) );
366 full.ApplyNetclasses( *netSettings );
367 BOOST_CHECK( netSettings->GetNetclassLabelAssignments() == assignments );
368 };
369 move( VECTOR2I( 0, 508000 ), movedAssignments );
370 move( VECTOR2I( 0, -508000 ), originalAssignments );
371 }
372 }
373}
374
375
376BOOST_AUTO_TEST_CASE( NativeCommittedDirectiveMoveReassignsNetclasses )
377{
378 auto& config = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
379 SCOPED_SET_RESET engine( config.m_ConnectivityEngine, config.m_ConnectivityEngine );
380 SCOPED_SET_RESET incremental( config.m_IncrementalConnectivity, true );
381
382 for( bool enabled : { false, true } )
383 {
384 BOOST_TEST_CONTEXT( "new engine " << enabled )
385 {
386 config.m_ConnectivityEngine = enabled;
387 SETTINGS_MANAGER settings;
388 std::unique_ptr<SCHEMATIC> schematic;
389 KI_TEST::LoadSchematic( settings, "netlists/multinetclasses/multinetclasses", schematic );
390 SCH_SCREEN* screen = schematic->RootScreen();
391 const SCH_SHEET_PATH path = schematic->Hierarchy().front();
392 SCH_ITEM* directive = screen->GetConnectivityItem( KIID( "20fe2096-2c56-4c5a-be18-dd8ed4e8c24b" ) );
393 SCH_ITEM* target = screen->GetConnectivityItem( KIID( "6145ae74-b637-4a72-a5de-ad08388fb892" ) );
394 BOOST_REQUIRE( directive );
395 BOOST_REQUIRE( target );
396 BOOST_REQUIRE( directive->Type() == SCH_DIRECTIVE_LABEL_T );
397 BOOST_REQUIRE( target->Type() == SCH_LABEL_T );
398 const VECTOR2I original = directive->GetPosition();
399 TOOL_MANAGER manager;
400 manager.SetEnvironment( schematic.get(), nullptr, nullptr, nullptr, nullptr );
401 schematic->SetCurrentSheet( path );
402 schematic->RecalculateConnections( nullptr, GLOBAL_CLEANUP, &manager );
403 const NET_NAMES names = NetNames( CommittedDump( *schematic ) );
404 const wxString sourceName = wxString::FromUTF8( NetName( names, path.Path(), directive->m_Uuid ) );
405 const wxString targetName = wxString::FromUTF8( NetName( names, path.Path(), target->m_Uuid ) );
406 BOOST_REQUIRE( !sourceName.IsEmpty() );
407 BOOST_REQUIRE( !targetName.IsEmpty() );
408 BOOST_REQUIRE( sourceName != targetName );
409 auto netSettings = schematic->Project().GetProjectFile().NetSettings();
410 const auto originalAssignments = netSettings->GetNetclassLabelAssignments();
411 BOOST_REQUIRE( originalAssignments.at( sourceName ).contains( wxString( "CLASS_COMPLETE" ) ) );
412 BOOST_REQUIRE( !originalAssignments.at( targetName ).contains( wxString( "CLASS_COMPLETE" ) ) );
413 auto movedAssignments = originalAssignments;
414 movedAssignments.at( sourceName ).erase( wxString( "CLASS_COMPLETE" ) );
415 movedAssignments.at( targetName ).insert( wxString( "CLASS_COMPLETE" ) );
416 const auto move = [&]( const VECTOR2I& position, const auto& expected )
417 {
418 SCH_COMMIT commit( &manager );
419 commit.Modify( directive, screen );
420 directive->SetPosition( position );
421 commit.Push( "Move Netclass Directive", SKIP_UNDO );
422 BOOST_CHECK( netSettings->GetNetclassLabelAssignments() == expected );
423 BOOST_CHECK_EQUAL( CommittedDump( *schematic ), RebuiltDump( *schematic ) );
424 };
425 move( target->GetPosition(), movedAssignments );
426 move( original, originalAssignments );
427 }
428 }
429}
430
int index
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
virtual VECTOR2I GetPosition() const
Definition eda_item.h:348
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:349
const KIID m_Uuid
Definition eda_item.h:597
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:248
wxString AsString() const
Definition kiid.cpp:423
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
Holds all the data relating to one schematic.
Definition schematic.h:149
SCH_CONNECTIVITY::FACADE & Connectivity() const
Definition schematic.h:316
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Model-owned source resolver.
void Update(SCHEMATIC &aSchematic, bool aRebuild=false)
void ApplyNetclasses(NET_SETTINGS &aSettings) const
Replace label-derived assignments from a complete publication; invalidate changed net caches.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
bool IsWire() const
Return true if the line is a wire.
VECTOR2I GetEndPoint() const
Definition sch_line.h:145
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:146
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:122
SCH_ITEM * GetConnectivityItem(const KIID &aId) const
Resolve a drawing item or a connectable child on this screen; ambiguous IDs return null.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
RAII class that sets an value at construction and resets it to the original value at destruction.
Master controller class:
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
std::string Dump(SCHEMATIC &aSchematic)
Canonical, pointer-free connectivity rows for migration and rebuild comparisons.
#define SKIP_UNDO
Definition sch_commit.h:38
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ GLOBAL_CLEANUP
Definition schematic.h:95
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(NativeThreeInstancesPropagateChildShortAndRestore)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
KIBIS_PIN * pin
VECTOR3I expected(15, 30, 45)
VECTOR2I end
BOOST_TEST_CONTEXT("Test Clearance")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_LINE_T
Definition typeinfo.h:159
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:167
@ SCH_LABEL_T
Definition typeinfo.h:163
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683