mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
312 lines
9.6 KiB
C++
312 lines
9.6 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* 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/>.
|
|
*/
|
|
|
|
#define BOOST_TEST_NO_MAIN
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include <tool/grid_helper.h>
|
|
|
|
void TEST_CLEAR_ANCHORS( GRID_HELPER& helper )
|
|
{
|
|
helper.clearAnchors();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE( GridHelperTest )
|
|
|
|
BOOST_AUTO_TEST_CASE( DefaultConstructor )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Test default state
|
|
BOOST_CHECK( helper.GetSnap() );
|
|
BOOST_CHECK( helper.GetUseGrid() );
|
|
|
|
// Test that manual setters work
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 50, 50 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
VECTOR2I grid = helper.GetGrid();
|
|
BOOST_CHECK_EQUAL( grid.x, 100 );
|
|
BOOST_CHECK_EQUAL( grid.y, 100 );
|
|
|
|
VECTOR2I origin = helper.GetOrigin();
|
|
BOOST_CHECK_EQUAL( origin.x, 50 );
|
|
BOOST_CHECK_EQUAL( origin.y, 50 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( AlignBasic )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
// Test basic alignment - should round to nearest grid point
|
|
VECTOR2I aligned = helper.Align( VECTOR2I( 149, 251 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
|
|
// Test exact grid points
|
|
aligned = helper.Align( VECTOR2I( 200, 300 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 200 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
|
|
// Test negative coordinates
|
|
aligned = helper.Align( VECTOR2I( -149, -251 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, -100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, -300 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( AlignGridWithCustomGrid )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 50, 50 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
VECTOR2I aligned = helper.AlignGrid( VECTOR2I( 26, 74 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 50 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 50 );
|
|
|
|
// Test AlignGrid with specific grid parameter
|
|
aligned = helper.AlignGrid( VECTOR2I( 26, 74 ), VECTOR2D( 25, 25 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 25 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 75 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( AlignWithOriginOffset )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 25, 25 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
// When grid has an origin offset, alignment should still work from (0,0) reference
|
|
// AlignGrid doesn't use origin, just pure grid alignment
|
|
VECTOR2I aligned = helper.AlignGrid( VECTOR2I( 149, 251 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( AlignWithAuxiliaryAxes )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
// Set auxiliary axis at (75, 75)
|
|
helper.SetAuxAxes( true, VECTOR2I( 75, 75 ) );
|
|
|
|
// Point closer to aux axis than grid should snap to aux axis
|
|
VECTOR2I aligned = helper.Align( VECTOR2I( 80, 80 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 75 ); // Closer to aux axis X
|
|
BOOST_CHECK_EQUAL( aligned.y, 75 ); // Closer to aux axis Y
|
|
|
|
// Point closer to grid than aux axis should snap to grid
|
|
aligned = helper.Align( VECTOR2I( 95, 95 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 ); // Closer to grid
|
|
BOOST_CHECK_EQUAL( aligned.y, 100 ); // Closer to grid
|
|
|
|
// Disable aux axes
|
|
helper.SetAuxAxes( false );
|
|
aligned = helper.Align( VECTOR2I( 80, 80 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 ); // Should snap to grid only
|
|
BOOST_CHECK_EQUAL( aligned.y, 100 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( GridSnappingDisabled )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( false ); // Disable grid snapping
|
|
|
|
// When grid snapping is disabled, Align should return original point
|
|
VECTOR2I original( 149, 251 );
|
|
VECTOR2I aligned = helper.Align( original );
|
|
BOOST_CHECK_EQUAL( aligned.x, original.x );
|
|
BOOST_CHECK_EQUAL( aligned.y, original.y );
|
|
|
|
// AlignGrid should still work regardless of grid snapping setting
|
|
aligned = helper.AlignGrid( original );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( UseGridDisabled )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
helper.SetUseGrid( false ); // Disable grid usage
|
|
|
|
// When grid usage is disabled, Align should return original point
|
|
VECTOR2I original( 149, 251 );
|
|
VECTOR2I aligned = helper.Align( original );
|
|
BOOST_CHECK_EQUAL( aligned.x, original.x );
|
|
BOOST_CHECK_EQUAL( aligned.y, original.y );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( AsymmetricGrid )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 25, 75 ) ); // Different X and Y grid sizes
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
VECTOR2I aligned = helper.Align( VECTOR2I( 30, 100 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 25 ); // Nearest 25-unit boundary
|
|
BOOST_CHECK_EQUAL( aligned.y, 75 ); // Nearest 75-unit boundary
|
|
|
|
aligned = helper.Align( VECTOR2I( 40, 120 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 50 ); // Next 25-unit boundary
|
|
BOOST_CHECK_EQUAL( aligned.y, 150 ); // Next 75-unit boundary
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( SnapFlags )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Test snap flag getters/setters
|
|
BOOST_CHECK( helper.GetSnap() ); // Default should be true
|
|
|
|
helper.SetSnap( false );
|
|
BOOST_CHECK( !helper.GetSnap() );
|
|
|
|
helper.SetSnap( true );
|
|
BOOST_CHECK( helper.GetSnap() );
|
|
|
|
// Test grid usage flag
|
|
BOOST_CHECK( helper.GetUseGrid() ); // Default should be true
|
|
|
|
helper.SetUseGrid( false );
|
|
BOOST_CHECK( !helper.GetUseGrid() );
|
|
|
|
helper.SetUseGrid( true );
|
|
BOOST_CHECK( helper.GetUseGrid() );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( MaskOperations )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Test mask operations
|
|
helper.SetMask( GRID_HELPER::CORNER | GRID_HELPER::OUTLINE );
|
|
helper.SetMaskFlag( GRID_HELPER::SNAPPABLE );
|
|
helper.ClearMaskFlag( GRID_HELPER::CORNER );
|
|
|
|
// These don't have getters, so we can't verify the mask state directly
|
|
// but we can verify the methods don't crash
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( SkipPoint )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Test skip point operations
|
|
helper.SetSkipPoint( VECTOR2I( 100, 100 ) );
|
|
helper.ClearSkipPoint();
|
|
|
|
// These methods should not crash
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( GridTypeAlignment )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
// Test alignment with specific grid type
|
|
VECTOR2I aligned = helper.Align( VECTOR2I( 149, 251 ), GRID_CURRENT );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
|
|
aligned = helper.AlignGrid( VECTOR2I( 149, 251 ), GRID_CURRENT );
|
|
BOOST_CHECK_EQUAL( aligned.x, 100 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 300 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( EdgeCases )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetGridSize( VECTOR2D( 1, 1 ) ); // Very small grid
|
|
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
|
helper.SetGridSnapping( true );
|
|
|
|
// Test with very small grid
|
|
VECTOR2I aligned = helper.Align( VECTOR2I( 5, 5 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 5 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 5 );
|
|
|
|
// Test with zero point
|
|
aligned = helper.Align( VECTOR2I( 0, 0 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 0 );
|
|
BOOST_CHECK_EQUAL( aligned.y, 0 );
|
|
|
|
// Test with large grid
|
|
helper.SetGridSize( VECTOR2D( 10000, 10000 ) );
|
|
aligned = helper.Align( VECTOR2I( 3000, 7000 ) );
|
|
BOOST_CHECK_EQUAL( aligned.x, 0 ); // Closer to 0 than 10000
|
|
BOOST_CHECK_EQUAL( aligned.y, 10000 ); // Closer to 10000 than 0
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( GetGridSize )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Test GetGridSize with different grid types
|
|
helper.SetGridSize( VECTOR2D( 50, 75 ) );
|
|
|
|
VECTOR2D gridSize = helper.GetGridSize( GRID_CURRENT );
|
|
BOOST_CHECK_EQUAL( gridSize.x, 50 );
|
|
BOOST_CHECK_EQUAL( gridSize.y, 75 );
|
|
|
|
// Other grid types should return the same in the base implementation
|
|
gridSize = helper.GetGridSize( GRID_CONNECTABLE );
|
|
BOOST_CHECK_EQUAL( gridSize.x, 50 );
|
|
BOOST_CHECK_EQUAL( gridSize.y, 75 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( VisibleGrid )
|
|
{
|
|
GRID_HELPER helper;
|
|
helper.SetVisibleGridSize( VECTOR2D( 25, 35 ) );
|
|
|
|
VECTOR2D visibleGrid = helper.GetVisibleGrid();
|
|
BOOST_CHECK_EQUAL( visibleGrid.x, 25 );
|
|
BOOST_CHECK_EQUAL( visibleGrid.y, 35 );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( SnapPointManagement )
|
|
{
|
|
GRID_HELPER helper;
|
|
|
|
// Initially should have no snapped point
|
|
auto snappedPoint = helper.GetSnappedPoint();
|
|
BOOST_CHECK( !snappedPoint.has_value() );
|
|
|
|
// After clearing anchors, still no snapped point
|
|
TEST_CLEAR_ANCHORS( helper );
|
|
snappedPoint = helper.GetSnappedPoint();
|
|
BOOST_CHECK( !snappedPoint.has_value() );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END() |