KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_field_names.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 3
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 <array>
24#include <set>
25#include <advanced_config.h>
27#include <erc/erc.h>
28#include <locale_io.h>
29#include <sch_commit.h>
30#include <sch_field.h>
31#include <sch_marker.h>
32#include <sch_sheet.h>
33#include <sch_symbol.h>
34#include <schematic.h>
36#include <tool/tool_manager.h>
37#include <scoped_set_reset.h>
38
39BOOST_AUTO_TEST_CASE( ERCFieldNamesRetainSymbolAndSheetSnapshots )
40{
41 LOCALE_IO locale;
42 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
43 SCOPED_SET_RESET restore( enabled, enabled );
44
45 for( bool backend : { false, true } )
46 {
47 BOOST_TEST_CONTEXT( "new engine=" << backend )
48 {
49 enabled = backend;
50 SETTINGS_MANAGER settings;
51 std::unique_ptr<SCHEMATIC> schematic;
52 KI_TEST::LoadSchematic( settings, "legacy_hierarchy/legacy_hierarchy", schematic );
53 std::vector<SCH_SHEET_PATH> paths;
54
55 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
56 {
57 if( path.LastScreen()->GetFileName().EndsWith( "ampli_ht.kicad_sch" ) )
58 paths.push_back( path );
59 }
60
61 BOOST_REQUIRE_EQUAL( paths.size(), 2 );
62 SCH_SCREEN* screen = paths[0].LastScreen();
63 BOOST_REQUIRE( screen == paths[1].LastScreen() );
64 SCH_SYMBOL* symbol = nullptr;
65
66 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
67 {
68 symbol = static_cast<SCH_SYMBOL*>( item );
69 break;
70 }
71
72 BOOST_REQUIRE( symbol );
73 SCH_SHEET* sheet = paths[0].Last();
74 BOOST_REQUIRE( sheet );
75 const wxString badName( " Snapshot Field " );
76 symbol->AddField( SCH_FIELD( symbol, FIELD_T::USER, badName ) );
77 sheet->AddField( SCH_FIELD( sheet, FIELD_T::USER, badName ) );
78 SCH_FIELD* symbolField = symbol->GetField( badName );
79 SCH_FIELD* sheetField = sheet->GetField( badName );
80 BOOST_REQUIRE( symbolField );
81 BOOST_REQUIRE( sheetField );
82 const std::array<SCH_FIELD*, 2> fields{ symbolField, sheetField };
83 const std::array<KIID, 2> owners{ symbol->m_Uuid, sheet->m_Uuid };
84 std::array<VECTOR2I, 2> positions;
85
86 for( size_t i = 0; i < fields.size(); ++i )
87 {
88 fields[i]->SetPosition( VECTOR2I( 1000000 + i * 1000000, 3000000 ) );
89 positions[i] = fields[i]->GetPosition();
90 }
91
92 schematic->RebuildConnectivity();
93 schematic->SetCurrentSheet( paths[1] );
94 ERC_TESTER tester( schematic.get() );
95 const auto check = [&]( bool present )
96 {
97 BOOST_CHECK_EQUAL( tester.TestFieldNameWhitespace(), present ? 3 : 0 );
98 std::array<std::set<KIID_PATH>, 2> seen;
99 std::vector<std::pair<SCH_SCREEN*, SCH_MARKER*>> markers;
100
101 for( SCH_SCREEN* current : { schematic->RootScreen(), screen } )
102 {
103 for( SCH_ITEM* item : current->Items().OfType( SCH_MARKER_T ) )
104 {
105 auto* marker = static_cast<SCH_MARKER*>( item );
106 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() );
107 markers.emplace_back( current, marker );
108
109 if( error->GetErrorCode() != ERCE_FIELD_NAME_WHITESPACE )
110 continue;
111
112 for( size_t i = 0; i < fields.size(); ++i )
113 {
114 if( error->GetMainItemID() != owners[i] )
115 continue;
116
117 BOOST_CHECK( error->GetAuxItemID() == fields[i]->m_Uuid );
118 BOOST_CHECK( marker->GetPosition() == positions[i] );
119 BOOST_CHECK( error->GetErrorMessage( true ).Contains( badName ) );
120 BOOST_REQUIRE( error->IsSheetSpecific() );
121 const KIID_PATH& path = error->GetSpecificSheetPath().PathRef();
122 BOOST_CHECK( error->GetMainItemSheetPath().PathRef() == path );
123 BOOST_CHECK( error->GetAuxItemSheetPath().PathRef() == path );
124 BOOST_CHECK( seen[i].insert( path ).second );
125 }
126 }
127 }
128
129 const std::set<KIID_PATH> symbolPaths = present
130 ? std::set<KIID_PATH>{ paths[0].PathRef(), paths[1].PathRef() } : std::set<KIID_PATH>{};
131 const std::set<KIID_PATH> sheetPaths = present
132 ? std::set<KIID_PATH>{ schematic->Hierarchy().front().PathRef() } : std::set<KIID_PATH>{};
133 BOOST_CHECK( seen[0] == symbolPaths );
134 BOOST_CHECK( seen[1] == sheetPaths );
135
136 for( const auto& [current, marker] : markers )
137 current->DeleteItem( marker );
138 };
139 check( true );
140
141 for( SCH_FIELD* field : fields )
142 {
143 field->SetName( "Snapshot Field" );
144 field->SetPosition( field->GetPosition() + VECTOR2I( 500000, 500000 ) );
145 }
146
147 schematic->RebuildConnectivity();
148 check( false );
149
150 for( size_t i = 0; i < fields.size(); ++i )
151 {
152 fields[i]->SetName( badName );
153 positions[i] = fields[i]->GetPosition();
154 }
155
156 schematic->RebuildConnectivity();
157 check( true );
158
159 TOOL_MANAGER manager;
160
161 for( size_t i = 0; i < fields.size(); ++i )
162 {
163 SCH_COMMIT commit( &manager );
164 commit.Modify( fields[i], i == 0 ? screen : schematic->RootScreen() );
165 fields[i]->SetPosition( fields[i]->GetPosition() + VECTOR2I( 500000, 0 ) );
166 positions[i] = fields[i]->GetPosition();
167 }
168
169 if( backend )
170 schematic->Connectivity().Recalculate( *schematic, false );
171 else
172 schematic->RebuildConnectivity();
173
174 check( true );
175 }
176 }
177}
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
const KIID m_Uuid
Definition eda_item.h:597
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:248
Runs the electrical rules checks and adds a SCH_MARKER for each violation.
Definition erc.h:60
int TestFieldNameWhitespace()
Check for field names with leading or trailing whitespace.
Definition erc.cpp:804
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:122
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a @aField to the list of fields.
Schematic symbol object.
Definition sch_symbol.h:74
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
RAII class that sets an value at construction and resets it to the original value at destruction.
Master controller class:
@ ERCE_FIELD_NAME_WHITESPACE
Field name has leading or trailing whitespace.
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ USER
The field ID hasn't been set yet; field is invalid.
BOOST_AUTO_TEST_CASE(ERCFieldNamesRetainSymbolAndSheetSnapshots)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string path
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_MARKER_T
Definition typeinfo.h:154
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683