KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_ipc2581_export.cpp File Reference

Test suite for IPC-2581 export validation. More...

#include <pcbnew_utils/board_test_utils.h>
#include <pcbnew_utils/board_file_utils.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <pcbnew/pcb_io/ipc2581/pcb_io_ipc2581.h>
#include <pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h>
#include <board.h>
#include <board_design_settings.h>
#include <board_stackup_manager/board_stackup.h>
#include <footprint.h>
#include <pad.h>
#include <pcb_shape.h>
#include <pcb_track.h>
#include <base_units.h>
#include <wx/dir.h>
#include <wx/file.h>
#include <wx/filename.h>
#include <wx/process.h>
#include <wx/txtstrm.h>
#include <cmath>
#include <fstream>
#include <sstream>

Go to the source code of this file.

Classes

struct  IPC2581_EXPORT_FIXTURE
 

Functions

 BOOST_AUTO_TEST_CASE (SurfaceFinishExport)
 Test that surface finish is exported correctly (Issue #22690)
 
 BOOST_AUTO_TEST_CASE (NoSurfaceFinishExport)
 Test that boards without surface finish don't generate coating layers.
 
 BOOST_AUTO_TEST_CASE (SchemaValidationVersionB)
 Validate IPC-2581B export against schema for multiple boards.
 
 BOOST_AUTO_TEST_CASE (SchemaValidationVersionC)
 Validate IPC-2581C export against schema for multiple boards.
 
 BOOST_AUTO_TEST_CASE (ComplexBoardExport)
 Test export of boards with complex features.
 
 BOOST_AUTO_TEST_CASE (SmdPadSolderMaskExport_Issue16658)
 Test that SMD pad solder mask openings are exported (Issue #16658)
 
, or PinRef/@componentRef attributes, which are

Test that footprints with empty references produce valid XML attributes.

Footprints with blank GetReference() must not produce empty refDes, RefDes/ schema-invalid qualified names.

 BOOST_AUTO_TEST_CASE (EmptyRefDesProducesValidXml)
 
 BOOST_AUTO_TEST_CASE (FlippedComponentRotation)
 Test that flipped component rotation is not inverted (Finding A / Issue #18013)
 
 BOOST_AUTO_TEST_CASE (ContentBomRef)
 Test that Content section includes BomRef when BOM is emitted.
 
 BOOST_AUTO_TEST_CASE (KnockoutTextMultiContour_Issue23968)
 Test that knockout text with holes emits schema-valid XML (Issue #23968)
 
 BOOST_AUTO_TEST_CASE (BackdrillSpecEncoding)
 Verify IPC-2581 backdrill encoding matches the schema and expresses the correct must-not-cut layer.
 
 BOOST_AUTO_TEST_CASE (ExposedPadPasteRespected_Issue24318)
 Test that SMD pads without F.Paste in their layer set are not added to the solder paste layer (Issue #24318).
 
static std::string ReadFile (const wxString &aPath)
 Read an exported file's full contents into a std::string.
 
static std::string LayerFeatureRegion (const std::string &aXml, const std::string &aLayerRef)
 Extract the text of the first LayerFeature block for a given layer reference.
 
 BOOST_AUTO_TEST_CASE (GrRectCornerRadius_Issue24754)
 Test that a rounded gr_rect keeps its corner radius on export (Issue #24754).
 
 BOOST_AUTO_TEST_CASE (BackOnlyMaskNoFrontOpening_Issue24753)
 Test that a back-only masked through-hole pad gets no F.Mask opening (Issue #24753).
 
 BOOST_AUTO_TEST_CASE (RoundRectMaskRadius_Issue24751)
 Test that a roundrect pad's mask aperture shrinks its radius with its size (Issue #24751).
 
 BOOST_AUTO_TEST_CASE (MultiLayerFootprintGraphic_Issue24752)
 Test that a multi-layer footprint graphic is emitted on every layer (Issue #24752).
 
 BOOST_AUTO_TEST_CASE (SolderMaskMarginExpandsMaskPrimitive_Issue24749)
 Test that the per-layer solder mask margin expands the exported mask primitive (Issue #24749).
 

Detailed Description

Test suite for IPC-2581 export validation.

Tests per GitLab issues:

  • #22690: Surface finish data not exported
  • #19912: OtherSideView may be incorrect for bottom components

Definition in file test_ipc2581_export.cpp.

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/17]

BOOST_AUTO_TEST_CASE ( BackdrillSpecEncoding )

Verify IPC-2581 backdrill encoding matches the schema and expresses the correct must-not-cut layer.

KiCad's PADSTACK::DRILL_PROPS::end is the must-cut layer (per the UI "must-cut" labels). The IPC-2581 standard expects the must-not-cut layer, which is the next signal layer past the must-cut layer. The exporter must emit one Spec containing three sibling Backdrill children with type START_LAYER, MUST_NOT_CUT_LAYER, and MAX_STUB_LENGTH, each carrying its value in a Property child.

Definition at line 686 of file test_ipc2581_export.cpp.

References BOARD::Add(), B_Cu, BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), BOARD_STACKUP::BuildDefaultStackupList(), COUNTERSINK, F_Cu, BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetStackupDescriptor(), In3_Cu, pcbIUScale, BOARD::SetCopperLayerCount(), and via.

◆ BOOST_AUTO_TEST_CASE() [2/17]

BOOST_AUTO_TEST_CASE ( BackOnlyMaskNoFrontOpening_Issue24753 )

Test that a back-only masked through-hole pad gets no F.Mask opening (Issue #24753).

A pad on *.Cu with an explicit B.Mask (and no F.Mask) must not be added to the F.Mask LayerFeature. The implicit-mask heuristic only applies when the pad authors no mask side.

Definition at line 998 of file test_ipc2581_export.cpp.

References BOARD::Add(), FOOTPRINT::Add(), PADSTACK::ALL_LAYERS, B_Cu, B_Mask, BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), F_Cu, FOOTPRINT, LayerFeatureRegion(), OVAL, PAD, pad, pcbIUScale, PTH, ReadFile(), BOARD::SetCopperLayerCount(), FOOTPRINT::SetPosition(), and FOOTPRINT::SetReference().

◆ BOOST_AUTO_TEST_CASE() [3/17]

BOOST_AUTO_TEST_CASE ( ComplexBoardExport )

Test export of boards with complex features.

Tests boards with zones, custom pads, and other features that may exercise edge cases in the IPC-2581 exporter.

Definition at line 416 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), and BOOST_TEST_CONTEXT().

◆ BOOST_AUTO_TEST_CASE() [4/17]

BOOST_AUTO_TEST_CASE ( ContentBomRef )

Test that Content section includes BomRef when BOM is emitted.

Definition at line 614 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), and BOOST_REQUIRE().

◆ BOOST_AUTO_TEST_CASE() [5/17]

BOOST_AUTO_TEST_CASE ( EmptyRefDesProducesValidXml )

◆ BOOST_AUTO_TEST_CASE() [6/17]

BOOST_AUTO_TEST_CASE ( ExposedPadPasteRespected_Issue24318 )

Test that SMD pads without F.Paste in their layer set are not added to the solder paste layer (Issue #24318).

Exposed-pad QFN/QFP footprints commonly use a copper-only thermal pad (F.Cu + F.Mask, no F.Paste) plus several separate paste-only apertures. The earlier #16658 fix implicitly added every copper SMD pad to the paste layer, which contaminated the stencil for these footprints. Mask is still implicit for SMD pads (every copper pad needs a mask opening), but paste must be respected exactly as authored.

Definition at line 775 of file test_ipc2581_export.cpp.

References BOARD::Add(), FOOTPRINT::Add(), PADSTACK::ALL_LAYERS, BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), F_Cu, F_Mask, F_Paste, FOOTPRINT, FOOTPRINT::GetPosition(), HEATSINK, PAD, pcbIUScale, RECTANGLE, PAD::SetAttribute(), PAD::SetLayerSet(), PAD::SetNumber(), FOOTPRINT::SetPosition(), PAD::SetPosition(), PAD::SetProperty(), FOOTPRINT::SetReference(), PAD::SetShape(), PAD::SetSize(), and SMD.

◆ BOOST_AUTO_TEST_CASE() [7/17]

BOOST_AUTO_TEST_CASE ( FlippedComponentRotation )

Test that flipped component rotation is not inverted (Finding A / Issue #18013)

IPC-2581C 3.3.2 defines positive rotation as CCW from board top. mirror="true" handles the X-axis negation for bottom components. The component rotation must be the normalized board-top angle, NOT its inverse.

Definition at line 569 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), and BOOST_REQUIRE().

◆ BOOST_AUTO_TEST_CASE() [8/17]

BOOST_AUTO_TEST_CASE ( GrRectCornerRadius_Issue24754 )

Test that a rounded gr_rect keeps its corner radius on export (Issue #24754).

The exporter used to emit a RectRound with all corner flags off and a radius of stroke_width/2, discarding the shape's real corner radius. A gr_rect with a 0.75 mm corner radius must round its corners and carry that radius in the RectRound primitive.

Definition at line 950 of file test_ipc2581_export.cpp.

References BOARD::Add(), BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), Edge_Cuts, pcbIUScale, ReadFile(), RECTANGLE, BOARD::SetCopperLayerCount(), EDA_SHAPE::SetCornerRadius(), PCB_SHAPE::SetEnd(), EDA_SHAPE::SetFilled(), PCB_SHAPE::SetLayer(), PCB_SHAPE::SetStart(), PCB_SHAPE::SetStroke(), and SOLID.

◆ BOOST_AUTO_TEST_CASE() [9/17]

BOOST_AUTO_TEST_CASE ( KnockoutTextMultiContour_Issue23968 )

Test that knockout text with holes emits schema-valid XML (Issue #23968)

Knockout text renders as a filled polygon with each glyph contour becoming a separate outline. The IPC-2581 FeaturesType allows only one Feature child, so when a knockout text produces more than one Contour it must be wrapped in a UserSpecial (which itself is a Feature that may contain any number of child Features).

test_copper_graphics.kicad_pcb contains a knockout text "Otherwise" on B.Cu, whose 'O' glyph produces two contours (outer and inner), which reproduces the multi-contour case.

Definition at line 653 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), and BOOST_TEST_CONTEXT().

◆ BOOST_AUTO_TEST_CASE() [10/17]

BOOST_AUTO_TEST_CASE ( MultiLayerFootprintGraphic_Issue24752 )

Test that a multi-layer footprint graphic is emitted on every layer (Issue #24752).

An fp_poly on F.Cu + F.Mask used to export only on its primary layer (F.Cu). KiCad plots it on both, so the F.Mask copy must be present too.

Definition at line 1099 of file test_ipc2581_export.cpp.

References BOARD::Add(), FOOTPRINT::Add(), SHAPE_POLY_SET::Append(), BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), F_Cu, F_Mask, FOOTPRINT, LayerFeatureRegion(), SHAPE_POLY_SET::NewOutline(), pcbIUScale, POLY, ReadFile(), BOARD::SetCopperLayerCount(), EDA_SHAPE::SetFilled(), PCB_SHAPE::SetLayerSet(), PCB_SHAPE::SetPolyShape(), FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), PCB_SHAPE::SetStroke(), and SOLID.

◆ BOOST_AUTO_TEST_CASE() [11/17]

BOOST_AUTO_TEST_CASE ( NoSurfaceFinishExport )

Test that boards without surface finish don't generate coating layers.

Definition at line 286 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), and BOARD_STACKUP::m_FinishType.

◆ BOOST_AUTO_TEST_CASE() [12/17]

BOOST_AUTO_TEST_CASE ( RoundRectMaskRadius_Issue24751 )

Test that a roundrect pad's mask aperture shrinks its radius with its size (Issue #24751).

A roundrect pad with a negative mask margin has a smaller mask aperture, and its corner radius must shrink by the per-side margin too. The exporter used to reuse the copper radius, and the shape-dict key ignored the layer/expansion so the mask referenced the copper shape.

Definition at line 1050 of file test_ipc2581_export.cpp.

References BOARD::Add(), FOOTPRINT::Add(), PADSTACK::ALL_LAYERS, BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), F_Cu, F_Mask, FOOTPRINT, PAD, pad, pcbIUScale, ReadFile(), ROUNDRECT, BOARD::SetCopperLayerCount(), FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), and SMD.

◆ BOOST_AUTO_TEST_CASE() [13/17]

BOOST_AUTO_TEST_CASE ( SchemaValidationVersionB )

Validate IPC-2581B export against schema for multiple boards.

This test exports each board in VALIDATION_TEST_BOARDS to IPC-2581B format and validates against the IPC-2581B1.xsd schema using xmllint (if available).

Definition at line 330 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), and BOOST_TEST_CONTEXT().

