Generate C++ test cases

Validate the behavior of a C++ class using varied assertions

You can query a model directly and test the results returned when using different parameter values with the Cloud console, or by calling the Vertex AI API directly.

System instructions

You are a unit testing expert adept at identifying and covering edge cases. You only respond with the requested test code and no additional explanation.

Prompt Freeform

Create tests for the RegionTree class in the form of a main function containing assertions. The class should allow bounding boxes to be added if they do not intersect any other box currently in the tree. Label each test with a descriptive comment and the expected behavior.

// RegionTree.hpp

#include <vector>
#include <cassert>
#include <iostream>

class Bounds {
public:
Bounds(int left, int top, int right, int bottom)
: left_{left}
, right_{right}
, top_{top}
, bottom_{bottom} {
assert(right >= left);
assert(bottom >= top);
}

bool operator==(Bounds const& rhs) const {
return left_ == rhs.left_ && right_ == rhs.right_ && top_ == rhs.top_ && bottom_ == rhs.bottom_;
}

int left() const { return left_; }
int right() const { return right_; }
int top() const { return top_; }
int bottom() const { return bottom_; }

int width() const { return right_ - left_; }
int height() const { return bottom_ - top_; }

private:
int left_;
int right_;
int top_;
int bottom_;
};

bool intersects(Bounds const& a, Bounds const& b) {
return !(a.left() > b.right() || a.right() < b.left() || a.top() > b.bottom() || a.bottom() < b.top());
}

bool contains(Bounds const& a, Bounds const& b) {
return a.left() >= b.left() && a.right() <= b.right() && a.top() >= b.top() && a.bottom() <= b.bottom();
}


class RegionTree {
private:
static constexpr int MinSize = 8;

Bounds bounds_;
std::vector<Bounds> items_;
std::vector<RegionTree> subregions_;

bool canInsert(Bounds const& bounds) const {
for (RegionTree const& subregion : subregions_) {
if (intersects(subregion.bounds_, bounds) && !subregion.canInsert(bounds)) {
return false;
}
}
for (Bounds const& item : items_) {
if (intersects(item, bounds)) {
return false;
}
}
return true;
}

bool addImpl(Bounds const& bounds) {
if (!canInsert(bounds)) {
return false;
}
if (subregions_.empty()) {
items_.push_back(bounds);
} else {
for (RegionTree& subregion : subregions_) {
if (intersects(subregion.bounds_, bounds)) {
assert(subregion.addImpl(bounds));
}
}
}
return true;
}

public:
RegionTree(Bounds const& bounds)
: bounds_{bounds}
, items_{}
, subregions_{} {
if (bounds_.width() > MinSize || bounds_.height() > MinSize) {
int westWidth = bounds_.width() - bounds_.width() / 2;
int northHeight = bounds_.height() - bounds_.height() / 2;

subregions_.push_back(Bounds{bounds_.left(), bounds_.top(), bounds_.left() + westWidth, bounds_.top() + northHeight});
subregions_.push_back(Bounds{bounds_.left() + westWidth, bounds_.top(), bounds_.right(), bounds_.top() + northHeight});
subregions_.push_back(Bounds{bounds_.left(), bounds_.top() + northHeight, bounds_.left() + westWidth, bounds_.bottom()});
subregions_.push_back(Bounds{bounds_.left() + westWidth, bounds_.top() + northHeight, bounds_.right(), bounds_.bottom()});
}
}

bool add(Bounds const& bounds) {
if (!contains(bounds, bounds_)) {
return false;
}
return addImpl(bounds);
}

void remove(Bounds const& bounds) {
if (!intersects(bounds_, bounds)) {
return;
}
if (subregions_.empty()) {
auto it = std::find(items_.begin(), items_.end(), bounds);
if (it != items_.end()) {
items_.erase(it);
}
} else {
for (RegionTree& subregion : subregions_) {
subregion.remove(bounds);
}
}
}
};

Response

#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm> // For std::find

class Bounds {
public:
Bounds(int left, int top, int right, int bottom)
: left_{left}
, right_{right}
, top_{top}
, bottom_{bottom} {
assert(right >= left);
assert(bottom >= top);
}

bool operator==(Bounds const& rhs) const {
return left_ == rhs.left_ && right_ == rhs.right_ && top_ == rhs.top_ && bottom_ == rhs.bottom_;
}

int left() const { return left_; }
int right() const { return right_; }
int top() const { return top_; }
int bottom() const { return bottom_; }

int width() const { return right_ - left_; }
int height() const { return bottom_ - top_; }

private:
int left_;
int right_;
int top_;
int bottom_;
};

bool intersects(Bounds const& a, Bounds const& b) {
return !(a.left() > b.right() || a.right() < b.left() || a.top() > b.bottom() || a.bottom() < b.top());
}

bool contains(Bounds const& a, Bounds const& b) {
return a.left() >= b.left() && a.right() <= b.right() && a.top() >= b.top() && a.bottom() <= b.bottom();
}


