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.

192 lines
5.8KB

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