◆ BOOST_AUTO_TEST_CASE() [14/17]

BOOST_AUTO_TEST_CASE ( SchemaValidationVersionC )

Validate IPC-2581C export against schema for multiple boards.

This test exports each board in VALIDATION_TEST_BOARDS to IPC-2581C format and validates against the IPC-2581C.xsd schema using xmllint (if available).

Definition at line 373 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), and BOOST_TEST_CONTEXT().

◆ BOOST_AUTO_TEST_CASE() [15/17]

BOOST_AUTO_TEST_CASE ( SmdPadSolderMaskExport_Issue16658 )

Test that SMD pad solder mask openings are exported (Issue #16658)

This test verifies that SMD pads which have implicit solder mask openings (pads on copper layers that don't explicitly include F_Mask/B_Mask in their layer set) still get exported with solder mask features in the IPC-2581 output.

Definition at line 461 of file test_ipc2581_export.cpp.

References BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), F_Cu, F_Mask, pad, and SMD.

◆ BOOST_AUTO_TEST_CASE() [16/17]

BOOST_AUTO_TEST_CASE ( SolderMaskMarginExpandsMaskPrimitive_Issue24749 )

Test that the per-layer solder mask margin expands the exported mask primitive (Issue #24749).

The standard-primitive cache was keyed on pad geometry alone, so the copper primitive (no expansion) processed first was reused verbatim for the mask layer, dropping the solder mask margin. A 1.0 mm circular pad with a 0.5 mm mask margin must therefore export a 2.0 mm mask circle, not a 1.0 mm one.

Definition at line 1154 of file test_ipc2581_export.cpp.

References std::abs(), BOARD::Add(), FOOTPRINT::Add(), PADSTACK::ALL_LAYERS, BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), CIRCLE, F_Cu, F_Mask, FOOTPRINT, PAD, pad, pcbIUScale, FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), and SMD.

