OpenShot Library | libopenshot-audio  0.2.0
juce_UnitTest.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 UnitTest::UnitTest (const String& nm, const String& ctg)
27  : name (nm), category (ctg)
28 {
29  getAllTests().add (this);
30 }
31 
33 {
34  getAllTests().removeFirstMatchingValue (this);
35 }
36 
38 {
39  static Array<UnitTest*> tests;
40  return tests;
41 }
42 
44 {
45  if (category.isEmpty())
46  return getAllTests();
47 
48  Array<UnitTest*> unitTests;
49 
50  for (auto* test : getAllTests())
51  if (test->getCategory() == category)
52  unitTests.add (test);
53 
54  return unitTests;
55 }
56 
58 {
59  StringArray categories;
60 
61  for (auto* test : getAllTests())
62  if (test->getCategory().isNotEmpty())
63  categories.addIfNotAlreadyThere (test->getCategory());
64 
65  return categories;
66 }
67 
70 
71 void UnitTest::performTest (UnitTestRunner* const newRunner)
72 {
73  jassert (newRunner != nullptr);
74  runner = newRunner;
75 
76  initialise();
77  runTest();
78  shutdown();
79 }
80 
81 void UnitTest::logMessage (const String& message)
82 {
83  // This method's only valid while the test is being run!
84  jassert (runner != nullptr);
85 
86  runner->logMessage (message);
87 }
88 
89 void UnitTest::beginTest (const String& testName)
90 {
91  // This method's only valid while the test is being run!
92  jassert (runner != nullptr);
93 
94  runner->beginNewTest (this, testName);
95 }
96 
97 void UnitTest::expect (const bool result, const String& failureMessage)
98 {
99  // This method's only valid while the test is being run!
100  jassert (runner != nullptr);
101 
102  if (result)
103  runner->addPass();
104  else
105  runner->addFail (failureMessage);
106 }
107 
109 {
110  // This method's only valid while the test is being run!
111  jassert (runner != nullptr);
112 
113  return runner->randomForTest;
114 }
115 
116 //==============================================================================
117 UnitTestRunner::UnitTestRunner() {}
119 
120 void UnitTestRunner::setAssertOnFailure (bool shouldAssert) noexcept
121 {
122  assertOnFailure = shouldAssert;
123 }
124 
125 void UnitTestRunner::setPassesAreLogged (bool shouldDisplayPasses) noexcept
126 {
127  logPasses = shouldDisplayPasses;
128 }
129 
130 int UnitTestRunner::getNumResults() const noexcept
131 {
132  return results.size();
133 }
134 
135 const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const noexcept
136 {
137  return results [index];
138 }
139 
141 {
142 }
143 
144 void UnitTestRunner::runTests (const Array<UnitTest*>& tests, int64 randomSeed)
145 {
146  results.clear();
147  resultsUpdated();
148 
149  if (randomSeed == 0)
150  randomSeed = Random().nextInt (0x7ffffff);
151 
152  randomForTest = Random (randomSeed);
153  logMessage ("Random seed: 0x" + String::toHexString (randomSeed));
154 
155  for (auto* t : tests)
156  {
157  if (shouldAbortTests())
158  break;
159 
160  #if JUCE_EXCEPTIONS_DISABLED
161  t->performTest (this);
162  #else
163  try
164  {
165  t->performTest (this);
166  }
167  catch (...)
168  {
169  addFail ("An unhandled exception was thrown!");
170  }
171  #endif
172  }
173 
174  endTest();
175 }
176 
177 void UnitTestRunner::runAllTests (int64 randomSeed)
178 {
179  runTests (UnitTest::getAllTests(), randomSeed);
180 }
181 
182 void UnitTestRunner::runTestsInCategory (const String& category, int64 randomSeed)
183 {
184  runTests (UnitTest::getTestsInCategory (category), randomSeed);
185 }
186 
187 void UnitTestRunner::logMessage (const String& message)
188 {
189  Logger::writeToLog (message);
190 }
191 
193 {
194  return false;
195 }
196 
197 void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCategory)
198 {
199  endTest();
200  currentTest = test;
201 
202  auto* r = new TestResult();
203  results.add (r);
204  r->unitTestName = test->getName();
205  r->subcategoryName = subCategory;
206  r->passes = 0;
207  r->failures = 0;
208 
209  logMessage ("-----------------------------------------------------------------");
210  logMessage ("Starting test: " + r->unitTestName + " / " + subCategory + "...");
211 
212  resultsUpdated();
213 }
214 
215 void UnitTestRunner::endTest()
216 {
217  if (auto* r = results.getLast())
218  {
219  if (r->failures > 0)
220  {
221  String m ("FAILED!! ");
222  m << r->failures << (r->failures == 1 ? " test" : " tests")
223  << " failed, out of a total of " << (r->passes + r->failures);
224 
225  logMessage (String());
226  logMessage (m);
227  logMessage (String());
228  }
229  else
230  {
231  logMessage ("All tests completed successfully");
232  }
233  }
234 }
235 
236 void UnitTestRunner::addPass()
237 {
238  {
239  const ScopedLock sl (results.getLock());
240 
241  auto* r = results.getLast();
242  jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests!
243 
244  r->passes++;
245 
246  if (logPasses)
247  {
248  String message ("Test ");
249  message << (r->failures + r->passes) << " passed";
250  logMessage (message);
251  }
252  }
253 
254  resultsUpdated();
255 }
256 
257 void UnitTestRunner::addFail (const String& failureMessage)
258 {
259  {
260  const ScopedLock sl (results.getLock());
261 
262  auto* r = results.getLast();
263  jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests!
264 
265  r->failures++;
266 
267  String message ("!!! Test ");
268  message << (r->failures + r->passes) << " failed";
269 
270  if (failureMessage.isNotEmpty())
271  message << ": " << failureMessage;
272 
273  r->messages.add (message);
274 
275  logMessage (message);
276  }
277 
278  resultsUpdated();
279 
280  if (assertOnFailure) { jassertfalse; }
281 }
282 
283 } // namespace juce
juce::StringArray
A special array for holding a list of strings.
Definition: juce_StringArray.h:38
juce::UnitTest::~UnitTest
virtual ~UnitTest()
Destructor.
Definition: juce_UnitTest.cpp:32
juce::UnitTestRunner::getNumResults
int getNumResults() const noexcept
Returns the number of TestResult objects that have been performed.
Definition: juce_UnitTest.cpp:130
juce::UnitTest::getRandom
Random getRandom() const
Returns a shared RNG that all unit tests should use.
Definition: juce_UnitTest.cpp:108
juce::Random::nextInt
int nextInt() noexcept
Returns the next random 32 bit integer.
Definition: juce_Random.cpp:78
juce::UnitTest::getAllTests
static Array< UnitTest * > & getAllTests()
Returns the set of all UnitTest objects that currently exist.
Definition: juce_UnitTest.cpp:37
juce::Array::add
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition: juce_Array.h:375
juce::UnitTestRunner::setAssertOnFailure
void setAssertOnFailure(bool shouldAssert) noexcept
Sets a flag to indicate whether an assertion should be triggered if a test fails.
Definition: juce_UnitTest.cpp:120
juce::UnitTestRunner::setPassesAreLogged
void setPassesAreLogged(bool shouldDisplayPasses) noexcept
Sets a flag to indicate whether successful tests should be logged.
Definition: juce_UnitTest.cpp:125
juce::UnitTest::expect
void expect(bool testResult, const String &failureMessage=String())
Checks that the result of a test is true, and logs this result.
Definition: juce_UnitTest.cpp:97
juce::Array
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
juce::UnitTestRunner::runAllTests
void runAllTests(int64 randomSeed=0)
Runs all the UnitTest objects that currently exist.
Definition: juce_UnitTest.cpp:177
juce::String::toHexString
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
Definition: juce_String.h:1055
juce::UnitTestRunner::TestResult
Contains the results of a test.
Definition: juce_UnitTest.h:381
juce::Random
A random number generator.
Definition: juce_Random.h:38
juce::UnitTestRunner::logMessage
virtual void logMessage(const String &message)
Logs a message about the current test progress.
Definition: juce_UnitTest.cpp:187
juce::Logger::writeToLog
static void JUCE_CALLTYPE writeToLog(const String &message)
Writes a string to the current logger.
Definition: juce_Logger.cpp:40
juce::UnitTest::getName
const String & getName() const noexcept
Returns the name of the test.
Definition: juce_UnitTest.h:84
juce::UnitTestRunner::~UnitTestRunner
virtual ~UnitTestRunner()
Destructor.
Definition: juce_UnitTest.cpp:118
juce::StringArray::addIfNotAlreadyThere
bool addIfNotAlreadyThere(const String &stringToAdd, bool ignoreCase=false)
Adds a string to the array as long as it's not already in there.
Definition: juce_StringArray.cpp:149
juce::String::isEmpty
bool isEmpty() const noexcept
Returns true if the string contains no characters.
Definition: juce_String.h:300
juce::UnitTest::shutdown
virtual void shutdown()
You can optionally implement this method to clear up after your test has been run.
Definition: juce_UnitTest.cpp:69
juce::UnitTestRunner::resultsUpdated
virtual void resultsUpdated()
Called when the list of results changes.
Definition: juce_UnitTest.cpp:140
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::UnitTestRunner::shouldAbortTests
virtual bool shouldAbortTests()
This can be overridden to let the runner know that it should abort the tests as soon as possible,...
Definition: juce_UnitTest.cpp:192
juce::UnitTest::logMessage
void logMessage(const String &message)
Writes a message to the test log.
Definition: juce_UnitTest.cpp:81
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::UnitTest::UnitTest
UnitTest(const String &name, const String &category=String())
Creates a test with the given name and optionally places it in a category.
Definition: juce_UnitTest.cpp:26
juce::UnitTest::runTest
virtual void runTest()=0
Implement this method in your subclass to actually run your tests.
juce::UnitTest::performTest
void performTest(UnitTestRunner *runner)
Runs the test, using the specified UnitTestRunner.
Definition: juce_UnitTest.cpp:71
juce::UnitTest::getTestsInCategory
static Array< UnitTest * > getTestsInCategory(const String &category)
Returns the set of UnitTests in a specified category.
Definition: juce_UnitTest.cpp:43
juce::UnitTestRunner
Runs a set of unit tests.
Definition: juce_UnitTest.h:328
juce::UnitTest::getAllCategories
static StringArray getAllCategories()
Returns a StringArray containing all of the categories of UnitTests that have been registered.
Definition: juce_UnitTest.cpp:57
juce::UnitTestRunner::getResult
const TestResult * getResult(int index) const noexcept
Returns one of the TestResult objects that describes a test that has been run.
Definition: juce_UnitTest.cpp:135
juce::UnitTestRunner::runTestsInCategory
void runTestsInCategory(const String &category, int64 randomSeed=0)
Runs all the UnitTest objects within a specified category.
Definition: juce_UnitTest.cpp:182
juce::UnitTest::beginTest
void beginTest(const String &testName)
Tells the system that a new subsection of tests is beginning.
Definition: juce_UnitTest.cpp:89
juce::UnitTest::initialise
virtual void initialise()
You can optionally implement this method to set up your test.
Definition: juce_UnitTest.cpp:68
juce::UnitTestRunner::runTests
void runTests(const Array< UnitTest * > &tests, int64 randomSeed=0)
Runs a set of tests.
Definition: juce_UnitTest.cpp:144