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.

219 lines
6.8KB

  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, const String& ctg)
  51. : Thread ("Unit Tests"),
  52. owner (utd),
  53. category (ctg)
  54. {
  55. }
  56. void run() override
  57. {
  58. CustomTestRunner runner (*this);
  59. if (category == "All Tests")
  60. runner.runAllTests();
  61. else
  62. runner.runTestsInCategory (category);
  63. startTimer (50); // when finished, start the timer which will
  64. // wait for the thread to end, then tell our component.
  65. }
  66. void logMessage (const String& message)
  67. {
  68. MessageManagerLock mm (this);
  69. if (mm.lockWasGained()) // this lock may fail if this thread has been told to stop
  70. owner.logMessage (message);
  71. }
  72. void timerCallback() override
  73. {
  74. if (! isThreadRunning())
  75. owner.testFinished(); // inform the demo page when done, so it can delete this thread.
  76. }
  77. private:
  78. UnitTestsDemo& owner;
  79. const String category;
  80. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TestRunnerThread)
  81. };
  82. //==============================================================================
  83. class UnitTestsDemo : public Component,
  84. public Button::Listener
  85. {
  86. public:
  87. UnitTestsDemo()
  88. : startTestButton ("Run Unit Tests...")
  89. {
  90. setOpaque (true);
  91. addAndMakeVisible (startTestButton);
  92. startTestButton.addListener (this);
  93. addAndMakeVisible (testResultsBox);
  94. testResultsBox.setMultiLine (true);
  95. testResultsBox.setFont (Font (Font::getDefaultMonospacedFontName(), 12.0f, Font::plain));
  96. addAndMakeVisible (categoriesBox);
  97. categoriesBox.addItem ("All Tests", 1);
  98. auto categories = UnitTest::getAllCategories();
  99. categories.sort (true);
  100. categoriesBox.addItemList (categories, 2);
  101. categoriesBox.setSelectedId (1);
  102. logMessage ("This panel runs the built-in JUCE unit-tests from the selected category.\n");
  103. logMessage ("To add your own unit-tests, see the JUCE_UNIT_TESTS macro.");
  104. }
  105. ~UnitTestsDemo()
  106. {
  107. stopTest();
  108. }
  109. //==============================================================================
  110. void paint (Graphics& g) override
  111. {
  112. g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,
  113. Colours::grey));
  114. }
  115. void resized() override
  116. {
  117. auto bounds = getLocalBounds().reduced (6);
  118. auto topSlice = bounds.removeFromTop (25);
  119. startTestButton.setBounds (topSlice.removeFromLeft (200));
  120. topSlice.removeFromLeft (10);
  121. categoriesBox.setBounds (topSlice.removeFromLeft (250));
  122. bounds.removeFromTop (5);
  123. testResultsBox.setBounds (bounds);
  124. }
  125. void buttonClicked (Button* buttonThatWasClicked) override
  126. {
  127. if (buttonThatWasClicked == &startTestButton)
  128. startTest (categoriesBox.getText());
  129. }
  130. void startTest (const String& category)
  131. {
  132. testResultsBox.clear();
  133. startTestButton.setEnabled (false);
  134. currentTestThread = new TestRunnerThread (*this, category);
  135. currentTestThread->startThread();
  136. }
  137. void stopTest()
  138. {
  139. if (currentTestThread != nullptr)
  140. {
  141. currentTestThread->stopThread (15000);
  142. currentTestThread = nullptr;
  143. }
  144. }
  145. void logMessage (const String& message)
  146. {
  147. testResultsBox.moveCaretToEnd();
  148. testResultsBox.insertTextAtCaret (message + newLine);
  149. testResultsBox.moveCaretToEnd();
  150. }
  151. void testFinished()
  152. {
  153. stopTest();
  154. startTestButton.setEnabled (true);
  155. logMessage (newLine + "*** Tests finished ***");
  156. }
  157. private:
  158. ScopedPointer<TestRunnerThread> currentTestThread;
  159. TextButton startTestButton;
  160. ComboBox categoriesBox;
  161. TextEditor testResultsBox;
  162. void lookAndFeelChanged() override
  163. {
  164. testResultsBox.applyFontToAllText (testResultsBox.getFont());
  165. }
  166. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnitTestsDemo)
  167. };
  168. };
  169. // This static object will register this demo type in a global list of demos..
  170. static JuceDemoType<UnitTestClasses::UnitTestsDemo> demo ("40 Unit Tests");