KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_merge_validators.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, you may find one here:
18
* http://www.gnu.org/licenses/gpl-3.0.html
19
* or you may search the http://www.gnu.org website for the version 3 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
24
#include <boost/test/unit_test.hpp>
25
26
#include <
diff_merge/merge_validators.h
>
27
28
29
using namespace
KICAD_DIFF
;
30
31
32
BOOST_AUTO_TEST_SUITE
( MergeValidators )
33
34
35
BOOST_AUTO_TEST_CASE
( RefdesUniquenessPassesOnUnique )
36
{
37
KIID::SeedGenerator
( 300 );
38
KIID
id1, id2, id3;
39
40
std::vector<REFDES_ENTRY> entries = {
41
{ wxS(
"R1"
),
KIID_PATH
( id1.
AsString
() ) },
42
{ wxS(
"R2"
),
KIID_PATH
( id2.
AsString
() ) },
43
{ wxS(
"C1"
),
KIID_PATH
( id3.
AsString
() ) },
44
};
45
46
VALIDATION_REPORT
r =
CheckRefdesUniqueness
( entries );
47
BOOST_CHECK( r.
Passed
() );
48
}
49
50
51
BOOST_AUTO_TEST_CASE
( RefdesUniquenessDetectsDuplicates )
52
{
53
KIID::SeedGenerator
( 301 );
54
KIID
id1, id2;
55
56
std::vector<REFDES_ENTRY> entries = {
57
{ wxS(
"R1"
),
KIID_PATH
( id1.
AsString
() ) },
58
{ wxS(
"R1"
),
KIID_PATH
( id2.
AsString
() ) },
59
};
60
61
VALIDATION_REPORT
r =
CheckRefdesUniqueness
( entries );
62
BOOST_REQUIRE_EQUAL( r.
failures
.size(), 1u );
63
BOOST_CHECK( r.
HasErrors
() );
64
BOOST_CHECK_EQUAL
( r.
failures
[0].validator.ToStdString(),
"RefdesUniqueness"
);
65
BOOST_CHECK_EQUAL
( r.
failures
[0].relatedItems.size(), 2u );
66
}
67
68
69
BOOST_AUTO_TEST_CASE
( RefdesUniquenessIgnoresEmptyAndPlaceholder )
70
{
71
KIID::SeedGenerator
( 302 );
72
KIID
id1, id2, id3;
73
74
std::vector<REFDES_ENTRY> entries = {
75
{ wxS(
""
),
KIID_PATH
( id1.
AsString
() ) },
76
{ wxS(
""
),
KIID_PATH
( id2.
AsString
() ) },
// both empty — OK
77
{ wxS(
"R?"
),
KIID_PATH
( id3.
AsString
() ) },
// placeholder — OK
78
};
79
80
VALIDATION_REPORT
r =
CheckRefdesUniqueness
( entries );
81
BOOST_CHECK( r.
Passed
() );
82
}
83
84
85
BOOST_AUTO_TEST_CASE
( ConnectivityFlagDetectsMissedRebuild )
86
{
87
BOOST_CHECK(
CheckConnectivityRebuildFlag
(
true
,
true
).Passed() );
88
BOOST_CHECK(
CheckConnectivityRebuildFlag
(
false
,
false
).Passed() );
89
BOOST_CHECK(
CheckConnectivityRebuildFlag
(
false
,
true
).Passed() );
// OK to over-rebuild
90
91
VALIDATION_REPORT
r =
CheckConnectivityRebuildFlag
(
true
,
false
);
92
BOOST_REQUIRE_EQUAL( r.
failures
.size(), 1u );
93
BOOST_CHECK( r.
HasErrors
() );
94
}
95
96
97
BOOST_AUTO_TEST_CASE
( SchemaVersionEqualPasses )
98
{
99
VALIDATION_REPORT
r =
CheckSchemaVersions
( 20240108, 20240108, 20240108 );
100
BOOST_CHECK( r.
Passed
() );
101
}
102
103
104
BOOST_AUTO_TEST_CASE
( SchemaVersionMinorMismatchWarns )
105
{
106
VALIDATION_REPORT
r =
CheckSchemaVersions
( 20240108, 20240115, 20240108 );
107
BOOST_REQUIRE_EQUAL( r.
failures
.size(), 1u );
108
BOOST_CHECK( !r.
HasErrors
() );
// WARNING only
109
}
110
111
112
BOOST_AUTO_TEST_CASE
( SchemaVersionMajorMismatchErrors )
113
{
114
VALIDATION_REPORT
r =
CheckSchemaVersions
( 20180101, 20240115, 20240108 );
115
BOOST_CHECK( r.
HasErrors
() );
116
}
117
118
119
BOOST_AUTO_TEST_CASE
( ReportMergePreservesFailures )
120
{
121
KIID::SeedGenerator
( 303 );
122
KIID
id1, id2;
123
124
VALIDATION_REPORT
a =
CheckRefdesUniqueness
( {
125
{ wxS(
"R1"
),
KIID_PATH
( id1.
AsString
() ) },
126
{ wxS(
"R1"
),
KIID_PATH
( id2.
AsString
() ) },
127
} );
128
129
VALIDATION_REPORT
b =
CheckConnectivityRebuildFlag
(
true
,
false
);
130
131
std::size_t expectedSize = a.
failures
.size() + b.failures.size();
132
a.
Merge
( std::move( b ) );
133
BOOST_CHECK_EQUAL
( a.
failures
.size(), expectedSize );
134
}
135
136
137
BOOST_AUTO_TEST_CASE
( ReportMergePreservesFailureContent )
138
{
139
// Size alone isn't enough — verify the actual validator names from
140
// both sides land in the merged report. The move-out side must also
141
// be empty (Merge takes by rvalue and clear()s in the impl).
142
KIID::SeedGenerator
( 304 );
143
KIID
id1, id2;
144
145
VALIDATION_REPORT
a =
CheckRefdesUniqueness
( {
146
{ wxS(
"R1"
),
KIID_PATH
( id1.
AsString
() ) },
147
{ wxS(
"R1"
),
KIID_PATH
( id2.
AsString
() ) },
148
} );
149
VALIDATION_REPORT
b =
CheckConnectivityRebuildFlag
(
true
,
false
);
150
151
a.
Merge
( std::move( b ) );
152
153
BOOST_CHECK( b.failures.empty() );
154
155
bool
sawRefdes =
false
;
156
bool
sawConnectivity =
false
;
157
158
for
(
const
VALIDATION_FAILURE
& f : a.
failures
)
159
{
160
if
( f.
validator
== wxS(
"RefdesUniqueness"
) )
161
sawRefdes =
true
;
162
if
( f.
validator
== wxS(
"ConnectivityRebuild"
) )
163
sawConnectivity =
true
;
164
}
165
166
BOOST_CHECK( sawRefdes );
167
BOOST_CHECK( sawConnectivity );
168
}
169
170
171
BOOST_AUTO_TEST_CASE
( HasErrorsMixedSeverityFindsError )
172
{
173
// HasErrors must short-circuit on a single ERROR even when WARNINGs
174
// also exist. A naive "all entries are errors" implementation would
175
// miss this case.
176
VALIDATION_REPORT
r;
177
178
VALIDATION_FAILURE
w;
179
w.
severity
=
RPT_SEVERITY_WARNING
;
180
w.
validator
= wxS(
"WarnOnly"
);
181
r.
failures
.push_back( w );
182
183
VALIDATION_FAILURE
e;
184
e.
severity
=
RPT_SEVERITY_ERROR
;
185
e.
validator
= wxS(
"RealError"
);
186
r.
failures
.push_back( e );
187
188
BOOST_CHECK( r.
HasErrors
() );
189
BOOST_CHECK( !r.
Passed
() );
190
}
191
192
193
BOOST_AUTO_TEST_CASE
( HasErrorsAllWarningsIsClean )
194
{
195
// Only-warning reports must read as "passed for the purposes of
196
// errors" — the caller can still surface warnings separately, but
197
// HasErrors is the gate that blocks the merge.
198
VALIDATION_REPORT
r;
199
200
VALIDATION_FAILURE
w1;
201
w1.
severity
=
RPT_SEVERITY_WARNING
;
202
r.
failures
.push_back( w1 );
203
204
VALIDATION_FAILURE
w2;
205
w2.
severity
=
RPT_SEVERITY_WARNING
;
206
r.
failures
.push_back( w2 );
207
208
BOOST_CHECK( !r.
HasErrors
() );
209
BOOST_CHECK( !r.
Passed
() );
// warnings still fail Passed()
210
}
211
212
213
BOOST_AUTO_TEST_CASE
( HasErrorsEmptyReportIsClean )
214
{
215
VALIDATION_REPORT
r;
216
BOOST_CHECK( !r.
HasErrors
() );
217
BOOST_CHECK( r.
Passed
() );
218
}
219
220
221
BOOST_AUTO_TEST_CASE
( SchemaVersionBoundaryDeltaJustBelowMajor )
222
{
223
// 48885 < MAJOR_EPOCH_DELTA (50000), so this should warn, not error.
224
// Without an explicit boundary test the threshold could drift silently.
225
VALIDATION_REPORT
r =
CheckSchemaVersions
( 20240115, 20290000, 20240115 );
226
BOOST_REQUIRE_EQUAL( r.
failures
.size(), 1u );
227
BOOST_CHECK( !r.
HasErrors
() );
228
}
229
230
231
BOOST_AUTO_TEST_CASE
( SchemaVersionBoundaryDeltaExactly50000 )
232
{
233
// Delta == 50000 exactly. The implementation uses `>=` so this is the
234
// first ERROR; a future refactor to `>` would silently downgrade this
235
// case to WARNING and let a borderline-stale schema land. Pin the
236
// inclusive comparison explicitly.
237
VALIDATION_REPORT
r =
CheckSchemaVersions
( 20200000, 20250000, 20200000 );
238
BOOST_REQUIRE
( !r.
failures
.empty() );
239
BOOST_CHECK( r.
HasErrors
() );
240
}
241
242
243
BOOST_AUTO_TEST_CASE
( RefdesUniquenessSingleEntryNeverFails )
244
{
245
// A single entry can't collide with itself — the < 2 guard prevents
246
// emitting a vacuous self-collision report.
247
KIID::SeedGenerator
( 305 );
248
KIID
id1;
249
std::vector<REFDES_ENTRY> entries = {
250
{ wxS(
"R1"
),
KIID_PATH
( id1.
AsString
() ) },
251
};
252
BOOST_CHECK(
CheckRefdesUniqueness
( entries ).Passed() );
253
}
254
255
256
BOOST_AUTO_TEST_CASE
( RefdesUniquenessThreeWayCollision )
257
{
258
// Triple collision should surface all three ids in relatedItems, not
259
// just the first pair detected.
260
KIID::SeedGenerator
( 306 );
261
KIID
id1, id2, id3;
262
std::vector<REFDES_ENTRY> entries = {
263
{ wxS(
"U1"
),
KIID_PATH
( id1.
AsString
() ) },
264
{ wxS(
"U1"
),
KIID_PATH
( id2.
AsString
() ) },
265
{ wxS(
"U1"
),
KIID_PATH
( id3.
AsString
() ) },
266
};
267
268
VALIDATION_REPORT
r =
CheckRefdesUniqueness
( entries );
269
BOOST_REQUIRE_EQUAL( r.
failures
.size(), 1u );
270
BOOST_CHECK_EQUAL
( r.
failures
[0].relatedItems.size(), 3u );
271
}
272
273
274
BOOST_AUTO_TEST_SUITE_END
()
KIID_PATH
Definition
kiid.h:165
KIID
Definition
kiid.h:44
KIID::SeedGenerator
static void SeedGenerator(unsigned int aSeed)
Re-initialize the UUID generator with a given seed (for testing or QA purposes)
Definition
kiid.cpp:331
KIID::AsString
wxString AsString() const
Definition
kiid.cpp:242
merge_validators.h
KICAD_DIFF
Definition
auto_resolution.cpp:34
KICAD_DIFF::CheckConnectivityRebuildFlag
VALIDATION_REPORT CheckConnectivityRebuildFlag(bool aPlanRequiredRebuild, bool aApplierReportedRebuild)
Information needed for the connectivity-rebuild side-effect check.
Definition
merge_validators.cpp:93
KICAD_DIFF::CheckSchemaVersions
VALIDATION_REPORT CheckSchemaVersions(int aAncestorVersion, int aOursVersion, int aTheirsVersion)
Schema-version compatibility check: every input to the merge must use a compatible serialization vers...
Definition
merge_validators.cpp:112
KICAD_DIFF::CheckRefdesUniqueness
VALIDATION_REPORT CheckRefdesUniqueness(const std::vector< REFDES_ENTRY > &aEntries)
Run refdes-uniqueness checks.
Definition
merge_validators.cpp:54
RPT_SEVERITY_WARNING
@ RPT_SEVERITY_WARNING
Definition
report_severity.h:34
RPT_SEVERITY_ERROR
@ RPT_SEVERITY_ERROR
Definition
report_severity.h:35
KICAD_DIFF::VALIDATION_FAILURE
Outcome of a single validator run.
Definition
merge_validators.h:44
KICAD_DIFF::VALIDATION_FAILURE::severity
SEVERITY severity
Definition
merge_validators.h:45
KICAD_DIFF::VALIDATION_FAILURE::validator
wxString validator
Definition
merge_validators.h:46
KICAD_DIFF::VALIDATION_REPORT
Definition
merge_validators.h:53
KICAD_DIFF::VALIDATION_REPORT::Merge
void Merge(VALIDATION_REPORT &&aOther)
Definition
merge_validators.cpp:43
KICAD_DIFF::VALIDATION_REPORT::failures
std::vector< VALIDATION_FAILURE > failures
Definition
merge_validators.h:54
KICAD_DIFF::VALIDATION_REPORT::Passed
bool Passed() const
Definition
merge_validators.h:56
KICAD_DIFF::VALIDATION_REPORT::HasErrors
bool HasErrors() const
Definition
merge_validators.cpp:33
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
Definition
test_api_enums.cpp:71
BOOST_AUTO_TEST_SUITE
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(RefdesUniquenessPassesOnUnique)
Definition
test_merge_validators.cpp:35
BOOST_CHECK_EQUAL
BOOST_CHECK_EQUAL(result, "25.4")
src
qa
tests
diff_merge
test_merge_validators.cpp
Generated on Thu Jun 18 2026 00:07:05 for KiCad PCB EDA Suite by
1.13.2