The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "../JuceDemoHeader.h"
  20. struct UnitTestClasses
  21. {
  22. class UnitTestsDemo;
  23. class TestRunnerThread;
  24. //==============================================================================
  25. // This subclass of UnitTestRunner is used to redirect the test output to our
  26. // TextBox, and to interrupt the running tests when our thread is asked to stop..
  27. class CustomTestRunner : public UnitTestRunner
  28. {
  29. public:
  30. CustomTestRunner (TestRunnerThread& trt) : owner (trt)
  31. {
  32. }
  33. void logMessage (const String& message) override
  34. {
  35. owner.logMessage (message);
  36. }
  37. bool shouldAbortTests() override
  38. {
  39. return owner.threadShouldExit();
  40. }
  41. private:
  42. TestRunnerThread& owner;
  43. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomTestRunner)
  44. };
  45. //==============================================================================
  46. class TestRunnerThread : public Thread,
  47. private Timer
  48. {
  49. public:
  50. TestRunnerThread (UnitTestsDemo& utd)
  51. : Thread ("Unit Tests"),
  52. owner (utd)
  53. {
  54. }
  55. void run() override
  56. {
  57. CustomTestRunner runner (*this);
  58. runner.runAllTests();
  59. startTimer (50); // when finished, start the timer which will
  60. // wait for the thread to end, then tell our component.
  61. }
  62. void logMessage (const String& message)
  63. {
  64. MessageManagerLock mm (this);
  65. if (mm.lockWasGained()) // this lock may fail if this thread has been told to stop
  66. owner.logMessage (message);
  67. }
  68. void timerCallback() override
  69. {
  70. if (! isThreadRunning())
  71. owner.testFinished(); // inform the demo page when done, so it can delete this thread.
  72. }
  73. private:
  74. UnitTestsDemo& owner;
  75. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TestRunnerThread)
  76. };
  77. //==============================================================================
  78. class UnitTestsDemo : public Component,
  79. public Button::Listener
  80. {
  81. public:
  82. UnitTestsDemo()
  83. : startTestButton ("Run Unit Tests...")
  84. {
  85. setOpaque (true);
  86. addAndMakeVisible (startTestButton);
  87. addAndMakeVisible (testResultsBox);
  88. testResultsBox.setMultiLine (true);
  89. testResultsBox.setFont (Font (Font::getDefaultMonospacedFontName(), 12.0f, Font::plain));
  90. startTestButton.addListener (this);
  91. logMessage ("This panel runs all the built-in JUCE unit-tests.\n");
  92. logMessage ("To add your own unit-tests, see the JUCE_UNIT_TESTS macro.");
  93. }
  94. ~UnitTestsDemo()
  95. {
  96. stopTest();
  97. }
  98. //==============================================================================
  99. void paint (Graphics& g) override
  100. {
  101. g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,
  102. Colours::grey));
  103. }
  104. void resized() override
  105. {
  106. Rectangle<int> r (getLocalBounds().reduced (6));
  107. startTestButton.setBounds (r.removeFromTop (25).removeFromLeft (200));
  108. testResultsBox.setBounds (r.withTrimmedTop (5));
  109. }
  110. void buttonClicked (Button* buttonThatWasClicked) override
  111. {
  112. if (buttonThatWasClicked == &startTestButton)
  113. {
  114. startTest();
  115. }
  116. }
  117. void startTest()
  118. {
  119. testResultsBox.clear();
  120. startTestButton.setEnabled (false);
  121. currentTestThread = new TestRunnerThread (*this);
  122. currentTestThread->startThread();
  123. }
  124. void stopTest()
  125. {
  126. if (currentTestThread != nullptr)
  127. {
  128. currentTestThread->stopThread (15000);
  129. currentTestThread = nullptr;
  130. }
  131. }
  132. void logMessage (const String& message)
  133. {
  134. testResultsBox.moveCaretToEnd();
  135. testResultsBox.insertTextAtCaret (message + newLine);
  136. testResultsBox.moveCaretToEnd();
  137. }
  138. void testFinished()
  139. {
  140. stopTest();
  141. startTestButton.setEnabled (true);
  142. logMessage (newLine + "*** Tests finished ***");
  143. }
  144. private:
  145. ScopedPointer<TestRunnerThread> currentTestThread;
  146. TextButton startTestButton;
  147. TextEditor testResultsBox;
  148. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnitTestsDemo)
  149. };
  150. };
  151. // This static object will register this demo type in a global list of demos..
  152. static JuceDemoType<UnitTestClasses::UnitTestsDemo> demo ("40 Unit Tests");