OpenShot Audio Library | OpenShotAudio 0.4.0
 
Loading...
Searching...
No Matches
juce_UnitTest.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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
23namespace juce
24{
25
26UnitTest::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
72{
73 jassert (newRunner != nullptr);
74 runner = newRunner;
75
76 initialise();
77 runTest();
78 shutdown();
79}
80
81void 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
89void 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
97void 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//==============================================================================
117UnitTestRunner::UnitTestRunner() {}
119
120void UnitTestRunner::setAssertOnFailure (bool shouldAssert) noexcept
121{
122 assertOnFailure = shouldAssert;
123}
124
125void UnitTestRunner::setPassesAreLogged (bool shouldDisplayPasses) noexcept
126{
127 logPasses = shouldDisplayPasses;
128}
129
131{
132 return results.size();
133}
134
136{
137 return results [index];
138}
139
143
144void UnitTestRunner::runTests (const Array<UnitTest*>& tests, int64 randomSeed)
145{
146 results.clear();
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
177void UnitTestRunner::runAllTests (int64 randomSeed)
178{
179 runTests (UnitTest::getAllTests(), randomSeed);
180}
181
182void UnitTestRunner::runTestsInCategory (const String& category, int64 randomSeed)
183{
184 runTests (UnitTest::getTestsInCategory (category), randomSeed);
185}
186
188{
189 Logger::writeToLog (message);
190}
191
193{
194 return false;
195}
196
197static String getTestNameString (const String& testName, const String& subCategory)
198{
199 return testName + " / " + subCategory;
200}
201
202void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCategory)
203{
204 endTest();
205 currentTest = test;
206
207 auto testName = test->getName();
208 results.add (new TestResult (testName, subCategory));
209
210 logMessage ("-----------------------------------------------------------------");
211 logMessage ("Starting tests in: " + getTestNameString (testName, subCategory) + "...");
212
214}
215
216void UnitTestRunner::endTest()
217{
218 if (auto* r = results.getLast())
219 {
220 r->endTime = Time::getCurrentTime();
221
222 if (r->failures > 0)
223 {
224 String m ("FAILED!! ");
225 m << r->failures << (r->failures == 1 ? " test" : " tests")
226 << " failed, out of a total of " << (r->passes + r->failures);
227
228 logMessage (String());
229 logMessage (m);
230 logMessage (String());
231 }
232 else
233 {
234 logMessage ("Completed tests in " + getTestNameString (r->unitTestName, r->subcategoryName));
235 }
236 }
237}
238
239void UnitTestRunner::addPass()
240{
241 {
242 const ScopedLock sl (results.getLock());
243
244 auto* r = results.getLast();
245 jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests!
246
247 r->passes++;
248
249 if (logPasses)
250 {
251 String message ("Test ");
252 message << (r->failures + r->passes) << " passed";
253 logMessage (message);
254 }
255 }
256
258}
259
260void UnitTestRunner::addFail (const String& failureMessage)
261{
262 {
263 const ScopedLock sl (results.getLock());
264
265 auto* r = results.getLast();
266 jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests!
267
268 r->failures++;
269
270 String message ("!!! Test ");
271 message << (r->failures + r->passes) << " failed";
272
273 if (failureMessage.isNotEmpty())
274 message << ": " << failureMessage;
275
276 r->messages.add (message);
277
278 logMessage (message);
279 }
280
282
283 if (assertOnFailure) { jassertfalse; }
284}
285
286} // namespace juce
void add(const ElementType &newElement)
Definition juce_Array.h:418
static void JUCE_CALLTYPE writeToLog(const String &message)
int nextInt() noexcept
bool addIfNotAlreadyThere(const String &stringToAdd, bool ignoreCase=false)
static String toHexString(IntegerType number)
static Time JUCE_CALLTYPE getCurrentTime() noexcept
void runAllTests(int64 randomSeed=0)
void runTestsInCategory(const String &category, int64 randomSeed=0)
virtual bool shouldAbortTests()
const TestResult * getResult(int index) const noexcept
int getNumResults() const noexcept
void setAssertOnFailure(bool shouldAssert) noexcept
void runTests(const Array< UnitTest * > &tests, int64 randomSeed=0)
void setPassesAreLogged(bool shouldDisplayPasses) noexcept
virtual void logMessage(const String &message)
virtual void resultsUpdated()
const String & getName() const noexcept
void logMessage(const String &message)
static StringArray getAllCategories()
static Array< UnitTest * > getTestsInCategory(const String &category)
virtual void initialise()
UnitTest(const String &name, const String &category=String())
static Array< UnitTest * > & getAllTests()
void beginTest(const String &testName)
void expect(bool testResult, const String &failureMessage=String())
virtual void shutdown()
virtual void runTest()=0
Random getRandom() const
virtual ~UnitTest()
void performTest(UnitTestRunner *runner)