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.

216 lines
6.6KB

  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. {
  85. public:
  86. UnitTestsDemo()
  87. {
  88. setOpaque (true);
  89. addAndMakeVisible (startTestButton);
  90. startTestButton.onClick = [this] { start(); };
  91. addAndMakeVisible (testResultsBox);
  92. testResultsBox.setMultiLine (true);
  93. testResultsBox.setFont (Font (Font::getDefaultMonospacedFontName(), 12.0f, Font::plain));
  94. addAndMakeVisible (categoriesBox);
  95. categoriesBox.addItem ("All Tests", 1);
  96. auto categories = UnitTest::getAllCategories();
  97. categories.sort (true);
  98. categoriesBox.addItemList (categories, 2);
  99. categoriesBox.setSelectedId (1);
  100. logMessage ("This panel runs the built-in JUCE unit-tests from the selected category.\n");
  101. logMessage ("To add your own unit-tests, see the JUCE_UNIT_TESTS macro.");
  102. }
  103. ~UnitTestsDemo()
  104. {
  105. stopTest();
  106. }
  107. //==============================================================================
  108. void paint (Graphics& g) override
  109. {
  110. g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,
  111. Colours::grey));
  112. }
  113. void resized() override
  114. {
  115. auto bounds = getLocalBounds().reduced (6);
  116. auto topSlice = bounds.removeFromTop (25);
  117. startTestButton.setBounds (topSlice.removeFromLeft (200));
  118. topSlice.removeFromLeft (10);
  119. categoriesBox.setBounds (topSlice.removeFromLeft (250));
  120. bounds.removeFromTop (5);
  121. testResultsBox.setBounds (bounds);
  122. }
  123. void start()
  124. {
  125. startTest (categoriesBox.getText());
  126. }
  127. void startTest (const String& category)
  128. {
  129. testResultsBox.clear();
  130. startTestButton.setEnabled (false);
  131. currentTestThread = new TestRunnerThread (*this, category);
  132. currentTestThread->startThread();
  133. }
  134. void stopTest()
  135. {
  136. if (currentTestThread != nullptr)
  137. {
  138. currentTestThread->stopThread (15000);
  139. currentTestThread.reset();
  140. }
  141. }
  142. void logMessage (const String& message)
  143. {
  144. testResultsBox.moveCaretToEnd();
  145. testResultsBox.insertTextAtCaret (message + newLine);
  146. testResultsBox.moveCaretToEnd();
  147. }
  148. void testFinished()
  149. {
  150. stopTest();
  151. startTestButton.setEnabled (true);
  152. logMessage (newLine + "*** Tests finished ***");
  153. }
  154. private:
  155. ScopedPointer<TestRunnerThread> currentTestThread;
  156. TextButton startTestButton { "Run Unit Tests..." };
  157. ComboBox categoriesBox;
  158. TextEditor testResultsBox;
  159. void lookAndFeelChanged() override
  160. {
  161. testResultsBox.applyFontToAllText (testResultsBox.getFont());
  162. }
  163. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnitTestsDemo)
  164. };
  165. };
  166. // This static object will register this demo type in a global list of demos..
  167. static JuceDemoType<UnitTestClasses::UnitTestsDemo> demo ("40 Unit Tests");