mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Refactor grid_helper to allow testing
Make view and tool manager optional so that we can implement QA on the actual snapping
This commit is contained in:
parent
fb6bc9ca11
commit
29eee9f126
@ -37,8 +37,8 @@
|
||||
#include <settings/app_settings.h>
|
||||
|
||||
|
||||
GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
m_toolMgr( aToolMgr ), m_snapManager( m_constructionGeomPreview )
|
||||
GRID_HELPER::GRID_HELPER() :
|
||||
m_toolMgr( nullptr ), m_snapManager( m_constructionGeomPreview )
|
||||
{
|
||||
m_maskTypes = ALL;
|
||||
m_enableSnap = true;
|
||||
@ -46,6 +46,21 @@ GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
m_enableGrid = true;
|
||||
m_snapItem = std::nullopt;
|
||||
|
||||
m_manualGrid = VECTOR2D( 1, 1 );
|
||||
m_manualVisibleGrid = VECTOR2D( 1, 1 );
|
||||
m_manualOrigin = VECTOR2I( 0, 0 );
|
||||
m_manualGridSnapping = true;
|
||||
}
|
||||
|
||||
|
||||
GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
GRID_HELPER()
|
||||
{
|
||||
m_toolMgr = aToolMgr;
|
||||
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
KIGFX::RENDER_SETTINGS* settings = view->GetPainter()->GetSettings();
|
||||
|
||||
@ -72,11 +87,20 @@ GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
|
||||
m_toolMgr->GetToolHolder()->RefreshCanvas();
|
||||
} );
|
||||
|
||||
// Initialise manual values from view for compatibility
|
||||
m_manualGrid = view->GetGAL()->GetGridSize();
|
||||
m_manualVisibleGrid = view->GetGAL()->GetVisibleGridSize();
|
||||
m_manualOrigin = VECTOR2I( view->GetGAL()->GetGridOrigin() );
|
||||
m_manualGridSnapping = view->GetGAL()->GetGridSnapping();
|
||||
}
|
||||
|
||||
|
||||
GRID_HELPER::~GRID_HELPER()
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW& view = *m_toolMgr->GetView();
|
||||
view.Remove( &m_constructionGeomPreview );
|
||||
|
||||
@ -89,6 +113,9 @@ KIGFX::ANCHOR_DEBUG* GRID_HELPER::enableAndGetAnchorDebug()
|
||||
{
|
||||
static bool permitted = ADVANCED_CFG::GetCfg().m_EnableSnapAnchorsDebug;
|
||||
|
||||
if( !m_toolMgr )
|
||||
return nullptr;
|
||||
|
||||
if( permitted && !m_anchorDebug )
|
||||
{
|
||||
KIGFX::VIEW& view = *m_toolMgr->GetView();
|
||||
@ -103,12 +130,16 @@ KIGFX::ANCHOR_DEBUG* GRID_HELPER::enableAndGetAnchorDebug()
|
||||
|
||||
void GRID_HELPER::showConstructionGeometry( bool aShow )
|
||||
{
|
||||
m_toolMgr->GetView()->SetVisible( &m_constructionGeomPreview, aShow );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_constructionGeomPreview, aShow );
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::updateSnapPoint( const TYPED_POINT2I& aPoint )
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
m_viewSnapPoint.SetPosition( aPoint.m_point );
|
||||
m_viewSnapPoint.SetSnapTypes( aPoint.m_types );
|
||||
|
||||
@ -121,23 +152,26 @@ void GRID_HELPER::updateSnapPoint( const TYPED_POINT2I& aPoint )
|
||||
|
||||
VECTOR2I GRID_HELPER::GetGrid() const
|
||||
{
|
||||
VECTOR2D size = m_toolMgr->GetView()->GetGAL()->GetGridSize();
|
||||
|
||||
VECTOR2D size = m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSize() : m_manualGrid;
|
||||
return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D GRID_HELPER::GetVisibleGrid() const
|
||||
{
|
||||
return m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize();
|
||||
return m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize() : m_manualVisibleGrid;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::GetOrigin() const
|
||||
{
|
||||
VECTOR2D origin = m_toolMgr->GetView()->GetGAL()->GetGridOrigin();
|
||||
if( m_toolMgr )
|
||||
{
|
||||
VECTOR2D origin = m_toolMgr->GetView()->GetGAL()->GetGridOrigin();
|
||||
return VECTOR2I( origin );
|
||||
}
|
||||
|
||||
return VECTOR2I( origin );
|
||||
return m_manualOrigin;
|
||||
}
|
||||
|
||||
|
||||
@ -160,7 +194,7 @@ GRID_HELPER_GRIDS GRID_HELPER::GetSelectionGrid( const SELECTION& aSelection ) c
|
||||
|
||||
VECTOR2D GRID_HELPER::GetGridSize( GRID_HELPER_GRIDS aGrid ) const
|
||||
{
|
||||
return m_toolMgr->GetView()->GetGAL()->GetGridSize();
|
||||
return m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSize() : m_manualGrid;
|
||||
}
|
||||
|
||||
|
||||
@ -170,12 +204,14 @@ void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin )
|
||||
{
|
||||
m_auxAxis = aOrigin;
|
||||
m_viewAxis.SetPosition( aOrigin );
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, true );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_auxAxis = std::optional<VECTOR2I>();
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, false );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, false );
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +263,8 @@ VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) con
|
||||
|
||||
bool GRID_HELPER::canUseGrid() const
|
||||
{
|
||||
return m_enableGrid && m_toolMgr->GetView()->GetGAL()->GetGridSnapping();
|
||||
return m_enableGrid && ( m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSnapping()
|
||||
: m_manualGridSnapping );
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,10 +39,18 @@
|
||||
#include <view/view.h>
|
||||
#include "ee_grid_helper.h"
|
||||
|
||||
EE_GRID_HELPER::EE_GRID_HELPER() :
|
||||
GRID_HELPER()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EE_GRID_HELPER::EE_GRID_HELPER( TOOL_MANAGER* aToolMgr ) :
|
||||
GRID_HELPER( aToolMgr, LAYER_SCHEMATIC_ANCHOR )
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
|
||||
m_viewAxis.SetSize( 20000 );
|
||||
@ -62,6 +70,9 @@ EE_GRID_HELPER::EE_GRID_HELPER( TOOL_MANAGER* aToolMgr ) :
|
||||
|
||||
EE_GRID_HELPER::~EE_GRID_HELPER()
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
|
||||
view->Remove( &m_viewAxis );
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <math/vector2d.h>
|
||||
#include <origin_viewitem.h>
|
||||
#include <tool/grid_helper.h>
|
||||
#include <sch_selection.h>
|
||||
#include "sch_selection.h"
|
||||
|
||||
class SCH_ITEM;
|
||||
|
||||
@ -38,6 +38,7 @@ class EE_GRID_HELPER : public GRID_HELPER
|
||||
{
|
||||
public:
|
||||
|
||||
EE_GRID_HELPER();
|
||||
EE_GRID_HELPER( TOOL_MANAGER* aToolMgr );
|
||||
~EE_GRID_HELPER() override;
|
||||
|
||||
|
@ -32,10 +32,11 @@
|
||||
#include <preview_items/snap_indicator.h>
|
||||
#include <preview_items/construction_geom.h>
|
||||
#include <tool/construction_manager.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/selection.h>
|
||||
#include <origin_viewitem.h>
|
||||
|
||||
class TOOL_MANAGER; // Forward declaration to avoid hard dependency in tests
|
||||
|
||||
class EDA_ITEM;
|
||||
|
||||
enum GRID_HELPER_GRIDS : int
|
||||
@ -52,7 +53,9 @@ enum GRID_HELPER_GRIDS : int
|
||||
|
||||
class GRID_HELPER
|
||||
{
|
||||
friend void TEST_CLEAR_ANCHORS( GRID_HELPER& helper );
|
||||
public:
|
||||
GRID_HELPER();
|
||||
GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer );
|
||||
virtual ~GRID_HELPER();
|
||||
|
||||
@ -60,6 +63,12 @@ public:
|
||||
VECTOR2D GetVisibleGrid() const;
|
||||
VECTOR2I GetOrigin() const;
|
||||
|
||||
// Manual setters used when no TOOL_MANAGER/View is available (e.g. in tests)
|
||||
void SetGridSize( const VECTOR2D& aGrid ) { m_manualGrid = aGrid; }
|
||||
void SetVisibleGridSize( const VECTOR2D& aGrid ) { m_manualVisibleGrid = aGrid; }
|
||||
void SetOrigin( const VECTOR2I& aOrigin ) { m_manualOrigin = aOrigin; }
|
||||
void SetGridSnapping( bool aEnable ) { m_manualGridSnapping = aEnable; }
|
||||
|
||||
void SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin = VECTOR2I( 0, 0 ) );
|
||||
|
||||
virtual VECTOR2I Align( const VECTOR2I& aPoint, GRID_HELPER_GRIDS aGrid ) const
|
||||
@ -230,6 +239,12 @@ protected:
|
||||
KIGFX::SNAP_INDICATOR m_viewSnapPoint;
|
||||
KIGFX::ORIGIN_VIEWITEM m_viewAxis;
|
||||
|
||||
// Manual grid parameters used when no TOOL_MANAGER is provided
|
||||
VECTOR2D m_manualGrid;
|
||||
VECTOR2D m_manualVisibleGrid;
|
||||
VECTOR2I m_manualOrigin;
|
||||
bool m_manualGridSnapping;
|
||||
|
||||
private:
|
||||
/// Show construction geometry (if any) on the canvas.
|
||||
KIGFX::CONSTRUCTION_GEOM m_constructionGeomPreview;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <pcb_group.h>
|
||||
|
||||
#include <tool/edit_points.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/drawing_tool.h>
|
||||
#include <tools/generator_tool.h>
|
||||
#include <tools/pcb_picker_tool.h>
|
||||
|
@ -29,6 +29,7 @@ using namespace std::placeholders;
|
||||
#include <pcbnew_settings.h>
|
||||
#include <view/view_controls.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_grid_helper.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <pcb_generator.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <spread_footprints.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/edit_tool.h>
|
||||
|
@ -142,10 +142,20 @@ std::optional<int64_t> FindSquareDistanceToItem( const BOARD_ITEM& item, const V
|
||||
|
||||
} // namespace
|
||||
|
||||
PCB_GRID_HELPER::PCB_GRID_HELPER() :
|
||||
GRID_HELPER(),
|
||||
m_magneticSettings( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PCB_GRID_HELPER::PCB_GRID_HELPER( TOOL_MANAGER* aToolMgr, MAGNETIC_SETTINGS* aMagneticSettings ) :
|
||||
GRID_HELPER( aToolMgr, LAYER_ANCHOR ),
|
||||
m_magneticSettings( aMagneticSettings )
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
KIGFX::RENDER_SETTINGS* settings = view->GetPainter()->GetSettings();
|
||||
KIGFX::COLOR4D auxItemsColor = settings->GetLayerColor( LAYER_AUX_ITEMS );
|
||||
@ -168,6 +178,9 @@ PCB_GRID_HELPER::PCB_GRID_HELPER( TOOL_MANAGER* aToolMgr, MAGNETIC_SETTINGS* aMa
|
||||
|
||||
PCB_GRID_HELPER::~PCB_GRID_HELPER()
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
|
||||
view->Remove( &m_viewAxis );
|
||||
|
@ -43,8 +43,10 @@ struct PCB_SELECTION_FILTER_OPTIONS;
|
||||
|
||||
class PCB_GRID_HELPER : public GRID_HELPER, public BOARD_LISTENER
|
||||
{
|
||||
friend class PCBGridHelperTestFixture;
|
||||
public:
|
||||
|
||||
PCB_GRID_HELPER();
|
||||
PCB_GRID_HELPER( TOOL_MANAGER* aToolMgr, MAGNETIC_SETTINGS* aMagneticSettings );
|
||||
~PCB_GRID_HELPER() override;
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <status_popup.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/zone_filler_tool.h>
|
||||
#include <view/view_controls.h>
|
||||
|
@ -57,6 +57,7 @@ set( QA_COMMON_SRCS
|
||||
test_property_holder.cpp
|
||||
test_reporting.cpp
|
||||
test_refdes_utils.cpp
|
||||
test_grid_helper.cpp
|
||||
test_richio.cpp
|
||||
test_text_attributes.cpp
|
||||
test_title_block.cpp
|
||||
|
312
qa/tests/common/test_grid_helper.cpp
Normal file
312
qa/tests/common/test_grid_helper.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* 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()
|
@ -71,6 +71,7 @@ set( QA_EESCHEMA_SRCS
|
||||
test_junction_helpers.cpp
|
||||
test_bus_entry_concurrency.cpp
|
||||
test_lib_part.cpp
|
||||
test_ee_grid_helper.cpp
|
||||
test_netlist_exporter_kicad.cpp
|
||||
test_ee_item.cpp
|
||||
test_incremental_netlister.cpp
|
||||
|
47
qa/tests/eeschema/test_ee_grid_helper.cpp
Normal file
47
qa/tests/eeschema/test_ee_grid_helper.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 <tools/ee_grid_helper.h>
|
||||
#include <sch_text.h>
|
||||
#include <sch_line.h>
|
||||
#include <sch_shape.h>
|
||||
#include <sch_junction.h>
|
||||
#include <layer_ids.h>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( EEGridHelperTest )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ItemGridClassification )
|
||||
{
|
||||
EE_GRID_HELPER helper;
|
||||
|
||||
SCH_TEXT text;
|
||||
BOOST_CHECK_EQUAL( helper.GetItemGrid( &text ), GRID_TEXT );
|
||||
|
||||
SCH_LINE wire( VECTOR2I( 0, 0 ), LAYER_WIRE );
|
||||
BOOST_CHECK_EQUAL( helper.GetItemGrid( &wire ), GRID_WIRES );
|
||||
|
||||
SCH_LINE graphic( VECTOR2I( 0, 0 ), LAYER_NOTES );
|
||||
BOOST_CHECK_EQUAL( helper.GetItemGrid( &graphic ), GRID_GRAPHICS );
|
||||
|
||||
SCH_JUNCTION junc;
|
||||
BOOST_CHECK_EQUAL( helper.GetItemGrid( &junc ), GRID_WIRES );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -47,6 +47,7 @@ set( QA_PCBNEW_SRCS
|
||||
test_prettifier.cpp
|
||||
test_libeval_compiler.cpp
|
||||
test_reference_image_load.cpp
|
||||
test_pcb_grid_helper.cpp
|
||||
test_save_load.cpp
|
||||
test_tracks_cleaner.cpp
|
||||
test_triangulation.cpp
|
||||
|
410
qa/tests/pcbnew/test_pcb_grid_helper.cpp
Normal file
410
qa/tests/pcbnew/test_pcb_grid_helper.cpp
Normal file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
* 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 <tools/pcb_grid_helper.h>
|
||||
#include <geometry/seg.h>
|
||||
#include <geometry/shape_arc.h>
|
||||
#include <footprint.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_track.h>
|
||||
#include <zone.h>
|
||||
#include <pcb_text.h>
|
||||
|
||||
// Mock EDA_ITEM class for testing GetItemGrid
|
||||
class MOCK_BOARD_ITEM : public BOARD_ITEM
|
||||
{
|
||||
public:
|
||||
MOCK_BOARD_ITEM( KICAD_T aType ) : BOARD_ITEM( nullptr, aType ) {}
|
||||
|
||||
// Required virtual functions
|
||||
wxString GetClass() const override { return "MockEDAItem"; }
|
||||
void Move( const VECTOR2I& aMoveVector ) override {}
|
||||
VECTOR2I GetPosition() const override { return VECTOR2I( 0, 0 ); }
|
||||
void SetPosition( const VECTOR2I& aPos ) override {}
|
||||
BOARD_ITEM* Clone() const override { return new MOCK_BOARD_ITEM( Type() ); }
|
||||
|
||||
// Implement pure virtuals from BOARD_ITEM
|
||||
double Similarity( const BOARD_ITEM& aItem ) const override { return this == &aItem ? 1.0 : 0.0; }
|
||||
bool operator==( const BOARD_ITEM& aItem ) const override { return this == &aItem; }
|
||||
};
|
||||
|
||||
// Test fixture for accessing protected members
|
||||
class PCBGridHelperTestFixture
|
||||
{
|
||||
public:
|
||||
PCBGridHelperTestFixture()
|
||||
{
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
helper.SetSnap( true );
|
||||
}
|
||||
|
||||
PCB_GRID_HELPER helper;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( PCBGridHelperTest )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( DefaultConstructor )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
// Test default state matches base class
|
||||
BOOST_CHECK( helper.GetSnap() );
|
||||
BOOST_CHECK( helper.GetUseGrid() );
|
||||
|
||||
// Test that GetSnapped returns nullptr initially
|
||||
BOOST_CHECK( helper.GetSnapped() == nullptr );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToSegmentBasic )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Horizontal segment
|
||||
SEG seg( VECTOR2I( 0, 0 ), VECTOR2I( 300, 0 ) );
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 150, 50 ), seg );
|
||||
|
||||
// Should snap to grid point that intersects with segment
|
||||
BOOST_CHECK_EQUAL( result.x, 200 );
|
||||
BOOST_CHECK_EQUAL( result.y, 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToSegmentVertical )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Vertical segment
|
||||
SEG seg( VECTOR2I( 200, 0 ), VECTOR2I( 200, 400 ) );
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 150, 150 ), seg );
|
||||
|
||||
// Should snap to intersection with vertical line
|
||||
BOOST_CHECK_EQUAL( result.x, 200 );
|
||||
BOOST_CHECK_EQUAL( result.y, 200 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToSegmentDiagonal )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Diagonal segment
|
||||
SEG seg( VECTOR2I( 0, 0 ), VECTOR2I( 400, 400 ) );
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 150, 250 ), seg );
|
||||
|
||||
// 250,250 is the closest point to the nearest grid point to the segment.
|
||||
// First, it snaps to grid point (200, 300) and then finds the closest point on the segment.
|
||||
// So the result should be (250, 250).
|
||||
BOOST_CHECK_EQUAL( result.x, 250 );
|
||||
BOOST_CHECK_EQUAL( result.y, 250 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToSegmentEndpoints )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
SEG seg( VECTOR2I( 50, 50 ), VECTOR2I( 150, 50 ) );
|
||||
|
||||
// Point very close to start endpoint
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 55, 55 ), seg );
|
||||
BOOST_CHECK_EQUAL( result.x, 50 );
|
||||
BOOST_CHECK_EQUAL( result.y, 50 );
|
||||
|
||||
// Point very close to end endpoint
|
||||
result = helper.AlignToSegment( VECTOR2I( 145, 55 ), seg );
|
||||
BOOST_CHECK_EQUAL( result.x, 150 );
|
||||
BOOST_CHECK_EQUAL( result.y, 50 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToSegmentSnapDisabled )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
helper.SetSnap( false ); // Disable snapping
|
||||
|
||||
SEG seg( VECTOR2I( 0, 0 ), VECTOR2I( 300, 0 ) );
|
||||
VECTOR2I point( 150, 50 );
|
||||
VECTOR2I result = helper.AlignToSegment( point, seg );
|
||||
|
||||
// Should return grid-aligned point when snap is disabled
|
||||
VECTOR2I expected = helper.Align( point );
|
||||
BOOST_CHECK_EQUAL( result.x, expected.x );
|
||||
BOOST_CHECK_EQUAL( result.y, expected.y );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToArcBasic )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Create a simple arc (quarter circle)
|
||||
SHAPE_ARC arc( VECTOR2I( 100, 0 ), VECTOR2I( 0, 100 ), ANGLE_90 );
|
||||
|
||||
VECTOR2I result = helper.AlignToArc( VECTOR2I( 50, 50 ), arc );
|
||||
|
||||
// Should snap to arc endpoints or intersections
|
||||
BOOST_CHECK( result.x >= 0 );
|
||||
BOOST_CHECK( result.y >= 0 );
|
||||
}
|
||||
|
||||
// TODO: Fix broken AlignToArc Routine
|
||||
// BOOST_AUTO_TEST_CASE( AlignToArcEndpoints )
|
||||
// {
|
||||
// PCB_GRID_HELPER helper;
|
||||
// helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
// helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
// helper.SetGridSnapping( true );
|
||||
|
||||
// SHAPE_ARC arc( VECTOR2I( 100, 0 ), VECTOR2I( 65, 65 ), VECTOR2I( 0, 100 ), 0 );
|
||||
|
||||
// // Point close to start
|
||||
// VECTOR2I result = helper.AlignToArc( VECTOR2I( 95, 5 ), arc );
|
||||
// BOOST_CHECK_EQUAL( result.x, arc.GetP0().x );
|
||||
// BOOST_CHECK_EQUAL( result.y, arc.GetP0().y );
|
||||
|
||||
// // Point close to end
|
||||
// result = helper.AlignToArc( VECTOR2I( 5, 95 ), arc );
|
||||
// BOOST_CHECK_EQUAL( result.x, arc.GetP1().x );
|
||||
// BOOST_CHECK_EQUAL( result.y, arc.GetP1().y );
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AlignToArcSnapDisabled )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
helper.SetSnap( false ); // Disable snapping
|
||||
|
||||
SHAPE_ARC arc( VECTOR2I( 100, 0 ), VECTOR2I( 0, 100 ), ANGLE_90 );
|
||||
VECTOR2I point( 50, 50 );
|
||||
VECTOR2I result = helper.AlignToArc( point, arc );
|
||||
|
||||
// Should return grid-aligned point when snap is disabled
|
||||
VECTOR2I expected = helper.Align( point );
|
||||
BOOST_CHECK_EQUAL( result.x, expected.x );
|
||||
BOOST_CHECK_EQUAL( result.y, expected.y );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridFootprint )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM footprint( PCB_FOOTPRINT_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &footprint );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_CONNECTABLE );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridPad )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM pad( PCB_PAD_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &pad );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_CONNECTABLE );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridText )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM text( PCB_TEXT_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &text );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_TEXT );
|
||||
|
||||
MOCK_BOARD_ITEM field( PCB_FIELD_T );
|
||||
grid = helper.GetItemGrid( &field );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_TEXT );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridGraphics )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM shape( PCB_SHAPE_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &shape );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_GRAPHICS );
|
||||
|
||||
MOCK_BOARD_ITEM dimension( PCB_DIMENSION_T );
|
||||
grid = helper.GetItemGrid( &dimension );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_GRAPHICS );
|
||||
|
||||
MOCK_BOARD_ITEM refImage( PCB_REFERENCE_IMAGE_T );
|
||||
grid = helper.GetItemGrid( &refImage );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_GRAPHICS );
|
||||
|
||||
MOCK_BOARD_ITEM textbox( PCB_TEXTBOX_T );
|
||||
grid = helper.GetItemGrid( &textbox );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_GRAPHICS );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridTracks )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM trace( PCB_TRACE_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &trace );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_WIRES );
|
||||
|
||||
MOCK_BOARD_ITEM arc( PCB_ARC_T );
|
||||
grid = helper.GetItemGrid( &arc );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_WIRES );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridVias )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
MOCK_BOARD_ITEM via( PCB_VIA_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &via );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_VIAS );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetItemGridDefault )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
// Test with unknown item type
|
||||
MOCK_BOARD_ITEM unknown( PCB_ZONE_T );
|
||||
GRID_HELPER_GRIDS grid = helper.GetItemGrid( &unknown );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_CURRENT );
|
||||
|
||||
// Test with nullptr
|
||||
grid = helper.GetItemGrid( nullptr );
|
||||
BOOST_CHECK_EQUAL( grid, GRID_CURRENT );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GetSnappedInitiallyNull )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
BOARD_ITEM* snapped = helper.GetSnapped();
|
||||
BOOST_CHECK( snapped == nullptr );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( OnBoardItemRemovedClearsSnap )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
|
||||
// Create a mock board and item - this test verifies the interface exists
|
||||
// In a real scenario, the snap item would be set by other operations
|
||||
BOARD board;
|
||||
MOCK_BOARD_ITEM item( PCB_TRACE_T );
|
||||
|
||||
// This should not crash even if no snap item is set
|
||||
helper.OnBoardItemRemoved( board, static_cast<BOARD_ITEM*>( &item ) );
|
||||
|
||||
BOOST_CHECK( helper.GetSnapped() == nullptr );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GeometricSnapTolerance )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 100, 100 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
SEG seg( VECTOR2I( 0, 0 ), VECTOR2I( 200, 0 ) );
|
||||
|
||||
// Test that points very far from segment don't snap to unrealistic locations
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 50, 100000 ), seg );
|
||||
|
||||
// Should snap to midpoint of segment
|
||||
BOOST_CHECK( result == VECTOR2I( 100, 0 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( SegmentIntersectionPriority )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 50, 50 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Segment that passes through a grid point
|
||||
SEG seg( VECTOR2I( 0, 25 ), VECTOR2I( 100, 25 ) );
|
||||
|
||||
// Point near a grid intersection with the segment
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 48, 27 ), seg );
|
||||
|
||||
// Should snap to the intersection at (50, 25)
|
||||
BOOST_CHECK_EQUAL( result.x, 50 );
|
||||
BOOST_CHECK_EQUAL( result.y, 25 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ArcIntersectionWithGrid )
|
||||
{
|
||||
PCB_GRID_HELPER helper;
|
||||
helper.SetGridSize( VECTOR2D( 50, 50 ) );
|
||||
helper.SetOrigin( VECTOR2I( 0, 0 ) );
|
||||
helper.SetGridSnapping( true );
|
||||
|
||||
// Arc that should intersect grid lines
|
||||
SHAPE_ARC arc( VECTOR2I( 50, 0 ), VECTOR2I( 50, 50 ), VECTOR2I( 0, 50 ), 0 );
|
||||
|
||||
// Point that should snap to an intersection
|
||||
VECTOR2I result = helper.AlignToArc( VECTOR2I( 25, 25 ), arc );
|
||||
|
||||
// Should snap to the mid point of the arc
|
||||
BOOST_CHECK_EQUAL( result.x, 50 );
|
||||
BOOST_CHECK_EQUAL( result.y, 50 );
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( LargeGridSegmentSnap, PCBGridHelperTestFixture )
|
||||
{
|
||||
// Test with larger grid to verify scaling behavior
|
||||
helper.SetGridSize( VECTOR2D( 1000, 1000 ) );
|
||||
|
||||
SEG seg( VECTOR2I( 500, 0 ), VECTOR2I( 500, 2000 ) );
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 400, 800 ), seg );
|
||||
|
||||
// Should snap to the segment at grid intersection
|
||||
BOOST_CHECK_EQUAL( result.x, 500 );
|
||||
BOOST_CHECK_EQUAL( result.y, 1000 );
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( ZeroLengthSegment, PCBGridHelperTestFixture )
|
||||
{
|
||||
// Edge case: zero-length segment (point)
|
||||
SEG seg( VECTOR2I( 100, 100 ), VECTOR2I( 100, 100 ) );
|
||||
VECTOR2I result = helper.AlignToSegment( VECTOR2I( 95, 95 ), seg );
|
||||
|
||||
// Should snap to the point itself
|
||||
BOOST_CHECK_EQUAL( result.x, 100 );
|
||||
BOOST_CHECK_EQUAL( result.y, 100 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
x
Reference in New Issue
Block a user