◆ BOOST_AUTO_TEST_CASE() [17/17]

BOOST_AUTO_TEST_CASE ( SurfaceFinishExport )

Test that surface finish is exported correctly (Issue #22690)

This test verifies that when a board has a surface finish defined:

  1. A Spec element with SurfaceFinish is created
  2. COATING_TOP and COATING_BOTTOM Layer elements are created with layerFunction="COATINGCOND"
  3. StackupLayer entries reference the surface finish Spec

Definition at line 240 of file test_ipc2581_export.cpp.

References BOOST_AUTO_TEST_CASE(), BOOST_CHECK_EQUAL(), BOOST_CHECK_MESSAGE(), BOOST_REQUIRE(), and BOARD_STACKUP::m_FinishType.

◆ LayerFeatureRegion()

static std::string LayerFeatureRegion ( const std::string & aXml,
const std::string & aLayerRef )
static

Extract the text of the first LayerFeature block for a given layer reference.

Returns an empty string when no such LayerFeature exists.

Definition at line 926 of file test_ipc2581_export.cpp.

References end.

Referenced by BOOST_AUTO_TEST_CASE(), and BOOST_AUTO_TEST_CASE().

◆ ReadFile()

static std::string ReadFile ( const wxString & aPath)
static

Read an exported file's full contents into a std::string.

Definition at line 914 of file test_ipc2581_export.cpp.

Referenced by BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), and BOOST_AUTO_TEST_CASE().