KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue23743_sync_derived_fields.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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
31
33
34#include <lib_symbol.h>
35#include <sch_field.h>
36#include <template_fieldnames.h>
37
38BOOST_AUTO_TEST_SUITE( SyncDerivedFields )
39
40
41
44BOOST_AUTO_TEST_CASE( PullsValueAndNewFieldFromParent )
45{
46 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
47 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
48
49 BOOST_REQUIRE( child->IsDerived() );
50
51 // Parent gains a value and a manufacturer field after the child already exists.
52 parent->GetValueField().SetText( "10k" );
53
54 SCH_FIELD* mfg = new SCH_FIELD( parent.get(), FIELD_T::USER, "Manufacturer" );
55 mfg->SetText( "ACME" );
56 parent->AddField( mfg );
57
58 BOOST_CHECK( child->GetValueField().GetText().IsEmpty() );
59 BOOST_CHECK_EQUAL( child->GetField( wxString( "Manufacturer" ) ), nullptr );
60
62 options.m_resetText = true;
63
64 child->SyncFieldsFromParent( options );
65
66 BOOST_CHECK_EQUAL( child->GetValueField().GetText(), wxString( "10k" ) );
67
68 SCH_FIELD* childMfg = child->GetField( wxString( "Manufacturer" ) );
69 BOOST_REQUIRE( childMfg );
70 BOOST_CHECK_EQUAL( childMfg->GetText(), wxString( "ACME" ) );
71}
72
73
77BOOST_AUTO_TEST_CASE( RespectsSelectedFieldSubset )
78{
79 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
80
81 SCH_FIELD* mfg = new SCH_FIELD( parent.get(), FIELD_T::USER, "Manufacturer" );
82 mfg->SetText( "ACME" );
83 parent->AddField( mfg );
84
85 SCH_FIELD* mpn = new SCH_FIELD( parent.get(), FIELD_T::USER, "MPN" );
86 mpn->SetText( "12345" );
87 parent->AddField( mpn );
88
89 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
90
92 options.m_resetText = true;
93 options.m_updateAllFields = false;
94 options.m_updateFields = { wxString( "Manufacturer" ) };
95
96 child->SyncFieldsFromParent( options );
97
98 BOOST_REQUIRE( child->GetField( wxString( "Manufacturer" ) ) );
99 BOOST_CHECK_EQUAL( child->GetField( wxString( "Manufacturer" ) )->GetText(), wxString( "ACME" ) );
100
101 // MPN was not selected, so it must not have been pulled in.
102 BOOST_CHECK_EQUAL( child->GetField( wxString( "MPN" ) ), nullptr );
103}
104
105
111BOOST_AUTO_TEST_CASE( MandatoryFieldSelectedByCanonicalName )
112{
113 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
114 parent->GetValueField().SetText( "10k" );
115
116 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
117
119 options.m_resetText = true;
120 options.m_updateAllFields = false;
122
123 child->SyncFieldsFromParent( options );
124
125 BOOST_CHECK_EQUAL( child->GetValueField().GetText(), wxString( "10k" ) );
126}
127
128
132BOOST_AUTO_TEST_CASE( EmptySelectionUpdatesNothing )
133{
134 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
135 parent->GetValueField().SetText( "10k" );
136
137 SCH_FIELD* mfg = new SCH_FIELD( parent.get(), FIELD_T::USER, "Manufacturer" );
138 mfg->SetText( "ACME" );
139 parent->AddField( mfg );
140
141 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
142
144 options.m_updateAllFields = false;
145 options.m_resetText = true;
146
147 child->SyncFieldsFromParent( options );
148
149 BOOST_CHECK( child->GetValueField().GetText().IsEmpty() );
150 BOOST_CHECK_EQUAL( child->GetField( wxString( "Manufacturer" ) ), nullptr );
151}
152
153
157BOOST_AUTO_TEST_CASE( RemoveExtraFieldsOptional )
158{
159 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
160 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
161
162 SCH_FIELD* extra = new SCH_FIELD( child.get(), FIELD_T::USER, "ChildOnly" );
163 extra->SetText( "keep-me" );
164 child->AddField( extra );
165
166 // Without removeExtraFields the child-only field survives.
168 child->SyncFieldsFromParent( keep );
169 BOOST_REQUIRE( child->GetField( wxString( "ChildOnly" ) ) );
170
171 // With removeExtraFields it is dropped, since the parent has no such field.
173 strip.m_removeExtraFields = true;
174 child->SyncFieldsFromParent( strip );
175 BOOST_CHECK_EQUAL( child->GetField( wxString( "ChildOnly" ) ), nullptr );
176}
177
178
182BOOST_AUTO_TEST_CASE( ResetVisibilityFromParent )
183{
184 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
185
186 SCH_FIELD* mfg = new SCH_FIELD( parent.get(), FIELD_T::USER, "Manufacturer" );
187 mfg->SetText( "ACME" );
188 mfg->SetVisible( true );
189 parent->AddField( mfg );
190
191 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
192
193 // Pull the field in first (hidden by default for a fresh user field).
195 add.m_resetText = true;
196 child->SyncFieldsFromParent( add );
197
198 SCH_FIELD* childMfg = child->GetField( wxString( "Manufacturer" ) );
199 BOOST_REQUIRE( childMfg );
200 childMfg->SetVisible( false );
201
203 vis.m_resetVisibility = true;
204 child->SyncFieldsFromParent( vis );
205
206 BOOST_CHECK( child->GetField( wxString( "Manufacturer" ) )->IsVisible() );
207}
208
209
213BOOST_AUTO_TEST_CASE( RootSymbolUnchanged )
214{
215 std::unique_ptr<LIB_SYMBOL> root = std::make_unique<LIB_SYMBOL>( "root" );
216 root->GetValueField().SetText( "orig" );
217
218 BOOST_REQUIRE( root->IsRoot() );
219
221 options.m_resetText = true;
222 root->SyncFieldsFromParent( options );
223
224 BOOST_CHECK_EQUAL( root->GetValueField().GetText(), wxString( "orig" ) );
225}
226
227
233BOOST_AUTO_TEST_CASE( CanUpdateFieldsGate )
234{
235 std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
236 std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
237
238 BOOST_CHECK( !parent->CanUpdateFieldsFromParent() );
239 BOOST_CHECK( child->CanUpdateFieldsFromParent() );
240}
241
242
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:381
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
void SetText(const wxString &aText) override
Options controlling how a derived symbol's fields are reconciled with its parent.
Definition lib_symbol.h:80
bool m_removeExtraFields
Drop fields not present in the parent.
Definition lib_symbol.h:88
bool m_resetVisibility
Copy parent visibility and name-shown flags.
Definition lib_symbol.h:91
bool m_updateAllFields
Reconcile every field. When false only the names in m_updateFields are touched.
Definition lib_symbol.h:82
std::set< wxString > m_updateFields
Field names to reconcile when m_updateAllFields is false.
Definition lib_symbol.h:85
bool m_resetText
Copy parent text when the parent value is non-empty.
Definition lib_symbol.h:100
@ USER
The field ID hasn't been set yet; field is invalid.
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(PullsValueAndNewFieldFromParent)
A parent value change and a brand-new parent field both propagate to the derived child.
BOOST_CHECK_EQUAL(result, "25.4")