Skip to content

test(PS1): expand unit coverage for PlayStation importer paths - #535

Merged
fernandotonon merged 4 commits into
masterfrom
test/ps1-full-coverage
May 16, 2026
Merged

test(PS1): expand unit coverage for PlayStation importer paths#535
fernandotonon merged 4 commits into
masterfrom
test/ps1-full-coverage

Conversation

@fernandotonon

@fernandotonon fernandotonon commented May 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • Broaden PS1 unit tests (PS1TIM, PS1MAT, PS1RSD, PS1PLY, PS1TMD): invalid inputs, handwritten TIM payloads (4 / 8 / 16 bpp), MAT variants and failure paths, RSD TEX index edge cases, configurePsyqRsdMaterialPass branches, malformed / missing PLY import, TMD magic / missing-file failures, and sibling .tim binding for textured TMD imports.
  • Aims at higher automated coverage around the Psy‑Q / PlayStation mesh pipeline without touching production logic.

Test plan

  • cmake --build build_local --target UnitTests
  • xvfb-run -a ./build_local/bin/UnitTests --gtest_filter='PS1*' (or equivalent with a working GL/display setup)

Made with Cursor

Summary by CodeRabbit

  • Tests
    • Expanded test coverage for PS1 file formats: MAT material parsing and writing, PLY geometry with Ogre integration, RSD resource files with header validation, TIM texture decoding with CLUT support, and TMD model imports with texture linking.
    • Added failure-mode and edge-case assertions for missing files, malformed content, invalid paths, and unsupported formats.

Review Change Stack

Exercise error paths plus 4/8/16 bpp TIM payloads, MAT D/H variants, RSD TEX edge cases, Psy-Q PLY helpers, and TMD sibling `.tim` binding.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@fernandotonon has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 5 minutes and 21 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ca21e8d7-1a33-4aed-9923-535f66fdc1dc

📥 Commits

Reviewing files that changed from the base of the PR and between cec04da and 2f2fc58.

📒 Files selected for processing (5)
  • src/PS1/PS1MAT_test.cpp
  • src/PS1/PS1PLY_test.cpp
  • src/PS1/PS1RSD_test.cpp
  • src/PS1/PS1TIM_test.cpp
  • src/PS1/PS1TMD_test.cpp
📝 Walkthrough

Walkthrough

This pull request expands GoogleTest coverage for PS1 file format handling across five core modules: material (MAT), descriptor (RSD), polygon (PLY), texture (TIM), and mesh (TMD) parsing, writing, and integration. All changes are test-only; no production code is modified. The additions focus on negative-case error paths, edge-case data scenarios, and round-trip validation (parse → write → re-parse).

Changes

PS1 Format Handler Test Coverage

Layer / File(s) Summary
PS1MAT parsing and write coverage
src/PS1/PS1MAT_test.cpp
Test cases for parseMatFile with textured D/H entry types, file open failures, missing/mismatched entry-count lines, and absent parsable entries. Write tests verify typeChar normalization to C, S token preservation for T entries, H entry UV fallback with texture index retention, and failure on invalid nested paths.
PS1RSD parsing and write coverage
src/PS1/PS1RSD_test.cpp
Test cases for parseRsdFile with missing files, files lacking key/value pairs, automatic @RSD940102 header injection with geometry candidate verification, and sparse texture indices (TEX[300] producing chronological texture lists). Write test verifies failure when output path has non-existent parent directories.
PS1PLY validation and configuration coverage
src/PS1/PS1PLY_test.cpp
OgrePass.h include addition. Test cases for isPsyqPlyFile with nonexistent paths, configurePsyqRsdMaterialPass with null/non-null Ogre::Pass* and lightingEnabled parameter branches, and importPsyqPly with missing and malformed files.
PS1TIM image decoding and encoding coverage
src/PS1/PS1TIM_test.cpp
Test helpers for minimal valid TIM byte blobs (16bpp direct, 8bpp/4bpp indexed-with-CLUT). Negative tests for loadTimToOgreImage covering file missing, bad magic, insufficient size, unsupported bpp, missing CLUT, truncated headers/payloads. Positive decoding tests verify RGBA channels for all three formats. saveOgreImageToTim16 covers unwritable paths and STP bit encoding via pixel inspection.
PS1TMD mesh import and sibling texture integration
src/PS1/PS1TMD_test.cpp
Header includes for Qt/Ogre file/image/material/texture types. Test coverage for importTmd failures (missing file, bad magic) and integration test for minimal sibling .tmd/.tim pair generation, mesh import, material texture unit binding, and guarded resource cleanup.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • fernandotonon/QtMeshEditor#496: Implements the PS1MAT parsing/writing logic for expanded material entry types (D and H) that these test cases validate.
  • fernandotonon/QtMeshEditor#454: Introduces PS1 RSD/PLY/MAT file format handling APIs that these test cases exercise across error and edge-case branches.
  • fernandotonon/QtMeshEditor#394: Implements PS1 TMD mesh import and sibling TIM texture auto-application behavior that the integration test validates.

Poem

🐰 Test Hops Through Format Lands

A rabbit bounds through MAT and RSD,
TIM pixels decode left, right, and center,
TMD meshes mesh with textures wed—
Each edge case caught, each loop does enter.
Coverage spreads like clover in the field! 🍀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: expanding unit test coverage for PS1 importer modules.
Description check ✅ Passed The description covers both Summary and Technical Details sections, lists all five affected PS1 modules with specific test additions, and provides a concrete test plan with build and execution commands.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/ps1-full-coverage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05b27528f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/PS1/PS1TIM_test.cpp Outdated
ASSERT_TRUE(PS1TIM::loadTimToOgreImage(path, img, &err)) << err.toStdString();
const uint8_t* d = img.getData();
auto px = [&](int x, int y) {
const size_t i = (size_t(y) * 256u + size_t(x)) * 4u;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Index decoded TIM pixels with actual image width

The helper lambda in LoadDecodes8bppIndexedImage uses a hard-coded row stride of 256 pixels, but makeMinimalTim8_IndexedStrip() produces an 8×1 image (wWords=4 in 8bpp mode), so any read beyond (0,0) will compute incorrect offsets and can step outside the decoded buffer. This makes the test fragile and unable to reliably validate indexed decode behavior when expanded; derive the stride from img.getWidth() (or the known test width) instead of 256.

Useful? React with 👍 / 👎.

fernandotonon and others added 2 commits May 16, 2026 01:48
Ensure BaseMaterial exists before TMD import so per-mesh materials clone correctly.
Use decoded image width for TIM pixel indexing per review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/PS1/PS1MAT_test.cpp`:
- Around line 423-426: The test reads entries into QVector<PS1MAT::MatEntry> out
via PS1MAT::parseMatFile and then accesses out[0] without checking size; add an
assertion (e.g., ASSERT_EQ/ASSERT_GT) on out.size() or EXPECT_EQ to the expected
number of entries immediately after the parse (before accessing out[0]) so the
test fails with a clear message rather than crashing; update the test that calls
PS1MAT::parseMatFile and references out[0] to first assert the parsed entry
count.
- Around line 354-360: The test Rejects_ParseOpenFailure uses a hardcoded Unix
path; change it to create a platform-neutral non-existent path using
QTemporaryDir: instantiate QTemporaryDir, build a path inside it that you don't
create (e.g., tempDir.path() + QDir::separator() + "no_such_file.mat") and pass
that QString to PS1MAT::parseMatFile while keeping the rest of the expectations;
update the test to reference QTemporaryDir and ensure parseMatFile is called
with the constructed path so the test is deterministic across
Windows/Linux/macOS.

In `@src/PS1/PS1PLY_test.cpp`:
- Line 647: The test writes malformed PLY data to the QFile 'f' but does not
close or flush it before calling importPsyqPly, which can leave the buffer
unwritten; modify the test to flush and close 'f' (e.g., call f.flush() and
f.close() or ensure the QFile is destroyed/closed) immediately after
f.write(...) and before calling importPsyqPly so the importer reads the actual
file contents.

In `@src/PS1/PS1RSD_test.cpp`:
- Around line 103-109: The test PS1RSD.ParseFails_WhenFileMissing currently uses
a hardcoded POSIX path; change it to create a QTemporaryDir (e.g. QTemporaryDir
tmpDir) and build a platform-neutral missing-file path (e.g. tmpDir.path() +
QDir::separator() + "model.rsd") and pass that to PS1RSD::parseRsdFile with the
existing PS1RSD::RsdDescriptor d and err variables; ensure the file does not
exist in that temp dir before calling parseRsdFile so the
EXPECT_FALSE(parseRsdFile(...)) and EXPECT_FALSE(err.isEmpty()) assertions
remain valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 190268ad-e178-44a6-b117-b1d93aef06dc

📥 Commits

Reviewing files that changed from the base of the PR and between f93cbdf and cec04da.

📒 Files selected for processing (5)
  • src/PS1/PS1MAT_test.cpp
  • src/PS1/PS1PLY_test.cpp
  • src/PS1/PS1RSD_test.cpp
  • src/PS1/PS1TIM_test.cpp
  • src/PS1/PS1TMD_test.cpp

Comment thread src/PS1/PS1MAT_test.cpp
Comment thread src/PS1/PS1MAT_test.cpp
Comment thread src/PS1/PS1PLY_test.cpp
Comment thread src/PS1/PS1RSD_test.cpp
Use QTemporaryDir nested paths for open-failure tests, close PLY file before import,
and assert MAT round-trip entry count before indexing.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

Copy link
Copy Markdown

@fernandotonon
fernandotonon merged commit 82a74da into master May 16, 2026
20 checks passed
@fernandotonon
fernandotonon deleted the test/ps1-full-coverage branch May 16, 2026 15:37
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