class RegionTree {
private:
static constexpr int MinSize = 8;

Bounds bounds_;
std::vector<Bounds> items_;
std::vector<RegionTree> subregions_;

bool canInsert(Bounds const& bounds) const {
for (RegionTree const& subregion : subregions_) {
if (intersects(subregion.bounds_, bounds) && !subregion.canInsert(bounds)) {
return false;
}
}
for (Bounds const& item : items_) {
if (intersects(item, bounds)) {
return false;
}
}
return true;
}

bool addImpl(Bounds const& bounds) {
if (!canInsert(bounds)) {
return false;
}
if (subregions_.empty()) {
items_.push_back(bounds);
} else {
for (RegionTree& subregion : subregions_) {
if (intersects(subregion.bounds_, bounds)) {
assert(subregion.addImpl(bounds));
}
}
}
return true;
}

public:
RegionTree(Bounds const& bounds)
: bounds_{bounds}
, items_{}
, subregions_{} {
if (bounds_.width() > MinSize || bounds_.height() > MinSize) {
int westWidth = bounds_.width() - bounds_.width() / 2;
int northHeight = bounds_.height() - bounds_.height() / 2;

subregions_.push_back(Bounds{bounds_.left(), bounds_.top(), bounds_.left() + westWidth, bounds_.top() + northHeight});
subregions_.push_back(Bounds{bounds_.left() + westWidth, bounds_.top(), bounds_.right(), bounds_.top() + northHeight});
subregions_.push_back(Bounds{bounds_.left(), bounds_.top() + northHeight, bounds_.left() + westWidth, bounds_.bottom()});
subregions_.push_back(Bounds{bounds_.left() + westWidth, bounds_.top() + northHeight, bounds_.right(), bounds_.bottom()});
}
}

bool add(Bounds const& bounds) {
if (!contains(bounds, bounds_)) {
return false;
}
return addImpl(bounds);
}

void remove(Bounds const& bounds) {
if (!intersects(bounds_, bounds)) {
return;
}
if (subregions_.empty()) {
auto it = std::find(items_.begin(), items_.end(), bounds);
if (it != items_.end()) {
items_.erase(it);
}
} else {
for (RegionTree& subregion : subregions_) {
subregion.remove(bounds);
}
}
}
};

int main() {
    // Test: Basic construction with bounds smaller than MinSize
    // Expected: No subregions are created, add succeeds.
    {
        RegionTree tree(Bounds{0, 0, 7, 7});
        assert(tree.add(Bounds{1, 1, 2, 2}));
    }

    // Test: Basic construction with bounds larger than MinSize
    // Expected: Subregions are created, add succeeds.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{49, 49, 51, 51}));
    }

    // Test: Add a single valid box
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
    }

    // Test: Add a box outside the tree's bounds
    // Expected: Add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(!tree.add(Bounds{110, 110, 120, 120}));
    }

    // Test: Add a box partially overlapping the tree's bounds
    // Expected: Add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(!tree.add(Bounds{90, 90, 110, 110}));
    }

    // Test: Add a box that is flush with the tree's boundary
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{0, 0, 10, 10}));
        assert(tree.add(Bounds{90, 90, 100, 100}));
    }

    // Test: Add two non-intersecting boxes
    // Expected: Both adds return true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(tree.add(Bounds{30, 30, 40, 40}));
    }

    // Test: Add a box that completely overlaps an existing box
    // Expected: Second add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{5, 5, 25, 25}));
    }

    // Test: Add a box that is completely contained within an existing box
    // Expected: Second add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{5, 5, 25, 25}));
        assert(!tree.add(Bounds{10, 10, 20, 20}));
    }

    // Test: Add a box that partially intersects an existing box
    // Expected: Second add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{15, 15, 25, 25}));
    }

    // Test: Add a box that shares an edge with an existing box (touching)
    // Expected: Second add returns false because touching is intersecting.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{20, 10, 30, 20}));
    }

    // Test: Add a box that shares a corner with an existing box (touching)
    // Expected: Second add returns false because touching is intersecting.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{20, 20, 30, 30}));
    }

    // Test: Add identical box twice
    // Expected: Second add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{10, 10, 20, 20}));
    }

    // Test: Add a box that spans multiple subregions without collision
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{40, 40, 60, 60}));
    }

    // Test: Add a box that spans subregions and collides with an existing box
    // Expected: Second add returns false.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(!tree.add(Bounds{15, 15, 55, 55}));
    }

    // Test: Add two non-intersecting boxes in different subregions
    // Expected: Both adds return true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 20}));
        assert(tree.add(Bounds{60, 60, 70, 70}));
    }

    // Test: Add zero-width box (a vertical line)
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 10, 20}));
    }

    // Test: Add zero-height box (a horizontal line)
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 20, 10}));
    }

    // Test: Add zero-size box (a point)
    // Expected: Add returns true.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 10, 10}));
    }

    // Test: Add a box that touches a zero-width box
    // Expected: Add returns false due to intersection.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        assert(tree.add(Bounds{10, 10, 10, 20}));
        assert(!tree.add(Bounds{10, 15, 15, 18}));
    }

    // Test: Basic remove
    // Expected: Box can be added again after being removed.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        Bounds b{10, 10, 20, 20};
        assert(tree.add(b));
        assert(!tree.add(b));
        tree.remove(b);
        assert(tree.add(b));
    }

    // Test: Remove a non-existent box
    // Expected: No change, no crash, existing box remains.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        Bounds b1{10, 10, 20, 20};
        Bounds b2{30, 30, 40, 40};
        assert(tree.add(b1));
        tree.remove(b2);
        assert(!tree.add(b1));
    }

    // Test: Remove a box that has already been removed
    // Expected: No change, no crash.
    {
        RegionTree tree(Bounds{0, 0, 100, 100});
        Bounds b{10, 10, 20, 20};
        assert(tree.add(b));
        


        
Model: gemini-2.5-pro
Temperature: 0.2
Max output tokens: 8192
TopK: 40.0
TopP: 0.95