#include "UnitTest.h"
#include "../Console.h"
#ifdef VCZH_MSVC
#include <Windows.h>
#endif
namespace
{
namespace
{
using
namespace
vl
::
console
;
namespace
{
struct
{
const
char
*
;
=
nullptr
;
*
=
nullptr
;
};
*
=
nullptr
;
**
= &
testHead
;
enum
class
{
,
,
,
};
struct
{
*
=
nullptr
;
;
=
::
;
bool
=
false
;
};
*
=
nullptr
;
=
0
;
=
0
;
=
0
;
=
0
;
bool
=
false
;
template
<
typename
>
void
(
)
{
::
(
,
::
::
);
auto
=
testContext
;
while
(
current
)
{
current
->
=
true
;
current
=
current
->
;
}
}
template
<
typename
>
void
(
&&
)
{
try
{
();
}
catch
(
const
&
)
{
(
e
.
);
}
catch
(
const
&
)
{
(
e
.
);
}
catch
(
const
&
)
{
(
e
.
());
}
catch
(
const
&
)
{
(
e
.
());
}
catch
(...)
{
(
L"Unknown exception occurred!"
);
}
}
template
<
typename
>
void
(
&&
)
{
#ifdef VCZH_MSVC
__try
{
(
<
&&>(
));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
(
L"Runtime exception occurred!"
);
}
#else
SuppressCppFailure(callback);
#endif
}
template
<
typename
>
void
ExecuteAndSuppressFailure
(
&&
)
{
if
(
suppressFailure
)
{
(
<
&&>(
));
}
else
{
();
}
}
}
using
namespace
execution_impl
;
void
::
(
const
&
,
)
{
if
(
!=
::
&& !
testContext
)
{
throw
(
L"Cannot print message when unit test is not running."
);
}
switch
(
)
{
case
::
:
::
(
true
,
false
,
false
,
true
);
break
;
case
::
:
::
(
true
,
true
,
true
,
true
);
break
;
case
::
:
::
(
true
,
false
,
true
,
true
);
break
;
case
::
:
::
(
true
,
true
,
false
,
true
);
break
;
case
::
:
::
(
false
,
true
,
false
,
true
);
break
;
}
::
((
testContext
?
testContext
->
:
L""
) +
);
::
(
true
,
true
,
true
,
false
);
}
#ifdef VCZH_MSVC
int
::
(
int
,
wchar_t
*
[])
#else
int UnitTest::RunAndDisposeTests(int argc, char* argv[])
#endif
{
if
(
<
3
)
{
if
(
==
2
)
{
#ifdef VCZH_MSVC
=
[
1
];
#else
WString option = atow(argv[1]);
#endif
if
(
option
==
L"/D"
)
{
suppressFailure
=
false
;
}
else
if
(
option
==
L"/R"
)
{
suppressFailure
=
true
;
}
else
{
goto
PRINT_USAGE;
}
}
else
{
#ifdef VCZH_MSVC
if
(
())
{
suppressFailure
=
false
;
}
else
{
suppressFailure
=
true
;
}
#else
suppressFailure = true;
#endif
}
auto
=
testHead
;
testHead
=
nullptr
;
testTail
=
nullptr
;
;
testContext
= &
context
;
totalFiles
=
0
;
passedFiles
=
0
;
totalCases
=
0
;
passedCases
=
0
;
if
(
suppressFailure
)
{
(
L"Failures are suppressed."
,
::
);
}
else
{
(
L"Failures are not suppressed."
,
::
);
}
while
(
current
)
{
context
.
=
false
;
(
(
current
->
),
::
);
context
.
=
L" "
;
ExecuteAndSuppressFailure
(
current
->
);
if
(!
testContext
->
)
passedFiles
++;
totalFiles
++;
context
.
=
L""
;
auto
=
current
;
current
=
current
->
;
delete
temp
;
}
bool
=
totalFiles
==
passedFiles
;
auto
=
passed
?
::
:
::
;
(
L"Passed test files: "
+
(
passedFiles
) +
L"/"
+
(
totalFiles
),
messageKind
);
(
L"Passed test cases: "
+
(
passedCases
) +
L"/"
+
(
totalCases
),
messageKind
);
testContext
=
nullptr
;
return
passed
?
0
:
1
;
}
PRINT_USAGE:
(
L"Usage: [/D | /R]"
,
::
);
return
1
;
}
void
::
(
const
char
*
,
)
{
auto
=
new
;
link
->
=
;
link
->
=
;
*
testTail
=
link
;
testTail
= &
link
->
;
}
void
::
(
const
&
,
bool
,
<
void
()>&&
)
{
if
(!
testContext
)
throw
(
L"TEST_CATEGORY is not allowed to execute outside of TEST_FILE."
);
if
(
testContext
->
==
::
)
throw
(
?
L"TEST_CATEGORY is not allowed to execute inside TEST_CASE"
:
L"TEST_CASE is not allowed to execute inside TEST_CASE"
);
(
, (
?
::
:
::
));
;
context
.
=
testContext
;
context
.
=
testContext
->
+
L" "
;
context
.
=
?
::
:
::
;
testContext
= &
context
;
ExecuteAndSuppressFailure
(
);
if
(!
)
{
if
(!
testContext
->
)
passedCases
++;
totalCases
++;
}
testContext
=
context
.
;
}
void
::
()
{
if
(!
testContext
)
throw
(
L"Assertion is not allowed to execute outside of TEST_CASE."
);
if
(
testContext
->
!=
::
)
throw
(
L"Assertion is not allowed to execute outside of TEST_CASE."
);
}
}
}