kicad/qa/unittests/eeschema/test_sch_reference_list.cpp

300 lines
11 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <qa_utils/wx_utils/unit_test_utils.h>
#include "eeschema_test_utils.h"
#include <sch_reference_list.h>
#include <sch_sheet_path.h> // SCH_MULTI_UNIT_REFERENCE_MAP
struct REANNOTATED_REFERENCE
{
wxString m_KIID; ///< KIID of the symbol to reannotate
wxString m_OriginalRef; ///< Original Reference Designator (prior to reannotating)
wxString m_ExpectedRef; ///< Expected Reference Designator (after reannotating)
bool m_IncludeInReannotationList; ///< True if reference is "selected" for reannotation
};
class TEST_SCH_REFERENCE_LIST_FIXTURE : public KI_TEST::SCHEMATIC_TEST_FIXTURE
{
protected:
void loadTestCase( wxString aSchematicRelativePath, std::vector<REANNOTATED_REFERENCE> aRefs );
SCH_SYMBOL* getSymbolByKIID( wxString aKIID, SCH_SHEET_PATH* aSymbolPath );
SCH_REFERENCE_LIST getAdditionalRefs();
void checkAnnotation( std::vector<REANNOTATED_REFERENCE> aRefs );
SCH_REFERENCE_LIST m_refsToReannotate;
SCH_MULTI_UNIT_REFERENCE_MAP m_lockedRefs;
};
void TEST_SCH_REFERENCE_LIST_FIXTURE::loadTestCase( wxString aSchematicRelativePath,
std::vector<REANNOTATED_REFERENCE> aRefs )
{
m_refsToReannotate.Clear();
m_lockedRefs.clear();
LoadSchematic( aSchematicRelativePath );
// Create list of references to reannotate
for( REANNOTATED_REFERENCE ref : aRefs )
{
SCH_SHEET_PATH symbolPath;
SCH_SYMBOL* symbol = getSymbolByKIID( ref.m_KIID, &symbolPath );
//Make sure test case is built properly
BOOST_REQUIRE_NE( symbol, nullptr );
BOOST_REQUIRE_EQUAL( symbol->GetRef( &symbolPath, true ), ref.m_OriginalRef );
if( ref.m_IncludeInReannotationList )
{
symbolPath.AppendSymbol( m_refsToReannotate, symbol );
symbolPath.AppendMultiUnitSymbol( m_lockedRefs, symbol );
}
}
}
SCH_SYMBOL* TEST_SCH_REFERENCE_LIST_FIXTURE::getSymbolByKIID( wxString aKIID,
SCH_SHEET_PATH* aSymbolPath )
{
SCH_SHEET_LIST sheets = m_schematic.GetSheets();
KIID symKIID( aKIID );
SCH_ITEM* foundItem = sheets.GetItem( symKIID, aSymbolPath );
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( foundItem );
return symbol;
};
SCH_REFERENCE_LIST TEST_SCH_REFERENCE_LIST_FIXTURE::getAdditionalRefs()
{
// Build List of additional references to pass into Annotate()
SCH_REFERENCE_LIST allRefs, additionalRefs;
m_schematic.GetSheets().GetSymbols( allRefs );
for( size_t i = 0; i < allRefs.GetCount(); ++i )
{
if( !m_refsToReannotate.Contains( allRefs[i] ) )
additionalRefs.AddItem( allRefs[i] );
}
return additionalRefs;
}
void TEST_SCH_REFERENCE_LIST_FIXTURE::checkAnnotation( std::vector<REANNOTATED_REFERENCE> aRefs )
{
for( REANNOTATED_REFERENCE ref : aRefs )
{
SCH_SHEET_PATH symbolPath;
SCH_SYMBOL* symbol = getSymbolByKIID( ref.m_KIID, &symbolPath );
BOOST_CHECK_EQUAL( symbol->GetRef( &symbolPath, true ), ref.m_ExpectedRef );
}
}
BOOST_FIXTURE_TEST_SUITE( SchReferenceList, TEST_SCH_REFERENCE_LIST_FIXTURE )
struct REANNOTATION_CASE
{
std::string m_caseName;
wxString m_SchematicRelativePath;
int m_StartNumber;
std::vector<REANNOTATED_REFERENCE> m_ExpectedReannotations;
};
// Case 1: same value, same libref
// Case 2: same value, different libref
// Case 3: different value, same libref
// Case 4: Not annotated unit to reannotate
// Case 5: Duplicate references
static const std::vector<REANNOTATION_CASE> reannotationCases = {
{ "CASE 1. Rename only selected. All units selected",
"test_multiunit_reannotate",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 1. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
"test_multiunit_reannotate",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U2B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
} },
{ "CASE 1. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
"test_multiunit_reannotate",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 2. Rename only selected. All units selected",
"test_multiunit_reannotate_2",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 2. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
"test_multiunit_reannotate_2",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
} },
{ "CASE 2. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
"test_multiunit_reannotate_2",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 3. Rename only selected. All units selected",
"test_multiunit_reannotate_3",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 3. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
"test_multiunit_reannotate_3",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
} },
{ "CASE 3. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
"test_multiunit_reannotate_3",
1,
{
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
} },
{ "CASE 4 - Not previously annotated (does not get added to multi-unit locked group)",
"test_multiunit_reannotate_4",
1,
{
{ "549455c3-ab6e-454e-94b0-5ca9e521ae0b", "U?B", "U2B", true },
} },
{ "CASE 5 - Duplicate annotation. 1 selected",
"test_multiunit_reannotate_5",
10,
{
{ "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
{ "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U2B", false },
{ "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U2A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U11B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U2C", false },
} },
{ "CASE 5 - Duplicate annotation. 2 selected",
"test_multiunit_reannotate_5",
10,
{
{ "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
{ "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U11B", true },
{ "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U2A", false },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U12B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U2C", false },
} },
};
// @todo simplify or refactor this test case.
// Currently it simulates part of SCH_EDIT_FRAME::AnnotateSymbols
BOOST_AUTO_TEST_CASE( Reannotate )
{
for( const REANNOTATION_CASE& c : reannotationCases )
{
BOOST_TEST_INFO_SCOPE( c.m_caseName );
loadTestCase( c.m_SchematicRelativePath, c.m_ExpectedReannotations );
m_refsToReannotate.RemoveAnnotation();
m_refsToReannotate.SplitReferences();
m_refsToReannotate.Annotate( false, 0, c.m_StartNumber, m_lockedRefs, getAdditionalRefs() );
m_refsToReannotate.UpdateAnnotation();
checkAnnotation( c.m_ExpectedReannotations );
}
}
struct DUPLICATE_REANNOTATION_CASE
{
std::string m_caseName;
wxString m_SchematicRelativePath;
std::vector<REANNOTATED_REFERENCE> m_ExpectedReannotations;
};
static const std::vector<DUPLICATE_REANNOTATION_CASE> reannotateDuplicatesCases = {
{ "Reannotate Duplicates. Simple case",
"test_multiunit_reannotate_5",
{
{ "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
{ "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U2B", false },
{ "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
{ "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U3A", true },
{ "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U3B", true },
{ "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U3C", true },
} },
};
BOOST_AUTO_TEST_CASE( ReannotateDuplicates )
{
for( const DUPLICATE_REANNOTATION_CASE& c : reannotateDuplicatesCases )
{
BOOST_TEST_INFO_SCOPE( c.m_caseName );
loadTestCase( c.m_SchematicRelativePath, c.m_ExpectedReannotations );
m_refsToReannotate.ReannotateDuplicates( getAdditionalRefs() );
m_refsToReannotate.UpdateAnnotation();
checkAnnotation( c.m_ExpectedReannotations );
}
}
BOOST_AUTO_TEST_SUITE_END()