mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-08 23:24:19 +00:00
Component: Add some basic unit tests
This commit is contained in:
parent
961ff32b9e
commit
5ec4d85d82
1 changed files with 532 additions and 0 deletions
|
|
@ -3205,4 +3205,536 @@ AccessibilityHandler* Component::getAccessibilityHandler()
|
|||
return accessibilityHandler.get();
|
||||
}
|
||||
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct ComponentTests : public UnitTest
|
||||
{
|
||||
ComponentTests()
|
||||
: UnitTest ("Component", UnitTestCategories::gui)
|
||||
{
|
||||
}
|
||||
|
||||
struct TestComponent : Component
|
||||
{
|
||||
void paint (Graphics& g) final
|
||||
{
|
||||
lastClipBounds = g.getClipBounds();
|
||||
++numPaintCalls;
|
||||
}
|
||||
|
||||
int numPaintCalls = 0;
|
||||
Rectangle<int> lastClipBounds;
|
||||
};
|
||||
|
||||
void paintComponentBounds (Component& componentToRepaint)
|
||||
{
|
||||
auto* topLevelComponent = componentToRepaint.getTopLevelComponent();
|
||||
topLevelComponent->createComponentSnapshot (topLevelComponent->getLocalArea (&componentToRepaint, componentToRepaint.getLocalBounds()));
|
||||
}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
ScopedJuceInitialiser_GUI libraryInitialiser;
|
||||
|
||||
beginTest ("Painting a parents bounds paints both parent and child");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child->numPaintCalls, 0);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Non-opaque children require their parent to repaint");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*child);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Opaque children don't require their parent to repaint");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
child->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*child);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Opaque children don't require their parent to repaint (even when the parent uses setPaintingIsUnclipped (true))");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setPaintingIsUnclipped (true);
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
child->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*child);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("A partially obscured parent will repaint with reduced clip bounds");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.removeFromTop (50));
|
||||
child->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
|
||||
expect (parent->lastClipBounds == bounds);
|
||||
}
|
||||
|
||||
beginTest ("A totally obscured parent will never repaint");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds.removeFromTop (50));
|
||||
child1->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child2);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child1->numPaintCalls, 1);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("An opaque component will hide sibling components behind it");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
const auto child3 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child2);
|
||||
|
||||
child3->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child3);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child1->numPaintCalls, 0);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
expectEquals (child3->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("An opaque component will hide parent-sibling components behind it");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
const auto child3 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child2);
|
||||
|
||||
child3->setBounds (bounds);
|
||||
child3->setOpaque (true);
|
||||
child2->addAndMakeVisible (*child3);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child1->numPaintCalls, 0);
|
||||
expectEquals (child2->numPaintCalls, 0);
|
||||
expectEquals (child3->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("An opaque component will reduce the clip bounds of sibling components behind it");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
const auto child3 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds.removeFromTop (50));
|
||||
child2->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child2);
|
||||
|
||||
child3->setBounds (child1->getBounds());
|
||||
parent->addAndMakeVisible (*child3);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child1->numPaintCalls, 1);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
expectEquals (child3->numPaintCalls, 1);
|
||||
|
||||
expect (child1->lastClipBounds == bounds);
|
||||
expect (child3->lastClipBounds == child3->getBounds());
|
||||
}
|
||||
|
||||
beginTest ("A child component will be clipped when painted");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
expect (parent->lastClipBounds.isEmpty());
|
||||
expect (child->lastClipBounds.isEmpty());
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expect (parent->lastClipBounds == parent->getLocalBounds());
|
||||
expect (child->lastClipBounds == child->getLocalBounds());
|
||||
}
|
||||
|
||||
beginTest ("setPaintingIsUnclipped (true) will cause a child to have its parents clip bounds");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.reduced (25));
|
||||
child->setPaintingIsUnclipped (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expect (child->lastClipBounds == child->getLocalArea (parent.get(), parent->getLocalBounds()));
|
||||
}
|
||||
|
||||
beginTest ("Opaque components hide parents that use setPaintingIsUnclipped (true)");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
parent->setPaintingIsUnclipped (true);
|
||||
|
||||
child->setBounds (bounds);
|
||||
child->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Opaque components hide parents that use setPaintingIsUnclipped (true)");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
parent->setPaintingIsUnclipped (true);
|
||||
|
||||
child->setBounds (bounds);
|
||||
child->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Invisible child components will not be considered opaque");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds);
|
||||
child->setOpaque (true);
|
||||
parent->addChildComponent (*child);
|
||||
|
||||
expect (! child->isVisible());
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 0);
|
||||
}
|
||||
|
||||
beginTest ("Invisible sibling components will not be considered opaque");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
parent->addChildComponent (*child2);
|
||||
|
||||
expect ( child1->isVisible());
|
||||
expect (! child2->isVisible());
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (child1->numPaintCalls, 1);
|
||||
expectEquals (child2->numPaintCalls, 0);
|
||||
}
|
||||
|
||||
beginTest ("Components with an invisible parent will not be considered opaque");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
const auto grandchild = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds);
|
||||
parent->addChildComponent (*child);
|
||||
|
||||
grandchild->setBounds (bounds);
|
||||
grandchild->setOpaque (true);
|
||||
child->addAndMakeVisible (*grandchild);
|
||||
|
||||
expect (! child->isVisible());
|
||||
expect (grandchild->isVisible());
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 0);
|
||||
expectEquals (grandchild->numPaintCalls, 0);
|
||||
}
|
||||
|
||||
beginTest ("Components with a width of 0 will not have their paint function called");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.withWidth (0));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 0);
|
||||
}
|
||||
|
||||
beginTest ("Components with a height of 0 will not have their paint function called");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds.withHeight (0));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 0);
|
||||
}
|
||||
|
||||
beginTest ("Transparent components will not be considered opaque");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds);
|
||||
child->setOpaque (true);
|
||||
child->setAlpha (0.5f);
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Opaque components will only be considered opaque up to a transparent parent");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
child1->setAlpha (0.5f);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
child1->addAndMakeVisible (*child2);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child1->numPaintCalls, 0);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Transformed components will not be considered opaque");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child->setBounds (bounds);
|
||||
child->setOpaque (true);
|
||||
child->setTransform (AffineTransform::rotation (degreesToRadians (45.0f)));
|
||||
parent->addAndMakeVisible (*child);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Opaque components will only be considered opaque up to a transformed parent");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
child1->setTransform (AffineTransform::rotation (degreesToRadians (45.0f)));
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
child1->addAndMakeVisible (*child2);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 1);
|
||||
expectEquals (child1->numPaintCalls, 0);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
}
|
||||
|
||||
beginTest ("Nested opaque components prevent parents from being painted");
|
||||
{
|
||||
const auto parent = std::make_unique<TestComponent>();
|
||||
const auto child1 = std::make_unique<TestComponent>();
|
||||
const auto child2 = std::make_unique<TestComponent>();
|
||||
|
||||
Rectangle<int> bounds { 0, 0, 100, 100 };
|
||||
parent->setBounds (bounds);
|
||||
|
||||
child1->setBounds (bounds);
|
||||
child1->setOpaque (true);
|
||||
parent->addAndMakeVisible (*child1);
|
||||
|
||||
child2->setBounds (bounds);
|
||||
child2->setOpaque (true);
|
||||
child1->addAndMakeVisible (*child2);
|
||||
|
||||
paintComponentBounds (*parent);
|
||||
|
||||
expectEquals (parent->numPaintCalls, 0);
|
||||
expectEquals (child1->numPaintCalls, 0);
|
||||
expectEquals (child2->numPaintCalls, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ComponentTests componentTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue