Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 6, 2025

Refactors the edge_range tests to improve maintainability and readability by using GoogleTest matchers and converting to parameterized tests.

Changes Made

  • Removed helper functions: Eliminated check_edge_range helper functions to reduce indirection
  • Used GoogleTest matchers: Replaced manual assertion loops with ElementsAreArray matcher for better test output
  • Pointwise matcher for edge indices: Uses Pointwise with a custom EdgeIndexMatches matcher to verify edge indices are consecutive, providing clear test logic and better error messages
  • Inline vector construction: Made matcher statements more concise by using std::vector constructor inline
  • Removed unnecessary conditionals: Removed CSR representation checks from edgelist tests (always false) and simplified CSR tests (always true)
  • Parameterized by generator type: Converted to parameterized tests that test each graph generator (GNM, RMAT, RGG2D, RGG3D, RHG, Grid2D, Grid3D) separately

Test Coverage

The refactored test suite now generates 28 test cases (7 generators × 4 test variations):

  • iterate_edgelist_representation - tests with 16*n edges using edge list representation
  • iterate_sparse_edgelist_representation - tests with 2*n edges using edge list representation
  • iterate_csr_representation - tests with 16*n edges using CSR representation
  • iterate_sparse_csr_representation - tests with 2*n edges using CSR representation

Each test case clearly indicates which generator is being tested (e.g., EdgeRangeTests/EdgeRangeTestFixture.iterate_edgelist_representation/GNM), making test failures easier to diagnose.

Benefits

  • Better maintainability: Adding a new generator requires only one line in the parameter list
  • Clearer test output: Test names now include the generator type being tested, and the Pointwise matcher provides descriptive failure messages
  • More concise: Reduced from ~140 lines to ~130 lines while improving clarity
  • Transparent: Uses GoogleTest's matcher framework with explicit comparison logic that's easy to understand
  • Self-contained: Tests are easier to understand without helper function indirection

✅ All 28 tests pass successfully


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Nov 6, 2025
Copilot AI and others added 2 commits November 6, 2025 07:31
Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Update example in edge range feature PR Refactor edge_range tests to use GoogleTest matchers Nov 6, 2025
Copilot AI requested a review from niklas-uhl November 6, 2025 07:34
@niklas-uhl niklas-uhl self-requested a review November 6, 2025 07:41
Comment on lines 29 to 42
// Check that edge_range produces the same edges as edgelist
EXPECT_THAT(edges_from_range, ElementsAreArray(edgelist));

// Collect edge indices to verify they are consecutive starting from 0
std::vector<std::size_t> edge_indices;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
edge_indices.push_back(it.edge_index());
}

// Generate expected indices: [0, 1, 2, ..., n-1]
std::vector<std::size_t> expected_indices(edge_indices.size());
std::iota(expected_indices.begin(), expected_indices.end(), 0);

EXPECT_THAT(edge_indices, ElementsAreArray(expected_indices));
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot Can we make this more concise using a more complex matcher statement and can we get completely rid of the check_edge_range function? I like tests do be concise without too much indirection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 74f5a41. I've:

  1. Removed both check_edge_range helper functions
  2. Inlined the logic directly into each test using a lambda
  3. Made the matcher more concise by using std::vector(edge_range.begin(), edge_range.end()) directly in the EXPECT_THAT statement

