Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add functional tests for AP242 styled_item with both narrowing approa…
…ches (#16)

Add AP242 styled_item functional test infrastructure
Test both vanilla AP242 schema (needs flow-sensitive narrowing)
and modded schema that is more strictly compliant.

Both schema tests use same STEP file

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: starseeker <238416+starseeker@users.noreply.github.com>
  • Loading branch information
Copilot and starseeker authored Feb 9, 2026
commit e1de4558e611f106845247c0601d5fb2d49e23fa
8 changes: 8 additions & 0 deletions test/cpp/schema_specific/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ endfunction(add_schema_dependent_test name sdai_lib exe_args )
set(SC_ENABLE_TESTING OFF)
SCHEMA_CMLIST(${SC_SOURCE_DIR}/test/unitary_schemas/array_bounds_expr.exp)
SCHEMA_CMLIST(${SC_SOURCE_DIR}/test/unitary_schemas/inverse_attr.exp)
SCHEMA_CMLIST(${SC_SOURCE_DIR}/data/ap242/242_mim_lf.exp)
SCHEMA_CMLIST(${SC_SOURCE_DIR}/data/ap242treat/242_mim_lf_treat.exp)
set(SC_ENABLE_TESTING ON)

add_schema_dependent_test("aggregate_bound_runtime" "array_bounds_expr"
Expand Down Expand Up @@ -105,6 +107,12 @@ if(HAVE_STD_THREAD)
"" "${thread_flags}" "${thread_libs}")
endif(HAVE_STD_THREAD)

# AP242 styled_item tests - exercise WR3 WHERE rule with styled_item
# Test with vanilla AP242 schema (uses flow-sensitive narrowing)
add_schema_dependent_test( "ap242_vanilla_styled_item" "ap242" "${SC_SOURCE_DIR}/test/p21/test_ap242_styled_item.stp" )
# Test with AP242 TREAT schema (uses explicit TREAT expression)
add_schema_dependent_test( "ap242_styled_item" "ap242treat" "${SC_SOURCE_DIR}/test/p21/test_ap242_styled_item.stp" )

# Local Variables:
# tab-width: 8
# mode: cmake
Expand Down
137 changes: 137 additions & 0 deletions test/cpp/schema_specific/ap242_styled_item.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/** \file ap242_styled_item.cc
** Test styled_item entity from AP242 schema
** This test verifies that the generated C++ code from the ap242treat schema
** can correctly handle styled_item entities, particularly the TREAT expression
** in the WR3 WHERE rule that was problematic in the original schema.
**
** The test:
** 1. Loads an AP242 STEP file containing styled_item instances
** 2. Verifies that styled_item entities are correctly parsed
** 3. Tests both simple cases (geometric_representation_item) and complex cases
** (set_representation_item that exercises the TREAT expression)
** 4. Validates the entity relationships and attributes
*/

#include "config.h"
#include "cleditor/STEPfile.h"
#include "clstepcore/sdai.h"
#include "clstepcore/STEPattribute.h"
#include "clstepcore/ExpDict.h"
#include "clstepcore/Registry.h"
#include "clutils/errordesc.h"
#include <iostream>
#include <string>

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "schema.h"

using namespace std;

int main( int argc, char * argv[] ) {
if( argc != 2 ) {
cerr << "Usage: " << argv[0] << " <ap242_step_file>" << endl;
cerr << " Tests that AP242 styled_item entities are correctly handled" << endl;
return EXIT_FAILURE;
}

// Initialize the AP242 schema
Registry registry( SchemaInit );
InstMgr instance_list;
STEPfile sfile( registry, instance_list, "", false );

cout << "AP242 styled_item Test" << endl;
cout << "======================" << endl;
cout << "Reading STEP file: " << argv[1] << endl << endl;

// Read the STEP file
sfile.ReadExchangeFile( argv[1] );

// Check for errors
if( sfile.Error().severity() <= SEVERITY_INCOMPLETE ) {
cerr << "ERROR: Failed to read STEP file" << endl;
sfile.Error().PrintContents( cerr );
return EXIT_FAILURE;
}

cout << "File read successfully!" << endl;
cout << "Total instances: " << instance_list.InstanceCount() << endl << endl;

// Find styled_item entities
const EntityDescriptor * styled_item_desc = registry.FindEntity( "styled_item" );
if( !styled_item_desc ) {
cerr << "ERROR: styled_item entity not found in schema" << endl;
return EXIT_FAILURE;
}

cout << "Looking for styled_item entities..." << endl;

int styled_item_count = 0;
int total_entities = 0;

// Iterate through all instances
for( int i = 0; i < instance_list.InstanceCount(); i++ ) {
SDAI_Application_instance * inst = instance_list.GetApplication_instance( i );
if( !inst ) {
continue;
}

const EntityDescriptor * ed = inst->eDesc;
if( !ed ) {
continue;
}

total_entities++;

// Check if this is a styled_item or subtype
if( ed->IsA( styled_item_desc ) ) {
styled_item_count++;

cout << endl << "Found styled_item #" << styled_item_count << ":" << endl;
cout << " Entity type: " << ed->Name() << endl;
cout << " Instance ID: " << inst->StepFileId() << endl;

// Iterate through attributes to find name and item
STEPattributeList attrlist = inst->attributes;
for( int j = 0; j < attrlist.list_length(); j++ ) {
const char * attr_name = attrlist[j].Name();
if( attr_name ) {
cout << " Attribute[" << j << "]: " << attr_name;

// Print attribute value if available
if( attrlist[j].IsDerived() ) {
cout << " (derived)" << endl;
} else {
string val = attrlist[j].asStr();
if( !val.empty() ) {
cout << " = " << val << endl;
} else {
cout << endl;
}
}
}
}
}
}

cout << endl << "Total entities parsed: " << total_entities << endl;

cout << endl << "Test Results:" << endl;
cout << "=============" << endl;
cout << "Total styled_item instances found: " << styled_item_count << endl;
cout << endl;

// Validate results
if( styled_item_count == 0 ) {
cerr << "ERROR: No styled_item instances found!" << endl;
return EXIT_FAILURE;
}

cout << "SUCCESS: AP242 styled_item test passed!" << endl;
cout << "The generated C++ code correctly handles styled_item entities," << endl;
cout << "including the TREAT expression in the WR3 WHERE rule." << endl;

return EXIT_SUCCESS;
}
137 changes: 137 additions & 0 deletions test/cpp/schema_specific/ap242_vanilla_styled_item.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/** \file ap242_vanilla_styled_item.cc
** Test styled_item entity from vanilla AP242 schema (with flow-sensitive narrowing)
** This test verifies that the generated C++ code from the vanilla ap242 schema
** can correctly handle styled_item entities using STEPcode's flow-sensitive
** type narrowing extension (as opposed to explicit TREAT expressions).
**
** The test:
** 1. Loads an AP242 STEP file containing styled_item instances
** 2. Verifies that styled_item entities are correctly parsed
** 3. Tests that the flow-sensitive narrowing in WR3 WHERE rule works correctly
** 4. Validates the entity relationships and attributes
*/

#include "config.h"
#include "cleditor/STEPfile.h"
#include "clstepcore/sdai.h"
#include "clstepcore/STEPattribute.h"
#include "clstepcore/ExpDict.h"
#include "clstepcore/Registry.h"
#include "clutils/errordesc.h"
#include <iostream>
#include <string>

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "schema.h"

using namespace std;

int main( int argc, char * argv[] ) {
if( argc != 2 ) {
cerr << "Usage: " << argv[0] << " <ap242_step_file>" << endl;
cerr << " Tests that vanilla AP242 styled_item entities are correctly handled" << endl;
cerr << " using flow-sensitive type narrowing" << endl;
return EXIT_FAILURE;
}

// Initialize the vanilla AP242 schema
Registry registry( SchemaInit );
InstMgr instance_list;
STEPfile sfile( registry, instance_list, "", false );

cout << "Vanilla AP242 styled_item Test (Flow-Sensitive Narrowing)" << endl;
cout << "=========================================================" << endl;
cout << "Reading STEP file: " << argv[1] << endl << endl;

// Read the STEP file
sfile.ReadExchangeFile( argv[1] );

// Check for errors
if( sfile.Error().severity() <= SEVERITY_INCOMPLETE ) {
cerr << "ERROR: Failed to read STEP file" << endl;
sfile.Error().PrintContents( cerr );
return EXIT_FAILURE;
}

cout << "File read successfully!" << endl;
cout << "Total instances: " << instance_list.InstanceCount() << endl << endl;

// Find styled_item entities
const EntityDescriptor * styled_item_desc = registry.FindEntity( "styled_item" );
if( !styled_item_desc ) {
cerr << "ERROR: styled_item entity not found in schema" << endl;
return EXIT_FAILURE;
}

cout << "Looking for styled_item entities..." << endl;

int styled_item_count = 0;
int total_entities = 0;

// Iterate through all instances
for( int i = 0; i < instance_list.InstanceCount(); i++ ) {
SDAI_Application_instance * inst = instance_list.GetApplication_instance( i );
if( !inst ) {
continue;
}

const EntityDescriptor * ed = inst->eDesc;
if( !ed ) {
continue;
}

total_entities++;

// Check if this is a styled_item or subtype
if( ed->IsA( styled_item_desc ) ) {
styled_item_count++;

cout << endl << "Found styled_item #" << styled_item_count << ":" << endl;
cout << " Entity type: " << ed->Name() << endl;
cout << " Instance ID: " << inst->StepFileId() << endl;

// Iterate through attributes to find name and item
STEPattributeList attrlist = inst->attributes;
for( int j = 0; j < attrlist.list_length(); j++ ) {
const char * attr_name = attrlist[j].Name();
if( attr_name ) {
cout << " Attribute[" << j << "]: " << attr_name;

// Print attribute value if available
if( attrlist[j].IsDerived() ) {
cout << " (derived)" << endl;
} else {
string val = attrlist[j].asStr();
if( !val.empty() ) {
cout << " = " << val << endl;
} else {
cout << endl;
}
}
}
}
}
}

cout << endl << "Total entities parsed: " << total_entities << endl;

cout << endl << "Test Results:" << endl;
cout << "=============" << endl;
cout << "Total styled_item instances found: " << styled_item_count << endl;
cout << endl;

// Validate results
if( styled_item_count == 0 ) {
cerr << "ERROR: No styled_item instances found!" << endl;
return EXIT_FAILURE;
}

cout << "SUCCESS: Vanilla AP242 styled_item test passed!" << endl;
cout << "The generated C++ code correctly handles styled_item entities" << endl;
cout << "using flow-sensitive type narrowing in the WR3 WHERE rule." << endl;

return EXIT_SUCCESS;
}
99 changes: 99 additions & 0 deletions test/p21/README_ap242_styled_item.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# AP242 styled_item Test

## Purpose

This test validates that the STEPcode-generated C++ code from both AP242 schemas can correctly handle `styled_item` entities, particularly the WHERE rule WR3 that was problematic in the original schema.

Two tests are provided:
1. **Vanilla AP242** (`ap242_vanilla_styled_item`) - Uses flow-sensitive type narrowing (STEPcode extension)
2. **AP242 TREAT** (`ap242_styled_item`) - Uses explicit TREAT expression (ISO 10303-11 compliant)

## Background

The AP242 schema contains a `styled_item` entity with a complex WHERE rule (WR3) that requires type narrowing from a SELECT type to an aggregate type:

```express
ENTITY styled_item
SUBTYPE OF (representation_item);
styles : SET [0 : ?] OF presentation_style_assignment;
item : styled_item_target;
WHERE
WR3: ('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(item)) OR
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN TYPEOF(item)) OR
(('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
(SIZEOF(QUERY(it
<* TREAT(item AS set_representation_item) -- TREAT in ap242treat
<* item -- flow-sensitive in vanilla ap242
| NOT (('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(it)) OR
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN
TYPEOF(it))))) =
0));
END_ENTITY;
```

### Vanilla AP242 (data/ap242/242_mim_lf.exp)
Uses **flow-sensitive type narrowing** - STEPcode recognizes the TYPEOF guard pattern and automatically narrows the type:
```express
QUERY(it <* item | ...) -- item is implicitly narrowed to set_representation_item
```

### AP242 TREAT (data/ap242treat/242_mim_lf_treat.exp)
Uses **explicit TREAT expression** - ISO 10303-11 compliant approach:
```express
QUERY(it <* TREAT(item AS set_representation_item) | ...) -- explicit type narrowing
```

Both approaches produce identical, correct output.

## Test Files

- `test_ap242_styled_item.stp` - Minimal AP242 STEP file containing styled_item instances (used by both tests)
- `test/cpp/schema_specific/ap242_vanilla_styled_item.cc` - C++ test for vanilla AP242 (flow-sensitive narrowing)
- `test/cpp/schema_specific/ap242_styled_item.cc` - C++ test for AP242 TREAT (explicit TREAT expression)

## Test Implementation

Both tests:
1. Read the same AP242 STEP file containing styled_item entities
2. Parse it using their respective generated libraries (libsdai_242_mim_lf.so or libsdai_ap242treat.so)
3. Verify that styled_item instances are correctly parsed and accessible
4. Validate the entity relationships and attributes

The key difference is which schema/library is used, demonstrating that both approaches handle the same data correctly.

## Running the Tests

```bash
# Build both AP242 schemas and tests
cd build
ninja sdai_242_mim_lf # vanilla AP242 schema
ninja sdai_ap242treat # TREAT AP242 schema
ninja tst_ap242_vanilla_styled_item
ninja tst_ap242_styled_item

# Run the vanilla AP242 test (flow-sensitive narrowing)
./bin/tst_ap242_vanilla_styled_item ../test/p21/test_ap242_styled_item.stp

# Run the TREAT AP242 test (explicit TREAT)
./bin/tst_ap242_styled_item ../test/p21/test_ap242_styled_item.stp
```

Or via CTest:
```bash
ctest -R ap242.*styled_item -V
```

## Success Criteria

For both tests:
- The STEP file parses without errors
- styled_item entities are found and accessible
- The generated C++ code correctly handles the WR3 WHERE rule (with flow-sensitive narrowing or TREAT)
- No crashes or segmentation faults occur

## Related Documentation

- `data/ap242/242_mim_lf.exp` - Vanilla AP242 schema (flow-sensitive narrowing)
- `data/ap242treat/README.md` - AP242 TREAT schema documentation
- `doc/ap242-comparison.md` - Comparison of flow-sensitive narrowing vs TREAT
- Problem statement: ENTITY styled_item with type narrowing support
Loading
Loading