KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_text_var_reactive.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 along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <boost/test/unit_test.hpp>
21#include <algorithm>
22#include <board.h>
23#include <board_commit.h>
25#include <footprint.h>
26#include <pcb_field.h>
27#include <pcb_text.h>
29#include <text_var_dependency.h>
30#include <tool/tool_manager.h>
31
32
38BOOST_AUTO_TEST_SUITE( BoardTextVarReactive )
39
40
41BOOST_AUTO_TEST_CASE( AdapterIsInstalledOnConstruction )
42{
43 BOARD board;
46}
47
48
49BOOST_AUTO_TEST_CASE( AddingTextItemRegistersDependencies )
50{
51 BOARD board;
52 TOOL_MANAGER mgr;
53 mgr.SetEnvironment( &board, nullptr, nullptr, nullptr, nullptr );
55 mgr.RegisterTool( tool );
56 BOARD_COMMIT commit( tool );
57
58 PCB_TEXT* text = new PCB_TEXT( &board );
59 text->SetText( wxT( "${U1:VALUE}" ) );
60 commit.Add( text );
61 commit.Push( wxT( "add text" ), 0 );
62
65 index.DependentCount( TEXT_VAR_REF_KEY::FromToken( wxT( "U1:VALUE" ) ) ), 1u );
66}
67
68
69BOOST_AUTO_TEST_CASE( FootprintChangeFiresInvalidation )
70{
71 BOARD board;
72 TOOL_MANAGER mgr;
73 mgr.SetEnvironment( &board, nullptr, nullptr, nullptr, nullptr );
75 mgr.RegisterTool( tool );
76
77 // Add a footprint U1 with default fields, and a PCB_TEXT that depends on
78 // its VALUE.
79 {
80 BOARD_COMMIT commit( tool );
81 FOOTPRINT* fp = new FOOTPRINT( &board );
82 fp->SetReference( wxT( "U1" ) );
83 fp->SetValue( wxT( "10k" ) );
84 commit.Add( fp );
85
86 PCB_TEXT* text = new PCB_TEXT( &board );
87 text->SetText( wxT( "${U1:Value}" ) );
88 commit.Add( text );
89
90 commit.Push( wxT( "seed" ), 0 );
91 }
92
93 // Register an invalidate callback and then edit the footprint's value.
94 std::vector<std::pair<EDA_ITEM*, TEXT_VAR_REF_KEY>> invalidations;
96 [&]( EDA_ITEM* dep, const TEXT_VAR_REF_KEY& key )
97 { invalidations.emplace_back( dep, key ); } );
98
99 FOOTPRINT* fp = board.Footprints().front();
100
101 BOARD_COMMIT commit( tool );
102 commit.Modify( fp );
103 fp->SetValue( wxT( "100k" ) );
104 commit.Push( wxT( "edit value" ), 0 );
105
106 // The adapter should have fanned out ${U1:Value} among others. Look for
107 // at least one invalidation that targets a PCB_TEXT dependent.
108 bool sawTextDependent = std::any_of( invalidations.begin(), invalidations.end(),
109 []( const auto& pair )
110 { return pair.first && pair.first->Type() == PCB_TEXT_T; } );
111
112 BOOST_CHECK( sawTextDependent );
113}
114
115
116BOOST_AUTO_TEST_CASE( RemovedItemsAreUnregistered )
117{
118 BOARD board;
119 TOOL_MANAGER mgr;
120 mgr.SetEnvironment( &board, nullptr, nullptr, nullptr, nullptr );
122 mgr.RegisterTool( tool );
123
124 PCB_TEXT* text = nullptr;
125
126 {
127 BOARD_COMMIT commit( tool );
128 text = new PCB_TEXT( &board );
129 text->SetText( wxT( "${X}" ) );
130 commit.Add( text );
131 commit.Push( wxT( "add" ), 0 );
132 }
133
135 BOOST_CHECK_EQUAL( index.DependentCount( TEXT_VAR_REF_KEY::FromToken( wxT( "X" ) ) ), 1u );
136
137 {
138 BOARD_COMMIT commit( tool );
139 commit.Remove( text );
140 commit.Push( wxT( "remove" ), 0 );
141 }
142
143 BOOST_CHECK_EQUAL( index.DependentCount( TEXT_VAR_REF_KEY::FromToken( wxT( "X" ) ) ), 0u );
144}
145
146
147BOOST_AUTO_TEST_CASE( SpiceOPTokensAreNotRegistered )
148{
149 BOARD board;
150 TOOL_MANAGER mgr;
151 mgr.SetEnvironment( &board, nullptr, nullptr, nullptr, nullptr );
153 mgr.RegisterTool( tool );
154 BOARD_COMMIT commit( tool );
155
156 PCB_TEXT* text = new PCB_TEXT( &board );
157 text->SetText( wxT( "${OP:1}" ) );
158 commit.Add( text );
159 commit.Push( wxT( "add op" ), 0 );
160
161 // IsTrackable() gates OP keys out of registration entirely.
163 BOOST_CHECK_EQUAL( index.ItemCount(), 0u );
164}
165
166
167BOOST_AUTO_TEST_CASE( VariantSwitchFiresCrossRefInvalidation )
168{
169 BOARD board;
170 TOOL_MANAGER mgr;
171 mgr.SetEnvironment( &board, nullptr, nullptr, nullptr, nullptr );
173 mgr.RegisterTool( tool );
174
175 {
176 BOARD_COMMIT commit( tool );
177 FOOTPRINT* fp = new FOOTPRINT( &board );
178 fp->SetReference( wxT( "U1" ) );
179 fp->SetValue( wxT( "10k" ) );
180 commit.Add( fp );
181
182 PCB_TEXT* text = new PCB_TEXT( &board );
183 text->SetText( wxT( "${U1:Value}" ) );
184 commit.Add( text );
185
186 commit.Push( wxT( "seed" ), 0 );
187 }
188
189 board.AddVariant( wxT( "HighPrecision" ) );
190
191 std::vector<EDA_ITEM*> invalidations;
193 [&]( EDA_ITEM* dep, const TEXT_VAR_REF_KEY& ) { invalidations.push_back( dep ); } );
194
195 board.SetCurrentVariant( wxT( "HighPrecision" ) );
196
197 // The PCB_TEXT that depends on ${U1:Value} must have been invalidated —
198 // variant overrides change how that cross-ref resolves.
199 bool sawPcbText = std::any_of( invalidations.begin(), invalidations.end(),
200 []( EDA_ITEM* item )
201 { return item && item->Type() == PCB_TEXT_T; } );
202 BOOST_CHECK( sawPcbText );
203
204 // Redundant switch to the same variant must be a no-op.
205 invalidations.clear();
206 board.SetCurrentVariant( wxT( "HighPrecision" ) );
207 BOOST_CHECK( invalidations.empty() );
208}
209
210
int index
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
TEXT_VAR_TRACKER & Tracker()
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
BOARD_TEXT_VAR_ADAPTER * GetTextVarAdapter() const
Definition board.h:1675
void SetCurrentVariant(const wxString &aVariant)
Definition board.cpp:2737
void AddVariant(const wxString &aVariantName)
Definition board.cpp:2769
const FOOTPRINTS & Footprints() const
Definition board.h:364
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:90
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:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
void SetReference(const wxString &aReference)
Definition footprint.h:835
void SetValue(const wxString &aValue)
Definition footprint.h:856
Bidirectional index mapping TEXT_VAR_REF_KEY → dependent items and item → keys.
ListenerHandle AddInvalidateListener(InvalidateCallback aCallback)
Register a listener that fires for every invalidation.
TEXT_VAR_DEPENDENCY_INDEX & Index()
Master controller class:
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
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).
Identifies a single resolvable source that a text item's ${...} reference depends on.
static TEXT_VAR_REF_KEY FromToken(const wxString &aToken)
Parse a raw token (the text between ${ and }) into a key using lexical classification only — no looku...
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_CHECK_EQUAL(result, "25.4")
BOOST_AUTO_TEST_CASE(AdapterIsInstalledOnConstruction)
End-to-end reactive pipeline: BOARD commits + TEXT_VAR_TRACKER + BOARD_TEXT_VAR_ADAPTER together.