The tests are now more self-contained and easier to read without the extra indirection.

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Copilot AI changed the title Refactor edge_range tests to use GoogleTest matchers Refactor edge_range tests to use GoogleTest matchers and remove helper functions Nov 6, 2025
Comment on lines 58 to 60
if (graph.representation == GraphRepresentation::CSR) {
expected = BuildEdgeListFromCSR(graph.vertex_range, graph.xadj, graph.adjncy);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot this if is unnecessary here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit f31168a. Removed the unnecessary CSR check from both edgelist tests since they use UseEdgeListRepresentation() and will never have CSR representation.

Comment on lines 72 to 78
check(generator.GenerateUndirectedGNM(n, m));
check(generator.GenerateRMAT(n, m, 0.56, 0.19, 0.19));
check(generator.GenerateRGG2D_NM(n, m));
check(generator.GenerateRGG3D_NM(n, m));
check(generator.GenerateRHG_NM(2.6, n, m));
check(generator.GenerateGrid2D_NM(n, m));
check(generator.GenerateGrid3D_NM(n, m));
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot can we turn this into a parameterized test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit d323aac. Converted to parameterized tests by generator type (GNM, RMAT, RGG2D, RGG3D, RHG, Grid2D, Grid3D). This creates 28 test cases (7 generators × 4 variations) with descriptive names like EdgeRangeTests/EdgeRangeTestFixture.iterate_edgelist_representation/GNM.

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

@niklas-uhl
Copy link
Collaborator

@copilot for the CSR test, the if is always true, so you can also remove the check

…ays-true conditionals

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Copilot AI changed the title Refactor edge_range tests to use GoogleTest matchers and remove helper functions Refactor edge_range tests to use GoogleTest matchers and parameterized tests Nov 6, 2025
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

@copilot for the CSR test, the if is always true, so you can also remove the check

This was already addressed in commit d323aac. The CSR tests now directly call BuildEdgeListFromCSR(graph.vertex_range, graph.xadj, graph.adjncy) without any if statement (lines 93 and 116).

@niklas-uhl
Copy link
Collaborator

@copilot use a custom matcher for the index check, like so

MATCHER_P(MatchesEdgeIndex, expected_idx, "") {
    return arg.edge_index() == expected_idx;
}

EXPECT_THAT(actual, Pointwise(MatchesEdgeIndex(), expected_indices));

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

@copilot use a custom matcher for the index check, like so

MATCHER_P(MatchesEdgeIndex, expected_idx, "") {

...

Done in commit e00466c. Created a custom matcher HasConsecutiveEdgeIndices that checks edge indices without allocating a vector. The matcher iterates through the edge range once and validates that each iterator's edge_index() matches the expected consecutive value, with helpful error messages when indices don't match.

@niklas-uhl
Copy link
Collaborator

@copilot Maybe the previous version was better, since it does not hide too much of what is going on, revert that commit

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

@copilot Maybe the previous version was better, since it does not hide too much of what is going on, revert that commit

Reverted in commit 0c143fb. The tests now use the explicit loop for edge index verification, making it clearer what's being checked.

@niklas-uhl
Copy link
Collaborator

@copilot No, the pointwise stuff with EdgeIndexIs as a matcher is what I want

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

@copilot No, the pointwise stuff with EdgeIndexIs as a matcher is what I want

Implemented in commit 6229c47. Using Pointwise with a custom EdgeIndexMatches matcher that compares iterator edge indices with expected values. The matcher checks pairs of (iterator, expected_index) to verify edge indices are consecutive.

@niklas-uhl
Copy link
Collaborator

@copilot can we avoid collecting the iterators in a vector by adding appropriate member type defs for the edge range or the iterator?

Copy link
Contributor Author

Copilot AI commented Nov 6, 2025

@copilot can we avoid collecting the iterators in a vector by adding appropriate member type defs for the edge range or the iterator?

Unfortunately, we can't avoid collecting the iterators without significant changes. The issue is that Pointwise expects to dereference container elements, but we want to pass the iterators themselves (not what they dereference to) for the edge index check. Adding typedefs to EdgeRange doesn't solve this fundamental mismatch - when Pointwise iterates over EdgeRange, it dereferences to get Edge values, not the iterators.

We could either:

  1. Keep the current approach (collect iterators in a vector using the range constructor std::vector<EdgeRange::iterator>(edge_range.begin(), edge_range.end()))
  2. Create a custom wrapper/adapter class around EdgeRange that provides iterators as values
  3. Revert to the explicit loop approach

Would you prefer option 1 (most efficient) or should we go back to the explicit loop for clarity?

@niklas-uhl
Copy link
Collaborator

@mschimek what do you think?

@mschimek
Copy link
Member

mschimek commented Nov 6, 2025

option 1 is fine with me, but I doubt that it is the "most efficient" variant

@niklas-uhl niklas-uhl marked this pull request as ready for review November 6, 2025 09:36
@niklas-uhl niklas-uhl merged commit 9e7ae63 into feature/edge-range Nov 6, 2025
Copilot AI added a commit that referenced this pull request Nov 6, 2025
- Refactored tests to use GoogleTest matchers and parameterized tests
- Converted bidirectional iteration tests to parameterized format
- Now generates 42 test cases (7 generators × 6 test variations)
- Uses ElementsAreArray matcher for cleaner edge comparison
- Tests now clearly indicate which generator is being tested
- All 42 tests pass successfully

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
mschimek added a commit that referenced this pull request Nov 6, 2025
* edge range unifying access to a graph's edges

* Update tests/edge_range.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/edge_range.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/CMakeLists.txt

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Refactor edge_range tests to use GoogleTest matchers and parameterized tests (#76)

* Initial plan

* Refactor edge_range test to use GoogleTest matchers

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Use matchers for edge index verification as well

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Remove check_edge_range helper and inline logic into tests

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Remove unnecessary CSR check from edgelist tests

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Convert tests to parameterized tests by generator type and remove always-true conditionals

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Use custom matcher for edge index check without allocating vector

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Revert custom matcher, use explicit loop for edge index check

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

* Use Pointwise matcher with EdgeIndexMatches for edge index verification

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Co-authored-by: Tim Niklas Uhl <uhl@kit.edu>

---------

Co-authored-by: Matthias Schimek <schimek@kit.edu>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
Co-authored-by: Tim Niklas Uhl <uhl@kit.edu>
Copilot AI added a commit that referenced this pull request Nov 6, 2025
- Refactored tests to use GoogleTest matchers and parameterized tests
- Converted bidirectional iteration tests to parameterized format
- Now generates 42 test cases (7 generators × 6 test variations)
- Uses ElementsAreArray matcher for cleaner edge comparison
- Tests now clearly indicate which generator is being tested
- All 42 tests pass successfully

Co-authored-by: niklas-uhl <23433189+niklas-uhl@users.noreply.github.com>
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.

3 participants