KiCad PCB EDA Suite
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 CHANGELOG.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 
38 
44 {
45 public:
46  TEST_LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
47  const wxString& aDescr )
48  : LIB_TABLE_ROW( aNick, aURI, aOptions, aDescr )
49  {
50  }
51 
52  const wxString GetType() const override
53  {
54  return m_type;
55  }
56 
57  void SetType( const wxString& aType ) override
58  {
59  m_type = aType;
60  }
61 
62 private:
63  LIB_TABLE_ROW* do_clone() const override
64  {
65  return new TEST_LIB_TABLE_ROW( *this );
66  }
67 
68  wxString m_type;
69 };
70 
71 
79 class TEST_LIB_TABLE : public LIB_TABLE
80 {
81 public:
82  TEST_LIB_TABLE( LIB_TABLE* aFallback = nullptr ) : LIB_TABLE( aFallback )
83  {
84  }
85 
86  KICAD_T Type() override // from _ELEM
87  {
88  // Doesn't really matter what this is
89  return FP_LIB_TABLE_T;
90  }
91 
92 private:
93  void Parse( LIB_TABLE_LEXER* aLexer ) override
94  {
95  // Do nothing, we won't parse anything. Parse testing of actual data
96  // will happen in the relevant other tests.
97  }
98 
99  void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override
100  {
101  // do nothing, we don't need to test this function
102  }
103 };
104 
105 
110 {
111  std::string m_nickname;
112  std::string m_uri;
113  std::string m_description;
114  bool m_enabled;
115 };
116 
117 
118 // clang-format off
122 static const std::vector<LIB_ROW_DEFINITION> main_lib_defs = {
123  {
124  "Lib1",
125  "://lib/1",
126  "The first library",
127  true,
128  },
129  {
130  "Lib2",
131  "://lib/2",
132  "The second library",
133  true,
134  },
135  {
136  "Lib3",
137  "://lib/3",
138  "The third library",
139  false,
140  },
141 };
142 
143 static const std::vector<LIB_ROW_DEFINITION> fallback_lib_defs = {
144  {
145  "FallbackLib1",
146  "://lib/fb1",
147  "The first fallback library",
148  true,
149  },
150  {
151  "FallbackLib2",
152  "://lib/fb2",
153  "The second fallback library",
154  false,
155  },
156 };
157 // clang-format on
158 
159 
164 {
166  {
167  for( const auto& lib : main_lib_defs )
168  {
169  m_mainTableNoFb.InsertRow( makeRowFromDef( lib ).release() );
170  m_mainTableWithFb.InsertRow( makeRowFromDef( lib ).release() );
171  }
172 
173  for( const auto& lib : fallback_lib_defs )
174  {
175  m_fallbackTable.InsertRow( makeRowFromDef( lib ).release() );
176  }
177  }
178 
182  std::unique_ptr<TEST_LIB_TABLE_ROW> makeRowFromDef( const LIB_ROW_DEFINITION& aDef )
183  {
184  auto row = std::make_unique<TEST_LIB_TABLE_ROW>(
185  aDef.m_nickname, aDef.m_uri, "", aDef.m_description );
186 
187  row->SetEnabled( aDef.m_enabled );
188 
189  return row;
190  }
191 
194 
197 
200 };
201 
205 BOOST_FIXTURE_TEST_SUITE( LibTable, LIB_TABLE_TEST_FIXTURE )
206 
207 
211 {
212  TEST_LIB_TABLE table;
213 
214  // Tables start out empty
215  BOOST_CHECK_EQUAL( table.GetCount(), 0 );
216  BOOST_CHECK_EQUAL( true, table.IsEmpty() );
217 }
218 
219 
223 BOOST_AUTO_TEST_CASE( EmptyWithFallback )
224 {
225  // Fall back though another empty table to the real fallback
226  TEST_LIB_TABLE interposer_table( &m_fallbackTable );
227  TEST_LIB_TABLE table( &interposer_table );
228 
229  // Table has no elements...
230  BOOST_CHECK_EQUAL( table.GetCount(), 0 );
231 
232  // But it's not empty if we include the fallback
233  BOOST_CHECK_EQUAL( false, table.IsEmpty( true ) );
234 }
235 
236 
241 {
242  m_mainTableNoFb.Clear();
243 
244  // Tables start out empty
245  BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 0 );
246  BOOST_CHECK_EQUAL( true, m_mainTableNoFb.IsEmpty() );
247 }
248 
249 
254 {
255  // writing a boot print is a bit of faff, so just use BOOST_CHECK_EQUAL and bools
256 
257  // These two are identical, except the fallback (which isn't checked)
258  BOOST_CHECK_EQUAL( true, m_mainTableNoFb == m_mainTableWithFb );
259  BOOST_CHECK_EQUAL( false, m_mainTableNoFb != m_mainTableWithFb );
260 
261  // Modify one of them
262  m_mainTableWithFb.At( 1 ).SetNickName( "NewNickname" );
263  BOOST_CHECK_EQUAL( false, m_mainTableNoFb == m_mainTableWithFb );
264  BOOST_CHECK_EQUAL( true, m_mainTableNoFb != m_mainTableWithFb );
265 
266  // And check unequal (against empty)
267  TEST_LIB_TABLE empty_table;
268  BOOST_CHECK_EQUAL( false, m_mainTableNoFb == empty_table );
269  BOOST_CHECK_EQUAL( true, m_mainTableNoFb != empty_table );
270 }
271 
272 
277 {
278  // Filled with the right row count
279  BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 3 );
280 
281  const auto& row0 = m_mainTableNoFb.At( 0 );
282  BOOST_CHECK_EQUAL( row0.GetNickName(), "Lib1" );
283 
284  const auto& row1 = m_mainTableNoFb.At( 1 );
285  BOOST_CHECK_EQUAL( row1.GetNickName(), "Lib2" );
286 
287  // disable, but still in the index
288  const auto& row2 = m_mainTableNoFb.At( 2 );
289  BOOST_CHECK_EQUAL( row2.GetNickName(), "Lib3" );
290 
291  // check correct handling of out-of-bounds
292  // TODO: this doesn't work with boost::ptr_vector - that only asserts
293  // BOOST_CHECK_THROW( m_mainTableNoFb.At( 3 ), std::out_of_range );
294 }
295 
296 
300 BOOST_AUTO_TEST_CASE( HasLibrary )
301 {
302  BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib1" ) );
303 
304  // disabled lib can be "not found" if checkEnabled is set
305  BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib3" ) );
306  BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "Lib3", true ) );
307 
308  BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "NotPresent" ) );
309 }
310 
311 
315 BOOST_AUTO_TEST_CASE( Descriptions )
316 {
317  BOOST_CHECK_EQUAL( "The first library", m_mainTableNoFb.GetDescription( "Lib1" ) );
318 
319  // disabled lib works
320  BOOST_CHECK_EQUAL( "The third library", m_mainTableNoFb.GetDescription( "Lib3" ) );
321 }
322 
323 
328 {
329  BOOST_CHECK_EQUAL( "://lib/1", m_mainTableNoFb.GetFullURI( "Lib1" ) );
330 
331  const LIB_TABLE_ROW* row = m_mainTableNoFb.FindRowByURI( "://lib/1" );
332 
333  // should be found
334  BOOST_CHECK_NE( nullptr, row );
335 
336  if( row )
337  {
338  BOOST_CHECK_EQUAL( "Lib1", row->GetNickName() );
339  }
340 
341  row = m_mainTableNoFb.FindRowByURI( "this_uri_is_not_found" );
342 
343  BOOST_CHECK_EQUAL( nullptr, row );
344 }
345 
346 
350 BOOST_AUTO_TEST_CASE( LogicalLibs )
351 {
352  auto logical_libs = m_mainTableNoFb.GetLogicalLibs();
353 
354  // The enabled library nicknames
355  const std::vector<wxString> exp_libs = {
356  "Lib1",
357  "Lib2",
358  };
359 
360  BOOST_CHECK_EQUAL_COLLECTIONS(
361  logical_libs.begin(), logical_libs.end(), exp_libs.begin(), exp_libs.end() );
362 }
363 
364 BOOST_AUTO_TEST_SUITE_END()
Simple structure to contain data to set up a single TEST_LIB_TABLE_ROW.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indention level of aIndentLevel.
unsigned GetCount() const
Get the number of rows contained in the table.
LIB_TABLE_ROW * do_clone() const override
OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a convenient ...
Definition: richio.h:327
std::unique_ptr< TEST_LIB_TABLE_ROW > makeRowFromDef(const LIB_ROW_DEFINITION &aDef)
Helper to construct a new TEST_LIB_TABLE_ROW from a definition struct.
TEST_LIB_TABLE m_mainTableNoFb
Table with some enabled and disabled libs, no fallback provided.
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
const wxString GetType() const override
Return the type of library represented by this row.
BOOST_AUTO_TEST_CASE(Empty)
Declare the test suite.
TEST_LIB_TABLE(LIB_TABLE *aFallback=nullptr)
TEST_LIB_TABLE m_mainTableWithFb
Identical to m_mainTableNoFb, but with a fallback.
TEST_LIB_TABLE m_fallbackTable
The table that m_mainTableWithFb falls back to.
KICAD_T Type() override
TEST_LIB_TABLE_ROW(const wxString &aNick, const wxString &aURI, const wxString &aOptions, const wxString &aDescr)
A concrete implementation of LIB_TABLE_ROW that implements the minimum interface.
void SetType(const wxString &aType) override
Change the type of library represented by this row that must be implemented in the derived object to ...
static const std::vector< LIB_ROW_DEFINITION > fallback_lib_defs
static const std::vector< LIB_ROW_DEFINITION > main_lib_defs
Set-up data for the re-used library row definitions.
std::string m_description
A concrete implementation of LIB_TABLE that implements the minimum interface for testing.
Reusable test fixture with some basic pre-filled tables.
bool IsEmpty(bool aIncludeFallback=true)
Return true if the table is empty.
void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.