KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_annotation_units_conflicts.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 "eeschema_test_utils.h"
22
23#include <sch_reference_list.h>
24#include <lib_id.h>
25#include <refdes_tracker.h>
26#include <sch_symbol.h>
27
28#include <memory>
29
31{
32protected:
35 SCH_REFERENCE createTestReference( const wxString& aRef, const wxString& aValue, int aUnit,
36 const wxString& aLibName = wxS( "TestPart" ) )
37 {
38 SCH_SYMBOL* symbol = m_symbols.emplace_back( std::make_unique<SCH_SYMBOL>() ).get();
39 symbol->SetLibId( LIB_ID( wxEmptyString, aLibName ) );
40
42 SCH_REFERENCE ref( symbol, path );
43 ref.SetRef( aRef );
44 ref.SetValue( aValue );
45 ref.SetUnit( aUnit );
46
47 return ref;
48 }
49
50private:
51 std::vector<std::unique_ptr<SCH_SYMBOL>> m_symbols;
52};
53
54
55BOOST_FIXTURE_TEST_SUITE( UnitConflicts, TEST_ANNOTATION_UNITS_CONFLICTS )
56
57
58
59BOOST_AUTO_TEST_CASE( GetNextRefDesForUnits_Integration )
60{
61 REFDES_TRACKER tracker;
62 tracker.SetReuseRefDes( false );
63
64 // Test the overall GetNextRefDesForUnits logic using the tracker
65
66 // Preload some references to simulate previously used ones
67 tracker.Insert( "U1" );
68 tracker.Insert( "U5" );
69
70 // Test case 1: Completely unused reference with empty units
71 // Should get U2 (first unused after U1)
72 SCH_REFERENCE testRef = createTestReference( "U", "LM358", 1 );
73 std::map<int, std::vector<SCH_REFERENCE>> emptyMap;
74 std::vector<int> emptyUnits;
75
76 int nextRef = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
77 BOOST_CHECK_EQUAL( nextRef, 2 ); // Should skip U1, get U2
78
79 // Test case 2: Min value higher than next available
80 nextRef = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 10 );
81 BOOST_CHECK_EQUAL( nextRef, 10 ); // Should start from min value
82
83 // Verify references were inserted
84 BOOST_CHECK( tracker.Contains( "U2" ) );
85 BOOST_CHECK( tracker.Contains( "U10" ) );
86
87 // Test case 3: New prefix
88 SCH_REFERENCE icRef = createTestReference( "IC", "74HC00", 1 );
89 nextRef = tracker.GetNextRefDesForUnits( icRef, emptyMap, emptyUnits, 1 );
90 BOOST_CHECK_EQUAL( nextRef, 1 ); // New prefix should start at 1
91 BOOST_CHECK( tracker.Contains( "IC1" ) );
92}
93
94BOOST_AUTO_TEST_CASE( RefDesTracker_StateConsistency )
95{
96 REFDES_TRACKER tracker;
97 tracker.SetReuseRefDes( false );
98
99 // Test that the tracker maintains consistent state across operations
100
101 // Insert some references manually
102 BOOST_CHECK( tracker.Insert( "R1" ) );
103 BOOST_CHECK( tracker.Insert( "R3" ) );
104 BOOST_CHECK( tracker.Insert( "R5" ) );
105
106 // Verify they exist
107 BOOST_CHECK( tracker.Contains( "R1" ) );
108 BOOST_CHECK( tracker.Contains( "R3" ) );
109 BOOST_CHECK( tracker.Contains( "R5" ) );
110 BOOST_CHECK( !tracker.Contains( "R2" ) );
111 BOOST_CHECK( !tracker.Contains( "R4" ) );
112
113 // Test GetNextRefDesForUnits with empty units - should fill gap at R2
114 SCH_REFERENCE testRef = createTestReference( "R", "1k", 1 );
115 std::map<int, std::vector<SCH_REFERENCE>> emptyMap;
116 std::vector<int> emptyUnits;
117
118 int next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
120 BOOST_CHECK( tracker.Contains( "R2" ) );
121
122 // Get next reference - should fill gap at R4
123 next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
125 BOOST_CHECK( tracker.Contains( "R4" ) );
126
127 // Get next reference - should go to R6
128 next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
130 BOOST_CHECK( tracker.Contains( "R6" ) );
131
132 // Verify total count
133 BOOST_CHECK_EQUAL( tracker.Size(), 6 );
134}
135
136BOOST_AUTO_TEST_CASE( CacheConsistency_AfterInserts )
137{
138 REFDES_TRACKER tracker;
139 tracker.SetReuseRefDes( false );
140
141 // Test that cache remains consistent after mixed Insert/GetNextRefDesForUnits operations
142
143 // Start with some manual inserts
144 tracker.Insert( "C1" );
145 tracker.Insert( "C5" );
146 tracker.Insert( "C10" );
147
148 SCH_REFERENCE testRef = createTestReference( "C", "100nF", 1 );
149 std::map<int, std::vector<SCH_REFERENCE>> emptyMap;
150 std::vector<int> emptyUnits;
151
152 // Get next ref - should use cached logic to find C2
153 int next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
155
156 // Insert C3 manually
157 tracker.Insert( "C3" );
158
159 // Get next ref - cache should be updated, should get C4
160 next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
162
163 // Test with minimum value - should respect cache
164 next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 7 );
165 BOOST_CHECK_EQUAL( next, 7 ); // C6 available but min is 7
166
167 // Verify all references exist
168 BOOST_CHECK( tracker.Contains( "C1" ) );
169 BOOST_CHECK( tracker.Contains( "C2" ) );
170 BOOST_CHECK( tracker.Contains( "C3" ) );
171 BOOST_CHECK( tracker.Contains( "C4" ) );
172 BOOST_CHECK( tracker.Contains( "C5" ) );
173 BOOST_CHECK( !tracker.Contains( "C6" ) ); // Skipped due to min value
174 BOOST_CHECK( tracker.Contains( "C7" ) );
175 BOOST_CHECK( tracker.Contains( "C10" ) );
176}
177
178BOOST_AUTO_TEST_CASE( ThreadSafety_BasicValidation )
179{
180 REFDES_TRACKER tracker( true ); // Enable thread safety
181 tracker.SetReuseRefDes( false );
182
183 // Basic validation that thread-safe operations work
184 BOOST_CHECK( tracker.Insert( "U1" ) );
185 BOOST_CHECK( tracker.Contains( "U1" ) );
186
187 // Test GetNextRefDesForUnits with thread safety
188 SCH_REFERENCE testRef = createTestReference( "U", "LM358", 1 );
189 std::map<int, std::vector<SCH_REFERENCE>> emptyMap;
190 std::vector<int> emptyUnits;
191
192 int next = tracker.GetNextRefDesForUnits( testRef, emptyMap, emptyUnits, 1 );
194
195 // Test serialization with thread safety
196 std::string serialized = tracker.Serialize();
197 BOOST_CHECK( !serialized.empty() );
198
199 REFDES_TRACKER tracker2( true );
200 BOOST_CHECK( tracker2.Deserialize( serialized ) );
201 BOOST_CHECK( tracker2.Contains( "U1" ) );
202 BOOST_CHECK( tracker2.Contains( "U2" ) );
203}
204
A generic fixture for loading schematics and associated settings for qa tests.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
Class to efficiently track reference designators and provide next available designators.
bool Deserialize(const std::string &aData)
Deserialize tracker data from string representation.
int GetNextRefDesForUnits(const SCH_REFERENCE &aRef, const std::map< int, std::vector< SCH_REFERENCE > > &aRefNumberMap, const std::vector< int > &aRequiredUnits, int aMinValue)
Get the next available reference designator number for multi-unit symbols.
void SetReuseRefDes(bool aReuse)
bool Insert(const std::string &aRefDes)
Insert a reference designator into the tracker.
size_t Size() const
Get the total count of stored reference designators.
std::string Serialize() const
Serialize the tracker data to a compact string representation.
bool Contains(const std::string &aRefDes) const
Check if a reference designator exists in the tracker.
A helper to define a symbol's reference designator in a schematic.
void SetValue(const wxString &aValue)
void SetRef(const wxString &aReference)
void SetUnit(int aUnit)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:69
void SetLibId(const LIB_ID &aName)
std::vector< std::unique_ptr< SCH_SYMBOL > > m_symbols
SCH_REFERENCE createTestReference(const wxString &aRef, const wxString &aValue, int aUnit, const wxString &aLibName=wxS("TestPart"))
SCH_REFERENCE holds a raw pointer to its symbol and CompareLibName dereferences it,...
CITER next(CITER it)
Definition ptree.cpp:120
BOOST_AUTO_TEST_CASE(GetNextRefDesForUnits_Integration)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
std::string path
BOOST_CHECK_EQUAL(result, "25.4")