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 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
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 { return m_type; }
87 void SetType( const wxString& aType ) override { m_type = aType; }
88
89 bool LibraryExists() const override { return true; }
90
91private:
92 LIB_TABLE_ROW* do_clone() const override
93 {
94 return new TEST_LIB_TABLE_ROW( *this );
95 }
96
97 wxString m_type;
98};
99
100
108class TEST_LIB_TABLE : public LIB_TABLE
109{
110public:
111 TEST_LIB_TABLE( LIB_TABLE* aFallback = nullptr ) :
112 LIB_TABLE( aFallback, std::make_unique<DUMMY_LIB_TABLE_IO>() )
113 {
114 }
115
116 PROJECT::ELEM ProjectElementType() override // from _ELEM
117 {
118 // Doesn't really matter what this is
120 }
121
122private:
123 void Parse( LIB_TABLE_LEXER* aLexer ) override
124 {
125 // Do nothing, we won't parse anything. Parse testing of actual data
126 // will happen in the relevant other tests.
127 }
128
129 void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override
130 {
131 // do nothing, we don't need to test this function
132 }
133};
134
135
139struct LIB_ROW_DEFINITION
140{
141 std::string m_nickname;
142 std::string m_uri;
143 std::string m_description;
144 bool m_enabled;
145};
146
147
148// clang-format off
152static const std::vector<LIB_ROW_DEFINITION> main_lib_defs = {
153 {
154 "Lib1",
155 "://lib/1",
156 "The first library",
157 true,
158 },
159 {
160 "Lib2",
161 "://lib/2",
162 "The second library",
163 true,
164 },
165 {
166 "Lib3",
167 "://lib/3",
168 "The third library",
169 false,
170 },
171};
172
173static const std::vector<LIB_ROW_DEFINITION> fallback_lib_defs = {
174 {
175 "FallbackLib1",
176 "://lib/fb1",
177 "The first fallback library",
178 true,
179 },
180 {
181 "FallbackLib2",
182 "://lib/fb2",
183 "The second fallback library",
184 false,
185 },
186};
187// clang-format on
188
189
193struct LIB_TABLE_TEST_FIXTURE
194{
195 LIB_TABLE_TEST_FIXTURE() : m_mainTableWithFb( &m_fallbackTable )
196 {
197 for( const auto& lib : main_lib_defs )
198 {
199 m_mainTableNoFb.InsertRow( makeRowFromDef( lib ).release() );
200 m_mainTableWithFb.InsertRow( makeRowFromDef( lib ).release() );
201 }
202
203 for( const auto& lib : fallback_lib_defs )
204 {
205 m_fallbackTable.InsertRow( makeRowFromDef( lib ).release() );
206 }
207 }
208
212 std::unique_ptr<TEST_LIB_TABLE_ROW> makeRowFromDef( const LIB_ROW_DEFINITION& aDef )
213 {
214 auto row = std::make_unique<TEST_LIB_TABLE_ROW>(
215 aDef.m_nickname, aDef.m_uri, "", aDef.m_description );
216
217 row->SetEnabled( aDef.m_enabled );
218
219 return row;
220 }
221
223 TEST_LIB_TABLE m_mainTableNoFb;
224
226 TEST_LIB_TABLE m_mainTableWithFb;
227
229 TEST_LIB_TABLE m_fallbackTable;
230};
231
232} // namespace
233
237BOOST_FIXTURE_TEST_SUITE( LibTable, LIB_TABLE_TEST_FIXTURE )
238
239
243{
244 TEST_LIB_TABLE table;
245
246 // Tables start out empty
247 BOOST_CHECK_EQUAL( table.GetCount(), 0 );
248 BOOST_CHECK_EQUAL( true, table.IsEmpty() );
249}
250
251
255BOOST_AUTO_TEST_CASE( EmptyWithFallback )
256{
257 // Fall back though another empty table to the real fallback
258 TEST_LIB_TABLE interposer_table( &m_fallbackTable );
259 TEST_LIB_TABLE table( &interposer_table );
260
261 // Table has no elements...
262 BOOST_CHECK_EQUAL( table.GetCount(), 0 );
263
264 // But it's not empty if we include the fallback
265 BOOST_CHECK_EQUAL( false, table.IsEmpty( true ) );
266}
267
268
273{
274 // writing a boot print is a bit of faff, so just use BOOST_CHECK_EQUAL and bools
275
276 // These two are identical, except the fallback (which isn't checked)
277 BOOST_CHECK_EQUAL( true, m_mainTableNoFb == m_mainTableWithFb );
278 BOOST_CHECK_EQUAL( false, m_mainTableNoFb != m_mainTableWithFb );
279
280 // Modify one of them
281 m_mainTableWithFb.At( 1 ).SetNickName( "NewNickname" );
282 BOOST_CHECK_EQUAL( false, m_mainTableNoFb == m_mainTableWithFb );
283 BOOST_CHECK_EQUAL( true, m_mainTableNoFb != m_mainTableWithFb );
284
285 // And check unequal (against empty)
286 TEST_LIB_TABLE empty_table;
287 BOOST_CHECK_EQUAL( false, m_mainTableNoFb == empty_table );
288 BOOST_CHECK_EQUAL( true, m_mainTableNoFb != empty_table );
289}
290
291
296{
297 // Filled with the right row count
298 BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 3 );
299
300 const auto& row0 = m_mainTableNoFb.At( 0 );
301 BOOST_CHECK_EQUAL( row0.GetNickName(), "Lib1" );
302
303 const auto& row1 = m_mainTableNoFb.At( 1 );
304 BOOST_CHECK_EQUAL( row1.GetNickName(), "Lib2" );
305
306 // disable, but still in the index
307 const auto& row2 = m_mainTableNoFb.At( 2 );
308 BOOST_CHECK_EQUAL( row2.GetNickName(), "Lib3" );
309
310 // check correct handling of out-of-bounds
311 // TODO: this doesn't work with boost::ptr_vector - that only asserts
312 // BOOST_CHECK_THROW( m_mainTableNoFb.At( 3 ), std::out_of_range );
313}
314
315
320{
321 BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib1" ) );
322
323 // disabled lib can be "not found" if checkEnabled is set
324 BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib3" ) );
325 BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "Lib3", true ) );
326
327 BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "NotPresent" ) );
328}
329
330
334BOOST_AUTO_TEST_CASE( Descriptions )
335{
336 BOOST_CHECK_EQUAL( "The first library", m_mainTableNoFb.GetDescription( "Lib1" ) );
337
338 // disabled lib works
339 BOOST_CHECK_EQUAL( "The third library", m_mainTableNoFb.GetDescription( "Lib3" ) );
340}
341
342
347{
348 BOOST_CHECK_EQUAL( "://lib/1", m_mainTableNoFb.GetFullURI( "Lib1" ) );
349
350 const LIB_TABLE_ROW* row = m_mainTableNoFb.FindRowByURI( "://lib/1" );
351
352 // should be found
353 BOOST_CHECK_NE( nullptr, row );
354
355 if( row )
356 {
357 BOOST_CHECK_EQUAL( "Lib1", row->GetNickName() );
358 }
359
360 row = m_mainTableNoFb.FindRowByURI( "this_uri_is_not_found" );
361
362 BOOST_CHECK_EQUAL( nullptr, row );
363}
364
365
370{
371 auto logical_libs = m_mainTableNoFb.GetLogicalLibs();
372
373 // The enabled library nicknames
374 const std::vector<wxString> exp_libs = {
375 "Lib1",
376 "Lib2",
377 };
378
379 BOOST_CHECK_EQUAL_COLLECTIONS(
380 logical_libs.begin(), logical_libs.end(), exp_libs.begin(), exp_libs.end() );
381}
382
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 bool LibraryExists() const =0
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_CHECK_EQUAL(ret, c.m_exp_result)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(Empty)
Declare the test suite.