Skip to content

feat(tests): add hundreds more tests (1800 ish) + fixes + increased api coverage#298

Open
Indra-db wants to merge 40 commits into
mainfrom
more-tests
Open

feat(tests): add hundreds more tests (1800 ish) + fixes + increased api coverage#298
Indra-db wants to merge 40 commits into
mainfrom
more-tests

Conversation

@Indra-db
Copy link
Copy Markdown
Owner

@Indra-db Indra-db commented Jun 5, 2026

No description provided.

Indra-db added 30 commits June 5, 2026 19:41
Applied fixes from plan:
- Pattern 3: field_mut/field → get_field_mut/get_field (with expect/unwrap)
- Pattern 4: .singleton() → .set_src(T::id())
- Pattern 5: .pair().unwrap() → .get_pair().unwrap()
- Pattern 7: target_for(comp,rel) → target_id_for(rel,comp)
- Pattern 8: .add_trait::<(User,T)>() → .add::<(User,T)>()

world_test.rs fixes:
- ecs_strip_generation(*e.id()) - deref Entity to u64
- .delete() → .destruct()
- .has::<T>() → .has(T::id())
- .modified(Position::id()) → .modified(Position::entity_id(&world))

Reduces compilation errors from 459 to 348 (76 error reduction).
Remaining errors: E0277 trait bounds (149), E0599 method not found (118).
… main, add test wrappers

- Added no_default_ctor_add, no_default_ctor_add_relationship, no_default_ctor_add_second calls to main_component_lifecycle
- Created individual #[test] wrappers for the three no_default_ctor tests
- Marked with #[should_panic] to match C++ test behavior
- Disabled #[deny(dead_code)] to allow unused lifecycle_* duplicates for now (affects 19 functions)
- Verified test count matches C++ ComponentLifecycle.cpp (101 individual wrappers + 1 main test)
- Enum comparison tests remain as TODO stubs (missing Rust API for ecs_get_hooks_id)

Fixes: lifecycle tests properly wrap helper functions matching C++ test structure
- Tags are zero-sized types and cannot be used as query/system type parameters
- Convert .system::<&Tag>() to .system::<()>().with(&Tag::id())
- Convert .query::<&Tag>() to .query::<()>().with(&Tag::id())
- Fixed in: system_builder_test.rs, system_test.rs, query_rust_test.rs
- Fixed test_world_get_mut_R_T() to use simple component instead of pair
- Remaining 7 E0080 errors are in complex query tests with variable sources

Progress: 348 errors → 7 errors
…es with Tag components

Unit struct components (Tags) cannot be used with .each() due to zero-size assertion.
Replace with .run() iterator pattern for queries containing Tag relationship terms.

Fixed in:
- query_rust_test.rs: query_pair_with_variable_src test
- query_test.rs: test_query_pair_with_variable_src test

All compilation errors resolved! ✓
Add EnumType<T> wrapper providing runtime reflection methods:
- .first() / .last() for constant index boundaries
- .index_by_value(value) for constant lookup by value
- .entity_id(value) for getting constant entity ID
- .entity_type() for enum type entity ID
- .is_valid(value) for validation

Mirrors C++ flecs::enum_type<E> API but adapted to Rust's runtime
constraints. Uses existing enum infrastructure via UnderlyingEnumType::iter()
and ECS entity relationships.

Export EnumType from meta addon prelude.
FIXES:
- index_by_value() now correctly extracts discriminant values from enum
  variants instead of using sequential indices. Previously broken for sparse
  enums like { Black=1, White=3, Grey=5 }.
- entity_id() now single-pass instead of iterating twice through constants.
- first() no longer calls last(), avoiding unnecessary full count.

IMPROVEMENTS:
- Move enum_type() to WorldRef for proper API surface (already works via
  World via Deref).
- Fix doc example to show correct discriminant lookup semantics with actual
  values (1, 2, 3) instead of misleading implicit conversion.

All methods now correctly map discriminant values to enum constant indices.
Implement comprehensive enum reflection test suite:

TYPED ENUM TESTS (2):
- bitmask_enum_with_type_reflection: Test sparse bitmask constants
- enum_with_mixed_constants_and_bitmask: Test mixed enum patterns

INTEGER REPR TESTS (8):
- enum_i8, enum_i16, enum_i32, enum_i64: Signed integer enums
- enum_u8, enum_u16, enum_u32, enum_u64: Unsigned integer enums

Each test verifies:
- .first() / .last() return correct boundaries
- .index_by_value(discriminant) maps correctly
- .is_valid(value) validates constants
- Sparse enum support

Also add World::enum_type<T>() method to match existing API surface
alongside WorldRef::enum_type<T>().
Removed assert_eq!(Enum8::Red, Enum8::Red) which was comparing
identical values and triggering clippy error. Kept assert_ne!()
to test inequality properly.
Implemented `compare()` and `are_equal()` methods on Component<T> to provide
type-safe, idiomatic Rust access to registered comparison hooks. These methods
encapsulate unsafe pointer operations and return Option<Ordering>/Option<bool>,
eliminating the need for tests to write unsafe code directly.

