300 lines
11 KiB
C++
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()
|