Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 15, 2025

The Sheet class (model/sheet.h) had minimal test coverage - only a single instantiation in testTensorOps.cc. This PR adds focused unit tests covering meaningful functionality of the class's public API.

Changes

  • New test file: test/testSheet.cc with 9 focused test cases covering:

    • Hit testing (onResizeHandle, inItem, clickType, contains)
    • Scrolling with rank 3 tensor data (scrollUpDown with actual tensor data)
    • Keyboard input with rank 3 tensor data (onKeyPress verifying scrolling behavior)
    • Data operations (exportAsCSV error handling with unique temp files, setSliceIndicator with rank 3 tensor verification)
    • Construction (validates default constructor behavior)
  • Updated: test/Makefile to include testSheet.o in GTESTOBJS

Test Infrastructure

  • SetUp method initializes default dimensions for each test
  • TearDown method calls minsky::minsky().clearAllMaps() to clean up global state after each test, ensuring proper test isolation

Test Enhancements

Tests use rank 3 tensor data where appropriate to verify actual functionality:

  • scrollUpDown and onKeyPress tests create rank 3 tensors and verify scrolling behavior
  • setSliceIndicator test creates rank 3 tensor and verifies the slice indicator is populated
  • exportAsCSV test uses boost::filesystem::unique_path() for safe temporary file handling

Not covered

  • Private methods (ravelSize, ravelX, ravelY) - should not be tested directly
  • Rendering methods (draw, drawResizeHandles) - require Cairo context
  • computeValue - requires complex port/tensor setup, appropriate for integration tests
  • Trivial property getters/setters - not meaningful to test

Example test coverage

TEST_F(SheetTest, clickType)
{
  moveTo(100, 100);
  iWidth(200);
  iHeight(150);
  double z = zoomFactor();
  double w = 0.5 * 200 * z;
  double h = 0.5 * 150 * z;
  
  EXPECT_EQ(ClickType::onResize, clickType(100 + w, 100 + h));
  EXPECT_EQ(ClickType::inItem, clickType(100, 100));
  EXPECT_EQ(ClickType::onItem, clickType(100 + w * 0.9, 100 + h * 0.9));
  EXPECT_EQ(ClickType::outside, clickType(0, 0));
}
Original prompt

Improve code coverage on Sheet class, found in model/sheet.h


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


This change is Reviewable

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced scroll boundary validation to prevent inadvertent scrolling beyond valid range limits when scrolling in either direction.
  • Tests

    • Introduced comprehensive test coverage for sheet functionality, including resize operations, scrolling behavior, keyboard input, and data export capabilities.
    • Corrected test fixture tracking for accurate equation size measurement.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 15, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Changes add defensive guard conditions to Sheet scroll methods (scrollUp/scrollDown) to validate scroll delta and bounds before execution. A comprehensive GoogleTest suite for the Sheet class is introduced in test/testSheet.cc, the build configuration is updated to include the new test, and minor corrections are made to testMinsky.cc.

Changes

Cohort / File(s) Summary
Scroll Guard Conditions
model/sheet.cc
Added bounds-checking guards in scrollUp() and scrollDown() methods; scroll operations now only proceed when scrollDelta is non-zero and the resulting offset remains within valid range
Build Configuration
test/Makefile
Added testSheet.o to GTESTOBJS list to build new Sheet test suite
Test Suite Additions
test/testSheet.cc
New GoogleTest file with comprehensive Sheet class coverage: construction, resize handles, point containment, click types, scrolling behavior, keyboard input, CSV export, and slice indicator functionality
Test Corrections
test/testMinsky.cc
Updated comments and corrected eqSz assignment to use equations.size() instead of stockVars.size() for accurate equation tracking in test scenarios

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • model/sheet.cc: Straightforward defensive guard conditions; verify bounds logic is correct and consistent with Sheet state semantics
  • test/testSheet.cc: Extensive new test file requires verification that all test scenarios are valid, fixtures are properly initialized, and test assertions match intended Sheet behavior

Poem

🐰 Scrolling through sheets with careful bounds,
Guards in place on every scroll down,
Tests now woven, row by row,
Slicing tensors high and low! 📊✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add focused unit tests for Sheet class' directly and clearly describes the main change: introducing new unit tests for the Sheet class, which is confirmed by the new test/testSheet.cc file and updates to test/Makefile.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve code coverage for Sheet class in model/sheet.h Add comprehensive unit tests for Sheet class Nov 15, 2025
Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Copy link
Owner

@highperformancecoder highperformancecoder left a comment

Choose a reason for hiding this comment

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

@copilot please address review comments.

…s with rank 3 tensors, use unique temp files

Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Copilot AI changed the title Add comprehensive unit tests for Sheet class Add focused unit tests for Sheet class Nov 23, 2025
@highperformancecoder
Copy link
Owner

@CodeRabbit review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/testSheet.cc (1)

122-137: Good coverage of scrolling behavior with rank-3 tensors.

These tests effectively verify scrolling functionality and slice indicators with multi-dimensional data, addressing the requirements from previous review feedback. The tests correctly interact with the Sheet API and validate expected behavior.

Consider adding test cleanup to improve test isolation:

void TearDown() override
{
  minsky::minsky().model->clear();
  minsky::minsky().clearAllMaps();
}

This would prevent potential test interdependencies when tests modify the global minsky state.

Also applies to: 139-164, 173-186

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29392b2 and 62c71f8.

📒 Files selected for processing (4)
  • model/sheet.cc (2 hunks)
  • test/Makefile (1 hunks)
  • test/testMinsky.cc (3 hunks)
  • test/testSheet.cc (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-03T23:24:29.823Z
Learnt from: highperformancecoder
Repo: highperformancecoder/minsky PR: 566
File: test/testCSVParser.cc:154-156
Timestamp: 2025-10-03T23:24:29.823Z
Learning: The Minsky project's test suite is built with C++20 (`-std=c++20` in test/Makefile), so C++20 features like `std::string::starts_with`, `std::format`, ranges, concepts, etc., can be used in test code without compatibility concerns.

Applied to files:

  • test/testMinsky.cc
🧬 Code graph analysis (1)
test/testSheet.cc (1)
model/sheet.cc (14)
  • onResizeHandle (66-73)
  • onResizeHandle (66-66)
  • inItem (104-109)
  • inItem (104-104)
  • clickType (111-120)
  • clickType (111-111)
  • contains (128-131)
  • contains (128-128)
  • scrollUp (133-142)
  • scrollUp (133-133)
  • scrollDown (144-153)
  • scrollDown (144-144)
  • exportAsCSV (522-528)
  • exportAsCSV (522-522)
🪛 Clang (14.0.6)
test/testSheet.cc

[error] 19-19: 'sheet.h' file not found

(clang-diagnostic-error)


[error] 33-33: method 'SetUp' can be made static

(readability-convert-member-functions-to-static,-warnings-as-errors)


[error] 36-36: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 37-37: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 38-38: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 38-38: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 42-42: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 44-44: variable 'sheet' is not initialized

(cppcoreguidelines-init-variables,-warnings-as-errors)


[error] 50-50: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 52-52: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 52-52: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 53-53: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 54-54: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 55-55: variable name 'z' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 56-56: variable name 'w' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 56-56: 0.5 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 56-56: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 57-57: variable name 'h' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 57-57: 0.5 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 57-57: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 60-60: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 60-60: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 63-63: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 63-63: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 67-67: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 67-67: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 70-70: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 70-70: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 73-73: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 75-75: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 75-75: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 76-76: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 77-77: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 80-80: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 80-80: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 84-84: 300 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 84-84: 300 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 87-87: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 89-89: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 89-89: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 90-90: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 91-91: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 92-92: variable name 'z' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 93-93: variable name 'w' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 93-93: 0.5 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 93-93: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 94-94: variable name 'h' is too short, expected at least 3 characters

(readability-identifier-length,-warnings-as-errors)


[error] 94-94: 0.5 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 94-94: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 109-109: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 111-111: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 111-111: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 112-112: 200 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 113-113: 150 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 116-116: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 116-116: 100 is a magic number; consider replacing it with a named constant

(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers,-warnings-as-errors)


[error] 122-122: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 139-139: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 166-166: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)