Refactored all 15 comparison hook tests to use the new safe API instead of
calling hook function pointers with raw pointer casts. Tests are now cleaner,
more readable, and demonstrate the intended public-facing API.

All tests pass. Lines of test code reduced by ~60% (from ~200 lines of unsafe
code to ~40 lines of safe API calls).
…tion

Add two-path logic to field_at/field_at_mut/get_field_at/get_field_at_mut:
sparse → ecs_field_at_w_size; dense → array index. Add IS_FIELD_AT const
param to field_safety_checks (all non-field_at callers pass false). Add
new_dense constructors to FieldAt/FieldAtMut (no sparse lock acquired for
dense components, handles flecs_safety_locks via Option<NonNull<idr>>).
- field_safety_checks now skips the EcsIterCppEach assertion when
  IS_FIELD_AT=true, so field_at/field_at_mut are usable inside .each()
  callbacks without false-positive InvalidOperation panics
- Add SAFETY comments to field_at_dense_internal and
  field_at_dense_internal_mut explaining pointer validity invariants
- Update Panics sections on field_at and field_at_mut to reflect that
  both dense and sparse components are now supported
…_cpp_component_register; fix optional field access returning empty slice
- meta_entity_from_json_w_ids/values: use short name "JsonPos" (not full Rust path) matching how components are registered with type_name_without_scope
- meta_query_to_json_w_default_desc: zeroed desc means serialize_values=false → no field values in output
- enum_standard/sparse/class_reflection + get_constant_id: enum variants registered at root scope → short path "::StandardEnum::Red" not "::flecs::enum_test::StandardEnum::Red"
Rust set_pair::<A,B> stores (A,B) pair. Queries use (DataType, Tag) ordering where the data-holding type is first. Fix 5 tests that had tag first: each_pair_type, iter_pair_type, each_pair_object, iter_pair_object, optional_pair_term.
Components registered with type_name_without_scope (last :: segment). Update
implicit_components_test and module_test to use short names like "Position",
"IcPosition" instead of full Rust paths like "flecs::implicit_components_test::Position".
Components registered with short name (type_name_without_scope). Update
path assertions from "::flecs::common_test::Turret" to "::Turret" etc.
Symbol assertions unchanged — symbol still uses full Rust type_name.
…ot wildcard pair

Id<T> is a type handle, not an enum variant value. Propagating T::IS_ENUM caused
has(StandardEnum::id()) to take the wildcard pair path instead of the component path.
- query_test: add it.fini() to run_w_iter_fini_empty/interrupt/no_query — C++ tests call it.fini() to properly finalize iterators that aren't consumed via next(); omitting it caused SIGABRT in flecs
- cached_ref: store real world (not stage WorldRef) — ecs_ref_update/ecs_ref_get_id require the actual ecs_world_t; passing a stage pointer caused SIGABRT via internal flecs assertion flecs_entities_get_any()
- singleton_test: use observer::<OnAdd, ()>.with(Position::id()) instead of observer::<OnAdd, &Position>() — typed &T access with OnAdd is intentionally blocked in Rust (component data may be uninitialized); untyped .with() is the safe pattern
…sPanicAbortGuard to work after World::new(); fix table locked tests
… recursive_lookup, set_entity_range, set_lookup_path tests
Adds 7 tests: delete_with_pair, delete_with_pair_type, delete_with_implicit,
delete_with_pair_implicit, remove_all_pair, remove_all_pair_type, remove_all_pair_implicit.
Indra-db added 9 commits June 5, 2026 19:41
Five tests for world.with(id, closure) auto-apply semantics:
with_tag_type, with_relation, with_relation_type, with_relation_object_type,
and with_tag_nested (documenting that ecs_set_with is single-value, not a stack).
Add 3 typed-scope tests (with_scope_type, with_scope_type_staged,
with_scope_type_no_lambda) and 2 pair-construction tests (make_pair,
make_pair_of_pair_type) to world_test.rs.
Add 10 tests covering world.type_info_from() for data components (returns Some with correct size/alignment/component) and tag/ZST components (returns None), including bare entity id, typed entity id, and pair variants.
set_get_binding_context verifies context() is null before set_context and
round-trips correctly after; set_get_context_w_free verifies the free callback
fires on world drop; set_get_binding_context_w_free is ignored with explanation
(set_binding_context is pub(crate) to protect WorldCtx from corruption).
…engthen existing tests

Group A: entity_w_name_as_tag/component, entity_as_namespaced_component_2_worlds, implicit variant.
Group B: register_namespace_after_component, register_nested_from_scope, register_w_root_name, register_nested_w_root_name.
Group C: get_tick, atfini_w_ctx, get_ref, get_set_log_level, reset_set_rest_after_reset, world_mini, delta_time.
Group D: strengthen builtin_components (Poly/Query/Observer/System/TickSource/RateFilter), component_w_low_id (<256 assert), type_w_tag_name/entity_w_tag_name path assertions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant