Initial release
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/source/vst/utility/testing.h
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Utility classes for custom testing in the vst validator
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/test/itest.h"
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** How to use the validator to run your own tests?
|
||||
\ingroup TestClass
|
||||
|
||||
It is possible to run your own tests when the validator checks your plug-in.
|
||||
|
||||
First you have to register a test factory in your plugin factory:
|
||||
|
||||
\code{.cpp}
|
||||
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
|
||||
BEGIN_FACTORY_DEF(...
|
||||
|
||||
DEF_CLASS2 (Your Plugin Processor)
|
||||
DEF_CLASS2 (Your Plugin Controller)
|
||||
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (getTestFactoryUID ()), PClassInfo::kManyInstances, kTestClass,
|
||||
"Test Factory", 0, "", "", "", createTestFactoryInstance)
|
||||
|
||||
END_FACTORY
|
||||
|
||||
\endcode
|
||||
|
||||
Second: write your tests:
|
||||
|
||||
\code{.cpp}
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
|
||||
static ModuleInitializer InitMyTests ([] () {
|
||||
registerTest ("MyTests", STR ("two plus two is four"), [] (ITestResult* testResult) {
|
||||
auto result = 2 + 2;
|
||||
if (result == 4)
|
||||
return true;
|
||||
testResult->addErrorMessage (STR ("Unexpected universe change where 2+2 != 4."));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
\endcode
|
||||
|
||||
If you need access to your audio effect or edit controller you can write your tests as done in the
|
||||
adelay example:
|
||||
|
||||
\code{.cpp}
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/testsuite/vsttestsuite.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
|
||||
static ModuleInitializer InitMyTests ([] () {
|
||||
registerTest ("MyTests", STR ("check one two three"), [] (FUnknown* context, ITestResult*
|
||||
testResult)
|
||||
{
|
||||
if (auto plugProvider = U::cast<ITestPlugProvider> (context))
|
||||
{
|
||||
auto controller = plugProvider->getController ();
|
||||
auto testController = U::cast<IDelayTestController> (controller);
|
||||
if (!controller)
|
||||
{
|
||||
testResult->addErrorMessage (String ("Unknown IEditController"));
|
||||
return false;
|
||||
}
|
||||
bool result = testController->doTest ();
|
||||
plugProvider->releasePlugIn (nullptr, controller);
|
||||
|
||||
return (result);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
\endcode
|
||||
|
||||
After that recompile and if the validator does not run automatically after every build, start the
|
||||
validator manually and let it check your plug-in.
|
||||
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** create a Test Factory instance */
|
||||
FUnknown* createTestFactoryInstance (void*);
|
||||
|
||||
/** the test factory class ID */
|
||||
static const DECLARE_UID (TestFactoryUID, 0x70AA33A3, 0x1AE74B24, 0xB726F784, 0xB706C080);
|
||||
|
||||
/** get the test factory class ID */
|
||||
const FUID& getTestFactoryUID ();
|
||||
|
||||
/** simple test function */
|
||||
using TestFunc = std::function<bool (ITestResult*)>;
|
||||
/** register a simple test function */
|
||||
void registerTest (FIDString name, const tchar* desc, const TestFunc& func);
|
||||
/** register a simple test function */
|
||||
void registerTest (FIDString name, const tchar* desc, TestFunc&& func);
|
||||
|
||||
/** test function with context pointer */
|
||||
using TestFuncWithContext = std::function<bool (FUnknown*, ITestResult*)>;
|
||||
/** register a test function with context pointer */
|
||||
void registerTest (FIDString name, const tchar* desc, const TestFuncWithContext& func);
|
||||
/** register a test function with context pointer */
|
||||
void registerTest (FIDString name, const tchar* desc, TestFuncWithContext&& func);
|
||||
|
||||
/** register a custom test, the test object will be owned by the implementation */
|
||||
void registerTest (FIDString name, ITest* test);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Test {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
|
||||
inline constexpr bool equal (const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
return std::abs (lhs - rhs) <= std::numeric_limits<T>::epsilon ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
|
||||
inline constexpr bool equal (const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline constexpr bool notEqual (const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
return equal (lhs, rhs) == false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline constexpr bool maxDiff (const T& lhs, const T& rhs, const T& maxDiff) noexcept
|
||||
{
|
||||
return std::abs (lhs - rhs) <= maxDiff;
|
||||
}
|
||||
|
||||
#ifndef SMTG_DISABLE_VST_TEST_MACROS
|
||||
|
||||
#ifndef SMTG_MAKE_STRING_PRIVATE_DONT_USE
|
||||
#define SMTG_MAKE_STRING_PRIVATE_DONT_USE(x) #x
|
||||
#define SMTG_MAKE_STRING(x) SMTG_MAKE_STRING_PRIVATE_DONT_USE (x)
|
||||
#endif // SMTG_MAKE_STRING_PRIVATE_DONT_USE
|
||||
|
||||
#define EXPECT(condition) \
|
||||
{ \
|
||||
if (!(condition)) \
|
||||
{ \
|
||||
testResult->addErrorMessage (STR (__FILE__ ":" SMTG_MAKE_STRING ( \
|
||||
__LINE__) ": error: " SMTG_MAKE_STRING (condition))); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EXPECT_TRUE(condition) EXPECT (condition)
|
||||
#define EXPECT_FALSE(condition) EXPECT (!condition)
|
||||
#define EXPECT_EQ(var1, var2) EXPECT ((var1 == var2))
|
||||
#define EXPECT_NE(var1, var2) EXPECT ((var1 != var2))
|
||||
|
||||
#endif // SMTG_DISABLE_VST_TEST_MACROS
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Test
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
Reference in New Issue
Block a user