[error] 169-169: variable 'tmpFile' is not initialized

(cppcoreguidelines-init-variables,-warnings-as-errors)


[error] 173-173: all parameters should be named in a function

(readability-named-parameter,-warnings-as-errors)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
🔇 Additional comments (6)
test/testMinsky.cc (1)

1755-1755: LGTM! Correct variable assignment.

The assignment eqSz=equations.size() properly captures the equations array size for later verification in the garbage collection test. This ensures the test correctly validates that garbage entries added to the equations array are properly cleaned up.

test/Makefile (1)

14-14: LGTM! Test object properly added to build.

The addition of testSheet.o to GTESTOBJS correctly integrates the new Sheet test suite into the build system.

model/sheet.cc (1)

135-136: LGTM! Improved bounds checking.

The added guards ensure scrolling only occurs when scrollDelta is non-zero and the resulting offset remains within valid bounds. This prevents edge cases where scrolling might occur with invalid state or produce out-of-bounds offsets.

Also applies to: 146-147

test/testSheet.cc (3)

42-120: LGTM! Well-structured basic functionality tests.

The construction and hit-testing tests provide good coverage of the Sheet class's geometric operations. The test fixture properly sets up consistent dimensions and positions, and each test validates expected behavior for coordinate-based operations.


166-171: LGTM! Error handling properly validated.

The test correctly verifies that exportAsCSV throws an exception when attempting to export without a value. The use of unique_path() follows the requested pattern from previous reviews.


28-40: LGTM! Well-designed test fixture.

The SheetTest fixture appropriately inherits from both Sheet and ::testing::Test, allowing tests to directly access Sheet members while integrating with GoogleTest. The SetUp() override properly initializes consistent test state.

@highperformancecoder
Copy link
Owner

@copilot - please add TearDown methods suggested by coderabbit. Calling clearAllMaps should suffice, as the first line of clearAllMaps calls model->clear() anyway.

Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 24, 2025

@copilot - please add TearDown methods suggested by coderabbit. Calling clearAllMaps should suffice, as the first line of clearAllMaps calls model->clear() anyway.

Added TearDown method that calls minsky::minsky().clearAllMaps() to clean up global state after each test. (commit f0da861)

@highperformancecoder highperformancecoder marked this pull request as ready for review November 24, 2025 07:03
Copilot AI review requested due to automatic review settings November 24, 2025 07:03
@highperformancecoder highperformancecoder merged commit 3176ee3 into master Nov 24, 2025
7 of 9 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive unit test coverage for the Sheet class, which previously had minimal testing. The changes include a new test file with 9 focused test cases, fixes for scroll boundary validation bugs, and minor corrections to existing test comments.

  • New test file test/testSheet.cc with 9 test cases covering hit testing, scrolling, keyboard input, data operations, and construction
  • Fixed scroll boundary validation bugs preventing proper scrolling when scrollDelta is zero
  • Enhanced setSliceIndicator() to return the slice indicator string
  • Corrected test fixture variable tracking in existing tests

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/testSheet.cc New comprehensive test suite for Sheet class covering public API methods with proper setup/teardown and tensor data
test/Makefile Added testSheet.o to GTESTOBJS for building the new test file
model/sheet.h Enhanced setSliceIndicator() signature to return const std::string& for testability
model/sheet.cc Fixed scrollUp/scrollDown boundary checks to prevent scrolling when scrollDelta is zero; updated setSliceIndicator() to return value
test/testMinsky.cc Corrected test fixture variable tracking (eqSz should use equations.size()) and improved comment clarity

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants