KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_lib_table.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 (C) 2018-2019 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
34
35// Code under test
36#include <lib_table_base.h>
37
38namespace
39{
40
47class DUMMY_LIB_TABLE_IO : public LIB_TABLE_IO
48{
49public:
50 std::unique_ptr<LINE_READER> GetReader( const wxString& aURI ) const override
51 {
52 return std::make_unique<STRING_LINE_READER>( "", "DUMMY_LIB_TABLE_IO Data" );
53 }
54
55 bool CanSaveToUri( const wxString& aURI ) const override
56 {
57 // Always return true, it'll just write to a dummy string
58 return true;
59 }
60
61 bool UrisAreEquivalent( const wxString& aURI1, const wxString& aURI2 ) const override
62 {
63 return aURI1 == aURI2;
64 }
65
66 std::unique_ptr<OUTPUTFORMATTER> GetWriter( const wxString& aURI ) const override
67 {
68 return std::make_unique<STRING_FORMATTER>();
69 }
70};
71
72
77class TEST_LIB_TABLE_ROW : public LIB_TABLE_ROW
78{
79public:
80 TEST_LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
81 const wxString& aDescr )
82 : LIB_TABLE_ROW( aNick, aURI, aOptions, aDescr )
83 {
84 }
85
86 const wxString GetType() const override
87 {
88 return m_type;
89 }
90
91 void SetType( const wxString& aType ) override
92 {
93 m_type = aType;
94 }
95
96private:
97 LIB_TABLE_ROW* do_clone() const override
98 {
99 return new TEST_LIB_TABLE_ROW( *this );
100 }
101
102 wxString m_type;
103};
104
105
113class TEST_LIB_TABLE : public LIB_TABLE
114{
115public:
116 TEST_LIB_TABLE( LIB_TABLE* aFallback = nullptr ) :
117 LIB_TABLE( aFallback, std::make_unique<DUMMY_LIB_TABLE_IO>() )
118 {
119 }
120
121 PROJECT::ELEM ProjectElementType() override // from _ELEM
122 {
123 // Doesn't really matter what this is
125 }
126
127private:
128 void Parse( LIB_TABLE_LEXER* aLexer ) override
129 {
130 // Do nothing, we won't parse anything. Parse testing of actual data
131 // will happen in the relevant other tests.
132 }
133
134 void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override
135 {
136 // do nothing, we don't need to test this function
137 }
138};
139
140
144struct LIB_ROW_DEFINITION
145{
146 std::string m_nickname;
147 std::string m_uri;
148 std::string m_description;
149 bool m_enabled;
150};
151
152
153// clang-format off
157static const std::vector<LIB_ROW_DEFINITION> main_lib_defs = {
158 {
159 "Lib1",
160 "://lib/1",
161 "The first library",
162 true,
163 },
164 {
165 "Lib2",
166 "://lib/2",
167 "The second library",
168 true,
169 },
170 {
171 "Lib3",
172 "://lib/3",
173 "The third library",
174 false,
175 },
176};
177
178static const std::vector<LIB_ROW_DEFINITION> fallback_lib_defs = {
179 {
180 "FallbackLib1",
181 "://lib/fb1",
182 "The first fallback library",
183 true,
184 },
185 {
186 "FallbackLib2",
187 "://lib/fb2",
188 "The second fallback library",
189 false,
190 },
191};
192// clang-format on
193
194
198struct LIB_TABLE_TEST_FIXTURE
199{
200 LIB_TABLE_TEST_FIXTURE() : m_mainTableWithFb( &m_fallbackTable )
201 {
202 for( const auto& lib : main_lib_defs )
203 {
204 m_mainTableNoFb.InsertRow( makeRowFromDef( lib ).release() );
205 m_mainTableWithFb.InsertRow( makeRowFromDef( lib ).release() );
206 }
207
208 for( const auto& lib : fallback_lib_defs )
209 {
210 m_fallbackTable.InsertRow( makeRowFromDef( lib ).release() );
211 }
212 }
213
217 std::unique_ptr<TEST_LIB_TABLE_ROW> makeRowFromDef( const LIB_ROW_DEFINITION& aDef )
218 {
219 auto row = std::make_unique<TEST_LIB_TABLE_ROW>(
220 aDef.m_nickname, aDef.m_uri, "", aDef.m_description );
221
222 row->SetEnabled( aDef.m_enabled );
223
224 return row;
225 }
226
228 TEST_LIB_TABLE m_mainTableNoFb;
229
231 TEST_LIB_TABLE m_mainTableWithFb;
232
234 TEST_LIB_TABLE m_fallbackTable;
235};
236
237} // namespace
238
242BOOST_FIXTURE_TEST_SUITE( LibTable, LIB_TABLE_TEST_FIXTURE )
243
244
248{
249 TEST_LIB_TABLE table;
250
251 // Tables start out empty
252 BOOST_CHECK_EQUAL( table.GetCount(), 0 );
253 BOOST_CHECK_EQUAL( true, table.IsEmpty() );
254}
255
256
260BOOST_AUTO_TEST_CASE( EmptyWithFallback )
261{
262 // Fall back though another empty table to the real fallback
263 TEST_LIB_TABLE interposer_table( &m_fallbackTable );
264 TEST_LIB_TABLE table( &interposer_table );
265
266 // Table has no elements...
267 BOOST_CHECK_EQUAL( table.GetCount(), 0 );
268
269 // But it's not empty if we include the fallback
270 BOOST_CHECK_EQUAL( false, table.IsEmpty( true ) );
271}
272
273
278{
279 // writing a boot print is a bit of faff, so just use BOOST_CHECK_EQUAL and bools
280
281 // These two are identical, except the fallback (which isn't checked)
282 BOOST_CHECK_EQUAL( true, m_mainTableNoFb == m_mainTableWithFb );
283 BOOST_CHECK_EQUAL( false, m_mainTableNoFb != m_mainTableWithFb );
284
285 // Modify one of them
286 m_mainTableWithFb.At( 1 ).SetNickName( "NewNickname" );
287 BOOST_CHECK_EQUAL( false, m_mainTableNoFb == m_mainTableWithFb );
288 BOOST_CHECK_EQUAL( true, m_mainTableNoFb != m_mainTableWithFb );
289
290 // And check unequal (against empty)
291 TEST_LIB_TABLE empty_table;
292 BOOST_CHECK_EQUAL( false, m_mainTableNoFb == empty_table );
293 BOOST_CHECK_EQUAL( true, m_mainTableNoFb != empty_table );
294}
295
296
301{
302 // Filled with the right row count
303 BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 3 );
304
305 const auto& row0 = m_mainTableNoFb.At( 0 );
306 BOOST_CHECK_EQUAL( row0.GetNickName(), "Lib1" );
307
308 const auto& row1 = m_mainTableNoFb.At( 1 );
309 BOOST_CHECK_EQUAL( row1.GetNickName(), "Lib2" );
310
311 // disable, but still in the index
312 const auto& row2 = m_mainTableNoFb.At( 2 );
313 BOOST_CHECK_EQUAL( row2.GetNickName(), "Lib3" );
314
315 // check correct handling of out-of-bounds
316 // TODO: this doesn't work with boost::ptr_vector - that only asserts
317 // BOOST_CHECK_THROW( m_mainTableNoFb.At( 3 ), std::out_of_range );
318}
319
320
325{
326 BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib1" ) );
327
328 // disabled lib can be "not found" if checkEnabled is set
329 BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib3" ) );
330 BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "Lib3", true ) );
331
332 BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "NotPresent" ) );
333}
334
335
339BOOST_AUTO_TEST_CASE( Descriptions )
340{
341 BOOST_CHECK_EQUAL( "The first library", m_mainTableNoFb.GetDescription( "Lib1" ) );
342
343 // disabled lib works
344 BOOST_CHECK_EQUAL( "The third library", m_mainTableNoFb.GetDescription( "Lib3" ) );
345}
346
347
352{
353 BOOST_CHECK_EQUAL( "://lib/1", m_mainTableNoFb.GetFullURI( "Lib1" ) );
354
355 const LIB_TABLE_ROW* row = m_mainTableNoFb.FindRowByURI( "://lib/1" );
356
357 // should be found
358 BOOST_CHECK_NE( nullptr, row );
359
360 if( row )
361 {
362 BOOST_CHECK_EQUAL( "Lib1", row->GetNickName() );
363 }
364
365 row = m_mainTableNoFb.FindRowByURI( "this_uri_is_not_found" );
366
367 BOOST_CHECK_EQUAL( nullptr, row );
368}
369
370
375{
376 auto logical_libs = m_mainTableNoFb.GetLogicalLibs();
377
378 // The enabled library nicknames
379 const std::vector<wxString> exp_libs = {
380 "Lib1",
381 "Lib2",
382 };
383
384 BOOST_CHECK_EQUAL_COLLECTIONS(
385 logical_libs.begin(), logical_libs.end(), exp_libs.begin(), exp_libs.end() );
386}
387
LIB_TABLE_IO abstracts the file I/O operations for the library table loading and saving.
virtual std::unique_ptr< OUTPUTFORMATTER > GetWriter(const wxString &aURI) const =0
Save the given table to the given URI.
virtual std::unique_ptr< LINE_READER > GetReader(const wxString &aURI) const =0
Create a reader for the given URI.
virtual bool CanSaveToUri(const wxString &aURI) const =0
Check if the given URI is writable.
virtual bool UrisAreEquivalent(const wxString &aURI1, const wxString &aURI2) const =0
Compare two URIs for equivalence.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
virtual LIB_TABLE_ROW * do_clone() const =0
virtual const wxString GetType() const =0
Return the type of library represented by this row.
virtual void SetType(const wxString &aType)=0
Change the type of library represented by this row that must be implemented in the derived object to ...
const wxString & GetNickName() const
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const =0
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
virtual void Parse(LIB_TABLE_LEXER *aLexer)=0
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:322
virtual PROJECT::ELEM ProjectElementType()=0
ELEM
The set of #_ELEMs that a PROJECT can hold.
Definition: project.h:70
STL namespace.
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(Empty)
Declare the test suite.