add initial unittest framework (tests)
move some previous unittests out of core classes and into tests git-svn-id: http://skia.googlecode.com/svn/trunk@96 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
3469c76c40
commit
ed673310e2
@ -217,14 +217,5 @@ static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
|
||||
return (prod + (prod >> shift)) >> shift;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
class SkMath {
|
||||
public:
|
||||
static void UnitTest();
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -403,13 +403,6 @@ public:
|
||||
void dump() const;
|
||||
void toDumpString(SkString*) const;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum {
|
||||
/** Set if the matrix will map a rectangle to another rectangle. This
|
||||
|
@ -118,7 +118,7 @@
|
||||
so this flag is optional.
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
//#define SK_SUPPORT_UNITTEST
|
||||
#define SK_SUPPORT_UNITTEST
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -96,13 +96,6 @@ size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL);
|
||||
size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
|
||||
char utf8[] = NULL);
|
||||
|
||||
class SkUtils {
|
||||
public:
|
||||
#ifdef SK_DEBUG
|
||||
static void UnitTest();
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkAutoTrace {
|
||||
|
@ -304,137 +304,9 @@ private:
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
static const uint16_t gTest0[] = { 0, 0, 1, 1 };
|
||||
static const uint16_t gTest1[] = { 1, 2, 3, 4, 5, 6 };
|
||||
static const uint16_t gTest2[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
|
||||
static const uint16_t gTest3[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
|
||||
|
||||
#include "SkRandom.h"
|
||||
static SkRandom gRand;
|
||||
static void rand_fill(uint16_t buffer[], int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
buffer[i] = (uint16_t)gRand.nextU();
|
||||
}
|
||||
|
||||
static void test_pack16() {
|
||||
static const struct {
|
||||
const uint16_t* fSrc;
|
||||
int fCount;
|
||||
} gTests[] = {
|
||||
{ gTest0, SK_ARRAY_COUNT(gTest0) },
|
||||
{ gTest1, SK_ARRAY_COUNT(gTest1) },
|
||||
{ gTest2, SK_ARRAY_COUNT(gTest2) },
|
||||
{ gTest3, SK_ARRAY_COUNT(gTest3) }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); i++) {
|
||||
uint8_t dst[100];
|
||||
size_t dstSize = SkPackBits::Pack16(gTests[i].fSrc,
|
||||
gTests[i].fCount, dst);
|
||||
printf("Test[%d] orig size = %d, dst size = %d",
|
||||
i, gTests[i].fCount, (int)dstSize);
|
||||
uint16_t src[100];
|
||||
int srcCount = SkPackBits::Unpack16(dst, dstSize, src);
|
||||
printf(", src size = %d", srcCount);
|
||||
bool match = gTests[i].fCount == srcCount && memcmp(gTests[i].fSrc, src,
|
||||
gTests[i].fCount * sizeof(uint16_t)) == 0;
|
||||
printf(", match = %d\n", match);
|
||||
}
|
||||
|
||||
for (int n = 1000; n; n--) {
|
||||
size_t size = 50;
|
||||
uint16_t src[100], src2[100];
|
||||
uint8_t dst[200];
|
||||
rand_fill(src, size);
|
||||
|
||||
size_t dstSize = SkPackBits::Pack16(src, size, dst);
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize16(size);
|
||||
SkASSERT(maxSize >= dstSize);
|
||||
|
||||
int srcCount = SkPackBits::Unpack16(dst, dstSize, src2);
|
||||
SkASSERT(size == srcCount);
|
||||
bool match = memcmp(src, src2, size * sizeof(uint16_t)) == 0;
|
||||
SkASSERT(match);
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t gTest80[] = { 0, 0, 1, 1 };
|
||||
static const uint8_t gTest81[] = { 1, 2, 3, 4, 5, 6 };
|
||||
static const uint8_t gTest82[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
|
||||
static const uint8_t gTest83[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
|
||||
static const uint8_t gTest84[] = { 1, 0, 3, 0, 0, 0, 2, 1, 1, 2 };
|
||||
|
||||
static void rand_fill(uint8_t buffer[], int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
buffer[i] = (uint8_t)((gRand.nextU() >> 8) & 0x3);
|
||||
}
|
||||
|
||||
static void test_pack8() {
|
||||
static const struct {
|
||||
const uint8_t* fSrc;
|
||||
int fCount;
|
||||
} gTests[] = {
|
||||
{ gTest80, SK_ARRAY_COUNT(gTest80) },
|
||||
{ gTest81, SK_ARRAY_COUNT(gTest81) },
|
||||
{ gTest82, SK_ARRAY_COUNT(gTest82) },
|
||||
{ gTest83, SK_ARRAY_COUNT(gTest83) },
|
||||
{ gTest84, SK_ARRAY_COUNT(gTest84) }
|
||||
};
|
||||
|
||||
for (size_t i = 4; i < SK_ARRAY_COUNT(gTests); i++) {
|
||||
uint8_t dst[100];
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize8(gTests[i].fCount);
|
||||
size_t dstSize = SkPackBits::Pack8(gTests[i].fSrc,
|
||||
gTests[i].fCount, dst);
|
||||
SkASSERT(dstSize <= maxSize);
|
||||
printf("Test[%d] orig size = %d, dst size = %d", i,
|
||||
gTests[i].fCount, (int)dstSize);
|
||||
uint8_t src[100];
|
||||
int srcCount = SkPackBits::Unpack8(dst, dstSize, src);
|
||||
printf(", src size = %d", srcCount);
|
||||
bool match = gTests[i].fCount == srcCount &&
|
||||
memcmp(gTests[i].fSrc, src,
|
||||
gTests[i].fCount * sizeof(uint8_t)) == 0;
|
||||
printf(", match = %d\n", match);
|
||||
}
|
||||
|
||||
for (size_t size = 1; size <= 512; size += 1) {
|
||||
for (int n = 200; n; n--) {
|
||||
uint8_t src[600], src2[600];
|
||||
uint8_t dst[600];
|
||||
rand_fill(src, size);
|
||||
|
||||
size_t dstSize = SkPackBits::Pack8(src, size, dst);
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize8(size);
|
||||
SkASSERT(maxSize >= dstSize);
|
||||
|
||||
int srcCount = SkPackBits::Unpack8(dst, dstSize, src2);
|
||||
SkASSERT(size == srcCount);
|
||||
bool match = memcmp(src, src2, size * sizeof(uint8_t)) == 0;
|
||||
SkASSERT(match);
|
||||
|
||||
for (int j = 0; j < 200; j++) {
|
||||
size_t skip = gRand.nextU() % size;
|
||||
size_t write = gRand.nextU() % size;
|
||||
if (skip + write > size) {
|
||||
write = size - skip;
|
||||
}
|
||||
SkPackBits::Unpack8(src, skip, write, dst);
|
||||
bool match = memcmp(src, src2 + skip, write) == 0;
|
||||
SkASSERT(match);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkView* MyFactory() {
|
||||
static bool gOnce;
|
||||
if (!gOnce) {
|
||||
// test_pack8();
|
||||
gOnce = true;
|
||||
}
|
||||
return new TextOnPathView;
|
||||
}
|
||||
|
||||
|
@ -345,10 +345,7 @@ void SkGraphics::Init(bool runUnitTests)
|
||||
void (*fUnitTest)();
|
||||
} gUnitTests[] = {
|
||||
unittestline(Sk64),
|
||||
unittestline(SkMath),
|
||||
unittestline(SkUtils),
|
||||
unittestline(SkString),
|
||||
unittestline(SkMatrix),
|
||||
unittestline(SkGeometry),
|
||||
unittestline(SkPath),
|
||||
unittestline(SkPathMeasure),
|
||||
|
@ -543,396 +543,3 @@ SkFixed SkFixedATan2(SkFixed y, SkFixed x) { return SkCordicATan2(y, x); }
|
||||
SkFixed SkFixedExp(SkFixed x) { return SkCordicExp(x); }
|
||||
SkFixed SkFixedLog(SkFixed x) { return SkCordicLog(x); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
|
||||
#include "SkRandom.h"
|
||||
|
||||
#if defined(SkLONGLONG) && defined(SK_SUPPORT_UNITTEST)
|
||||
static int symmetric_fixmul(int a, int b) {
|
||||
int sa = SkExtractSign(a);
|
||||
int sb = SkExtractSign(b);
|
||||
|
||||
a = SkApplySign(a, sa);
|
||||
b = SkApplySign(b, sb);
|
||||
|
||||
#if 1
|
||||
int c = (int)(((SkLONGLONG)a * b) >> 16);
|
||||
|
||||
return SkApplySign(c, sa ^ sb);
|
||||
#else
|
||||
SkLONGLONG ab = (SkLONGLONG)a * b;
|
||||
if (sa ^ sb) {
|
||||
ab = -ab;
|
||||
}
|
||||
return ab >> 16;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "SkPoint.h"
|
||||
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
static void check_length(const SkPoint& p, SkScalar targetLen) {
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
float x = SkScalarToFloat(p.fX);
|
||||
float y = SkScalarToFloat(p.fY);
|
||||
float len = sk_float_sqrt(x*x + y*y);
|
||||
|
||||
len /= SkScalarToFloat(targetLen);
|
||||
|
||||
SkASSERT(len > 0.999f && len < 1.001f);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SK_CAN_USE_FLOAT) && defined(SK_SUPPORT_UNITTEST)
|
||||
|
||||
static float nextFloat(SkRandom& rand) {
|
||||
SkFloatIntUnion data;
|
||||
data.fSignBitInt = rand.nextU();
|
||||
return data.fFloat;
|
||||
}
|
||||
|
||||
/* returns true if a == b as resulting from (int)x. Since it is undefined
|
||||
what to do if the float exceeds 2^32-1, we check for that explicitly.
|
||||
*/
|
||||
static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
|
||||
if (!(x == x)) { // NAN
|
||||
return si == SK_MaxS32 || si == SK_MinS32;
|
||||
}
|
||||
// for out of range, C is undefined, but skia always should return NaN32
|
||||
if (x > SK_MaxS32) {
|
||||
return si == SK_MaxS32;
|
||||
}
|
||||
if (x < -SK_MaxS32) {
|
||||
return si == SK_MinS32;
|
||||
}
|
||||
return si == ni;
|
||||
}
|
||||
|
||||
static void assert_float_equal(const char op[], float x, uint32_t ni,
|
||||
uint32_t si) {
|
||||
if (!equal_float_native_skia(x, ni, si)) {
|
||||
SkDebugf("-- %s float %g bits %x native %x skia %x\n", op, x, ni, si);
|
||||
SkASSERT(!"oops");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_float_cast(float x) {
|
||||
int ix = (int)x;
|
||||
int iix = SkFloatToIntCast(x);
|
||||
assert_float_equal("cast", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_floor(float x) {
|
||||
int ix = (int)floor(x);
|
||||
int iix = SkFloatToIntFloor(x);
|
||||
assert_float_equal("floor", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_round(float x) {
|
||||
double xx = x + 0.5; // need intermediate double to avoid temp loss
|
||||
int ix = (int)floor(xx);
|
||||
int iix = SkFloatToIntRound(x);
|
||||
assert_float_equal("round", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_ceil(float x) {
|
||||
int ix = (int)ceil(x);
|
||||
int iix = SkFloatToIntCeil(x);
|
||||
assert_float_equal("ceil", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_conversions(float x) {
|
||||
test_float_cast(x);
|
||||
test_float_floor(x);
|
||||
test_float_round(x);
|
||||
test_float_ceil(x);
|
||||
}
|
||||
|
||||
static void test_int2float(int ival) {
|
||||
float x0 = (float)ival;
|
||||
float x1 = SkIntToFloatCast(ival);
|
||||
float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
|
||||
SkASSERT(x0 == x1);
|
||||
SkASSERT(x0 == x2);
|
||||
}
|
||||
|
||||
static void unittest_fastfloat() {
|
||||
SkRandom rand;
|
||||
size_t i;
|
||||
|
||||
static const float gFloats[] = {
|
||||
0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
|
||||
0.000000001f, 1000000000.f, // doesn't overflow
|
||||
0.0000000001f, 10000000000.f // does overflow
|
||||
};
|
||||
for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
|
||||
// SkDebugf("---- test floats %g %d\n", gFloats[i], (int)gFloats[i]);
|
||||
test_float_conversions(gFloats[i]);
|
||||
test_float_conversions(-gFloats[i]);
|
||||
}
|
||||
|
||||
for (int outer = 0; outer < 100; outer++) {
|
||||
rand.setSeed(outer);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
float x = nextFloat(rand);
|
||||
test_float_conversions(x);
|
||||
}
|
||||
|
||||
test_int2float(0);
|
||||
test_int2float(1);
|
||||
test_int2float(-1);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
// for now only test ints that are 24bits or less, since we don't
|
||||
// round (down) large ints the same as IEEE...
|
||||
int ival = rand.nextU() & 0xFFFFFF;
|
||||
test_int2float(ival);
|
||||
test_int2float(-ival);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
static void test_muldiv255() {
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
for (int a = 0; a <= 255; a++) {
|
||||
for (int b = 0; b <= 255; b++) {
|
||||
int ab = a * b;
|
||||
float s = ab / 255.0f;
|
||||
int round = (int)floorf(s + 0.5f);
|
||||
int trunc = (int)floorf(s);
|
||||
|
||||
int iround = SkMulDiv255Round(a, b);
|
||||
int itrunc = SkMulDiv255Trunc(a, b);
|
||||
|
||||
SkASSERT(iround == round);
|
||||
SkASSERT(itrunc == trunc);
|
||||
|
||||
SkASSERT(itrunc <= iround);
|
||||
SkASSERT(iround <= a);
|
||||
SkASSERT(iround <= b);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void SkMath::UnitTest() {
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
int i;
|
||||
int32_t x;
|
||||
SkRandom rand;
|
||||
|
||||
SkToS8(127); SkToS8(-128); SkToU8(255);
|
||||
SkToS16(32767); SkToS16(-32768); SkToU16(65535);
|
||||
SkToS32(2*1024*1024); SkToS32(-2*1024*1024); SkToU32(4*1024*1024);
|
||||
|
||||
SkCordic_UnitTest();
|
||||
|
||||
// these should assert
|
||||
#if 0
|
||||
SkToS8(128);
|
||||
SkToS8(-129);
|
||||
SkToU8(256);
|
||||
SkToU8(-5);
|
||||
|
||||
SkToS16(32768);
|
||||
SkToS16(-32769);
|
||||
SkToU16(65536);
|
||||
SkToU16(-5);
|
||||
|
||||
if (sizeof(size_t) > 4) {
|
||||
SkToS32(4*1024*1024);
|
||||
SkToS32(-4*1024*1024);
|
||||
SkToU32(5*1024*1024);
|
||||
SkToU32(-5);
|
||||
}
|
||||
#endif
|
||||
|
||||
test_muldiv255();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
{
|
||||
SkScalar x = SK_ScalarNaN;
|
||||
SkASSERT(SkScalarIsNaN(x));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 1; i <= 10; i++) {
|
||||
x = SkCubeRootBits(i*i*i, 11);
|
||||
SkASSERT(x == i);
|
||||
}
|
||||
|
||||
x = SkFixedSqrt(SK_Fixed1);
|
||||
SkASSERT(x == SK_Fixed1);
|
||||
x = SkFixedSqrt(SK_Fixed1/4);
|
||||
SkASSERT(x == SK_Fixed1/2);
|
||||
x = SkFixedSqrt(SK_Fixed1*4);
|
||||
SkASSERT(x == SK_Fixed1*2);
|
||||
|
||||
x = SkFractSqrt(SK_Fract1);
|
||||
SkASSERT(x == SK_Fract1);
|
||||
x = SkFractSqrt(SK_Fract1/4);
|
||||
SkASSERT(x == SK_Fract1/2);
|
||||
x = SkFractSqrt(SK_Fract1/16);
|
||||
SkASSERT(x == SK_Fract1/4);
|
||||
|
||||
for (i = 1; i < 100; i++) {
|
||||
x = SkFixedSqrt(SK_Fixed1 * i * i);
|
||||
SkASSERT(x == SK_Fixed1 * i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
int value = rand.nextS16();
|
||||
int max = rand.nextU16();
|
||||
|
||||
int clamp = SkClampMax(value, max);
|
||||
int clamp2 = value < 0 ? 0 : (value > max ? max : value);
|
||||
SkASSERT(clamp == clamp2);
|
||||
}
|
||||
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkPoint p;
|
||||
|
||||
p.setLength(rand.nextS(), rand.nextS(), SK_Scalar1);
|
||||
check_length(p, SK_Scalar1);
|
||||
p.setLength(rand.nextS() >> 13, rand.nextS() >> 13, SK_Scalar1);
|
||||
check_length(p, SK_Scalar1);
|
||||
}
|
||||
|
||||
{
|
||||
SkFixed result = SkFixedDiv(100, 100);
|
||||
SkASSERT(result == SK_Fixed1);
|
||||
result = SkFixedDiv(1, SK_Fixed1);
|
||||
SkASSERT(result == 1);
|
||||
}
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
unittest_fastfloat();
|
||||
#endif
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkFixed numer = rand.nextS();
|
||||
SkFixed denom = rand.nextS();
|
||||
SkFixed result = SkFixedDiv(numer, denom);
|
||||
SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
|
||||
|
||||
(void)SkCLZ(numer);
|
||||
(void)SkCLZ(denom);
|
||||
|
||||
SkASSERT(result != (SkFixed)SK_NaN32);
|
||||
if (check > SK_MaxS32) {
|
||||
check = SK_MaxS32;
|
||||
} else if (check < -SK_MaxS32) {
|
||||
check = SK_MinS32;
|
||||
}
|
||||
SkASSERT(result == (int32_t)check);
|
||||
|
||||
result = SkFractDiv(numer, denom);
|
||||
check = ((SkLONGLONG)numer << 30) / denom;
|
||||
|
||||
SkASSERT(result != (SkFixed)SK_NaN32);
|
||||
if (check > SK_MaxS32) {
|
||||
check = SK_MaxS32;
|
||||
} else if (check < -SK_MaxS32) {
|
||||
check = SK_MinS32;
|
||||
}
|
||||
SkASSERT(result == (int32_t)check);
|
||||
|
||||
// make them <= 2^24, so we don't overflow in fixmul
|
||||
numer = numer << 8 >> 8;
|
||||
denom = denom << 8 >> 8;
|
||||
|
||||
result = SkFixedMul(numer, denom);
|
||||
SkFixed r2 = symmetric_fixmul(numer, denom);
|
||||
// SkASSERT(result == r2);
|
||||
|
||||
result = SkFixedMul(numer, numer);
|
||||
r2 = SkFixedSquare(numer);
|
||||
SkASSERT(result == r2);
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
if (numer >= 0 && denom >= 0) {
|
||||
SkFixed mean = SkFixedMean(numer, denom);
|
||||
float fm = sk_float_sqrt(sk_float_abs(SkFixedToFloat(numer) * SkFixedToFloat(denom)));
|
||||
SkFixed mean2 = SkFloatToFixed(fm);
|
||||
int diff = SkAbs32(mean - mean2);
|
||||
SkASSERT(diff <= 1);
|
||||
}
|
||||
|
||||
{
|
||||
SkFixed mod = SkFixedMod(numer, denom);
|
||||
float n = SkFixedToFloat(numer);
|
||||
float d = SkFixedToFloat(denom);
|
||||
float m = sk_float_mod(n, d);
|
||||
#if 0
|
||||
SkDebugf("%g mod %g = %g [%g]\n",
|
||||
SkFixedToFloat(numer), SkFixedToFloat(denom),
|
||||
SkFixedToFloat(mod), m);
|
||||
#endif
|
||||
SkASSERT(mod == 0 || (mod < 0) == (m < 0)); // ensure the same sign
|
||||
int diff = SkAbs32(mod - SkFloatToFixed(m));
|
||||
SkASSERT((diff >> 7) == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkFract x = rand.nextU() >> 1;
|
||||
double xx = (double)x / SK_Fract1;
|
||||
SkFract xr = SkFractSqrt(x);
|
||||
SkFract check = SkFloatToFract(sqrt(xx));
|
||||
SkASSERT(xr == check || xr == check-1 || xr == check+1);
|
||||
|
||||
xr = SkFixedSqrt(x);
|
||||
xx = (double)x / SK_Fixed1;
|
||||
check = SkFloatToFixed(sqrt(xx));
|
||||
SkASSERT(xr == check || xr == check-1);
|
||||
|
||||
xr = SkSqrt32(x);
|
||||
xx = (double)x;
|
||||
check = (int32_t)sqrt(xx);
|
||||
SkASSERT(xr == check || xr == check-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SK_SCALAR_IS_FLOAT) && defined(SK_CAN_USE_FLOAT)
|
||||
{
|
||||
SkFixed s, c;
|
||||
s = SkFixedSinCos(0, &c);
|
||||
SkASSERT(s == 0);
|
||||
SkASSERT(c == SK_Fixed1);
|
||||
}
|
||||
|
||||
int maxDiff = 0;
|
||||
for (i = 0; i < 10000; i++) {
|
||||
SkFixed rads = rand.nextS() >> 10;
|
||||
double frads = SkFixedToFloat(rads);
|
||||
|
||||
SkFixed s, c;
|
||||
s = SkScalarSinCos(rads, &c);
|
||||
|
||||
double fs = sin(frads);
|
||||
double fc = cos(frads);
|
||||
|
||||
SkFixed is = SkFloatToFixed(fs);
|
||||
SkFixed ic = SkFloatToFixed(fc);
|
||||
|
||||
maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
|
||||
maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
|
||||
}
|
||||
SkDebugf("SinCos: maximum error = %d\n", maxDiff);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1606,85 +1606,3 @@ void SkMatrix::toDumpString(SkString* str) const {
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
|
||||
void SkMatrix::UnitTest() {
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
SkMatrix mat, inverse, iden1, iden2;
|
||||
|
||||
mat.reset();
|
||||
mat.setTranslate(SK_Scalar1, SK_Scalar1);
|
||||
mat.invert(&inverse);
|
||||
inverse.dump();
|
||||
iden1.setConcat(mat, inverse);
|
||||
iden1.dump();
|
||||
|
||||
mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
|
||||
mat.invert(&inverse);
|
||||
inverse.dump();
|
||||
iden1.setConcat(mat, inverse);
|
||||
iden1.dump();
|
||||
|
||||
mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
|
||||
mat.invert(&inverse);
|
||||
inverse.dump();
|
||||
iden1.setConcat(mat, inverse);
|
||||
iden1.dump();
|
||||
SkASSERT(iden1.isIdentity());
|
||||
|
||||
mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
|
||||
mat.postRotate(SkIntToScalar(25));
|
||||
|
||||
SkASSERT(mat.invert(NULL));
|
||||
mat.invert(&inverse);
|
||||
|
||||
iden1.setConcat(mat, inverse);
|
||||
iden2.setConcat(inverse, mat);
|
||||
|
||||
iden1.dump();
|
||||
// SkASSERT(iden1.isIdentity());
|
||||
iden2.dump();
|
||||
// SkASSERT(iden2.isIdentity());
|
||||
|
||||
// rectStaysRect test
|
||||
{
|
||||
static const struct {
|
||||
SkScalar m00, m01, m10, m11;
|
||||
bool mStaysRect;
|
||||
}
|
||||
gRectStaysRectSamples[] = {
|
||||
{ 0, 0, 0, 0, false },
|
||||
{ 0, 0, 0, SK_Scalar1, false },
|
||||
{ 0, 0, SK_Scalar1, 0, false },
|
||||
{ 0, 0, SK_Scalar1, SK_Scalar1, false },
|
||||
{ 0, SK_Scalar1, 0, 0, false },
|
||||
{ 0, SK_Scalar1, 0, SK_Scalar1, false },
|
||||
{ 0, SK_Scalar1, SK_Scalar1, 0, true },
|
||||
{ 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false },
|
||||
{ SK_Scalar1, 0, 0, 0, false },
|
||||
{ SK_Scalar1, 0, 0, SK_Scalar1, true },
|
||||
{ SK_Scalar1, 0, SK_Scalar1, 0, false },
|
||||
{ SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false },
|
||||
{ SK_Scalar1, SK_Scalar1, 0, 0, false },
|
||||
{ SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false },
|
||||
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false },
|
||||
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
|
||||
SkMatrix m;
|
||||
|
||||
m.reset();
|
||||
m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
|
||||
m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01);
|
||||
m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10);
|
||||
m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
|
||||
SkASSERT(m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -458,126 +458,3 @@ SkAutoMemoryUsageProbe::~SkAutoMemoryUsageProbe()
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
|
||||
#include "SkRandom.h"
|
||||
#include "SkTSearch.h"
|
||||
#include "SkTSort.h"
|
||||
|
||||
#define kSEARCH_COUNT 91
|
||||
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
static void test_search()
|
||||
{
|
||||
int i, array[kSEARCH_COUNT];
|
||||
SkRandom rand;
|
||||
|
||||
for (i = 0; i < kSEARCH_COUNT; i++)
|
||||
array[i] = rand.nextS();
|
||||
|
||||
SkTHeapSort<int>(array, kSEARCH_COUNT);
|
||||
// make sure we got sorted properly
|
||||
for (i = 1; i < kSEARCH_COUNT; i++)
|
||||
SkASSERT(array[i-1] <= array[i]);
|
||||
|
||||
// make sure we can find all of our values
|
||||
for (i = 0; i < kSEARCH_COUNT; i++)
|
||||
{
|
||||
int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
|
||||
SkASSERT(index == i);
|
||||
}
|
||||
|
||||
// make sure that random values are either found, or the correct
|
||||
// insertion index is returned
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
int value = rand.nextS();
|
||||
int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
|
||||
|
||||
if (index >= 0)
|
||||
SkASSERT(index < kSEARCH_COUNT && array[index] == value);
|
||||
else
|
||||
{
|
||||
index = ~index;
|
||||
SkASSERT(index <= kSEARCH_COUNT);
|
||||
if (index < kSEARCH_COUNT)
|
||||
{
|
||||
SkASSERT(value < array[index]);
|
||||
if (index > 0)
|
||||
SkASSERT(value > array[index - 1]);
|
||||
}
|
||||
else // we should append the new value
|
||||
{
|
||||
SkASSERT(value > array[kSEARCH_COUNT - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_utf16()
|
||||
{
|
||||
static const SkUnichar gUni[] = {
|
||||
0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
|
||||
};
|
||||
|
||||
uint16_t buf[2];
|
||||
|
||||
for (unsigned i = 0; i < SK_ARRAY_COUNT(gUni); i++)
|
||||
{
|
||||
size_t count = SkUTF16_FromUnichar(gUni[i], buf);
|
||||
SkASSERT(count == 2);
|
||||
size_t count2 = SkUTF16_CountUnichars(buf, 2);
|
||||
SkASSERT(count2 == 1);
|
||||
const uint16_t* ptr = buf;
|
||||
SkUnichar c = SkUTF16_NextUnichar(&ptr);
|
||||
SkASSERT(c == gUni[i]);
|
||||
SkASSERT(ptr - buf == 2);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void SkUtils::UnitTest()
|
||||
{
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
static const struct {
|
||||
const char* fUtf8;
|
||||
SkUnichar fUni;
|
||||
} gTest[] = {
|
||||
{ "a", 'a' },
|
||||
{ "\x7f", 0x7f },
|
||||
{ "\xC2\x80", 0x80 },
|
||||
{ "\xC3\x83", (3 << 6) | 3 },
|
||||
{ "\xDF\xBF", 0x7ff },
|
||||
{ "\xE0\xA0\x80", 0x800 },
|
||||
{ "\xE0\xB0\xB8", 0xC38 },
|
||||
{ "\xE3\x83\x83", (3 << 12) | (3 << 6) | 3 },
|
||||
{ "\xEF\xBF\xBF", 0xFFFF },
|
||||
{ "\xF0\x90\x80\x80", 0x10000 },
|
||||
{ "\xF3\x83\x83\x83", (3 << 18) | (3 << 12) | (3 << 6) | 3 }
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < SK_ARRAY_COUNT(gTest); i++)
|
||||
{
|
||||
const char* p = gTest[i].fUtf8;
|
||||
int n = SkUTF8_CountUnichars(p);
|
||||
SkUnichar u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
|
||||
SkUnichar u1 = SkUTF8_NextUnichar(&p);
|
||||
|
||||
SkASSERT(n == 1);
|
||||
SkASSERT(u0 == u1);
|
||||
SkASSERT(u0 == gTest[i].fUni);
|
||||
SkASSERT(p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
|
||||
}
|
||||
|
||||
test_utf16();
|
||||
|
||||
test_search();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
400
tests/MathTest.cpp
Normal file
400
tests/MathTest.cpp
Normal file
@ -0,0 +1,400 @@
|
||||
#include "Test.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
#if defined(SkLONGLONG)
|
||||
static int symmetric_fixmul(int a, int b) {
|
||||
int sa = SkExtractSign(a);
|
||||
int sb = SkExtractSign(b);
|
||||
|
||||
a = SkApplySign(a, sa);
|
||||
b = SkApplySign(b, sb);
|
||||
|
||||
#if 1
|
||||
int c = (int)(((SkLONGLONG)a * b) >> 16);
|
||||
|
||||
return SkApplySign(c, sa ^ sb);
|
||||
#else
|
||||
SkLONGLONG ab = (SkLONGLONG)a * b;
|
||||
if (sa ^ sb) {
|
||||
ab = -ab;
|
||||
}
|
||||
return ab >> 16;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_length(skiatest::Reporter* reporter,
|
||||
const SkPoint& p, SkScalar targetLen) {
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
float x = SkScalarToFloat(p.fX);
|
||||
float y = SkScalarToFloat(p.fY);
|
||||
float len = sk_float_sqrt(x*x + y*y);
|
||||
|
||||
len /= SkScalarToFloat(targetLen);
|
||||
|
||||
REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SK_CAN_USE_FLOAT)
|
||||
|
||||
static float nextFloat(SkRandom& rand) {
|
||||
SkFloatIntUnion data;
|
||||
data.fSignBitInt = rand.nextU();
|
||||
return data.fFloat;
|
||||
}
|
||||
|
||||
/* returns true if a == b as resulting from (int)x. Since it is undefined
|
||||
what to do if the float exceeds 2^32-1, we check for that explicitly.
|
||||
*/
|
||||
static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
|
||||
if (!(x == x)) { // NAN
|
||||
return si == SK_MaxS32 || si == SK_MinS32;
|
||||
}
|
||||
// for out of range, C is undefined, but skia always should return NaN32
|
||||
if (x > SK_MaxS32) {
|
||||
return si == SK_MaxS32;
|
||||
}
|
||||
if (x < -SK_MaxS32) {
|
||||
return si == SK_MinS32;
|
||||
}
|
||||
return si == ni;
|
||||
}
|
||||
|
||||
static void assert_float_equal(skiatest::Reporter* reporter, const char op[],
|
||||
float x, uint32_t ni, uint32_t si) {
|
||||
if (!equal_float_native_skia(x, ni, si)) {
|
||||
SkString desc;
|
||||
desc.printf("%s float %g bits %x native %x skia %x\n", op, x, ni, si);
|
||||
reporter->reportFailed(desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_float_cast(skiatest::Reporter* reporter, float x) {
|
||||
int ix = (int)x;
|
||||
int iix = SkFloatToIntCast(x);
|
||||
assert_float_equal(reporter, "cast", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_floor(skiatest::Reporter* reporter, float x) {
|
||||
int ix = (int)floor(x);
|
||||
int iix = SkFloatToIntFloor(x);
|
||||
assert_float_equal(reporter, "floor", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_round(skiatest::Reporter* reporter, float x) {
|
||||
double xx = x + 0.5; // need intermediate double to avoid temp loss
|
||||
int ix = (int)floor(xx);
|
||||
int iix = SkFloatToIntRound(x);
|
||||
assert_float_equal(reporter, "round", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_ceil(skiatest::Reporter* reporter, float x) {
|
||||
int ix = (int)ceil(x);
|
||||
int iix = SkFloatToIntCeil(x);
|
||||
assert_float_equal(reporter, "ceil", x, ix, iix);
|
||||
}
|
||||
|
||||
static void test_float_conversions(skiatest::Reporter* reporter, float x) {
|
||||
test_float_cast(reporter, x);
|
||||
test_float_floor(reporter, x);
|
||||
test_float_round(reporter, x);
|
||||
test_float_ceil(reporter, x);
|
||||
}
|
||||
|
||||
static void test_int2float(skiatest::Reporter* reporter, int ival) {
|
||||
float x0 = (float)ival;
|
||||
float x1 = SkIntToFloatCast(ival);
|
||||
float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
|
||||
REPORTER_ASSERT(reporter, x0 == x1);
|
||||
REPORTER_ASSERT(reporter, x0 == x2);
|
||||
}
|
||||
|
||||
static void unittest_fastfloat(skiatest::Reporter* reporter) {
|
||||
SkRandom rand;
|
||||
size_t i;
|
||||
|
||||
static const float gFloats[] = {
|
||||
0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
|
||||
0.000000001f, 1000000000.f, // doesn't overflow
|
||||
0.0000000001f, 10000000000.f // does overflow
|
||||
};
|
||||
for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
|
||||
// SkDebugf("---- test floats %g %d\n", gFloats[i], (int)gFloats[i]);
|
||||
test_float_conversions(reporter, gFloats[i]);
|
||||
test_float_conversions(reporter, -gFloats[i]);
|
||||
}
|
||||
|
||||
for (int outer = 0; outer < 100; outer++) {
|
||||
rand.setSeed(outer);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
float x = nextFloat(rand);
|
||||
test_float_conversions(reporter, x);
|
||||
}
|
||||
|
||||
test_int2float(reporter, 0);
|
||||
test_int2float(reporter, 1);
|
||||
test_int2float(reporter, -1);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
// for now only test ints that are 24bits or less, since we don't
|
||||
// round (down) large ints the same as IEEE...
|
||||
int ival = rand.nextU() & 0xFFFFFF;
|
||||
test_int2float(reporter, ival);
|
||||
test_int2float(reporter, -ival);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void test_muldiv255(skiatest::Reporter* reporter) {
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
for (int a = 0; a <= 255; a++) {
|
||||
for (int b = 0; b <= 255; b++) {
|
||||
int ab = a * b;
|
||||
float s = ab / 255.0f;
|
||||
int round = (int)floorf(s + 0.5f);
|
||||
int trunc = (int)floorf(s);
|
||||
|
||||
int iround = SkMulDiv255Round(a, b);
|
||||
int itrunc = SkMulDiv255Trunc(a, b);
|
||||
|
||||
REPORTER_ASSERT(reporter, iround == round);
|
||||
REPORTER_ASSERT(reporter, itrunc == trunc);
|
||||
|
||||
REPORTER_ASSERT(reporter, itrunc <= iround);
|
||||
REPORTER_ASSERT(reporter, iround <= a);
|
||||
REPORTER_ASSERT(reporter, iround <= b);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void TestMath(skiatest::Reporter* reporter) {
|
||||
int i;
|
||||
int32_t x;
|
||||
SkRandom rand;
|
||||
|
||||
// these should not assert
|
||||
SkToS8(127); SkToS8(-128); SkToU8(255);
|
||||
SkToS16(32767); SkToS16(-32768); SkToU16(65535);
|
||||
SkToS32(2*1024*1024); SkToS32(-2*1024*1024); SkToU32(4*1024*1024);
|
||||
|
||||
// these should assert
|
||||
#if 0
|
||||
SkToS8(128);
|
||||
SkToS8(-129);
|
||||
SkToU8(256);
|
||||
SkToU8(-5);
|
||||
|
||||
SkToS16(32768);
|
||||
SkToS16(-32769);
|
||||
SkToU16(65536);
|
||||
SkToU16(-5);
|
||||
|
||||
if (sizeof(size_t) > 4) {
|
||||
SkToS32(4*1024*1024);
|
||||
SkToS32(-4*1024*1024);
|
||||
SkToU32(5*1024*1024);
|
||||
SkToU32(-5);
|
||||
}
|
||||
#endif
|
||||
|
||||
test_muldiv255(reporter);
|
||||
|
||||
{
|
||||
SkScalar x = SK_ScalarNaN;
|
||||
REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
|
||||
}
|
||||
|
||||
for (i = 1; i <= 10; i++) {
|
||||
x = SkCubeRootBits(i*i*i, 11);
|
||||
REPORTER_ASSERT(reporter, x == i);
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(reporter, !"test the reporter");
|
||||
|
||||
x = SkFixedSqrt(SK_Fixed1);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fixed1);
|
||||
x = SkFixedSqrt(SK_Fixed1/4);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fixed1/2);
|
||||
x = SkFixedSqrt(SK_Fixed1*4);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fixed1*2);
|
||||
|
||||
x = SkFractSqrt(SK_Fract1);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fract1);
|
||||
x = SkFractSqrt(SK_Fract1/4);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fract1/2);
|
||||
x = SkFractSqrt(SK_Fract1/16);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fract1/4);
|
||||
|
||||
for (i = 1; i < 100; i++) {
|
||||
x = SkFixedSqrt(SK_Fixed1 * i * i);
|
||||
REPORTER_ASSERT(reporter, x == SK_Fixed1 * i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
int value = rand.nextS16();
|
||||
int max = rand.nextU16();
|
||||
|
||||
int clamp = SkClampMax(value, max);
|
||||
int clamp2 = value < 0 ? 0 : (value > max ? max : value);
|
||||
REPORTER_ASSERT(reporter, clamp == clamp2);
|
||||
}
|
||||
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkPoint p;
|
||||
|
||||
p.setLength(rand.nextS(), rand.nextS(), SK_Scalar1);
|
||||
check_length(reporter, p, SK_Scalar1);
|
||||
p.setLength(rand.nextS() >> 13, rand.nextS() >> 13, SK_Scalar1);
|
||||
check_length(reporter, p, SK_Scalar1);
|
||||
}
|
||||
|
||||
{
|
||||
SkFixed result = SkFixedDiv(100, 100);
|
||||
REPORTER_ASSERT(reporter, result == SK_Fixed1);
|
||||
result = SkFixedDiv(1, SK_Fixed1);
|
||||
REPORTER_ASSERT(reporter, result == 1);
|
||||
}
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
unittest_fastfloat(reporter);
|
||||
#endif
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkFixed numer = rand.nextS();
|
||||
SkFixed denom = rand.nextS();
|
||||
SkFixed result = SkFixedDiv(numer, denom);
|
||||
SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
|
||||
|
||||
(void)SkCLZ(numer);
|
||||
(void)SkCLZ(denom);
|
||||
|
||||
REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
|
||||
if (check > SK_MaxS32) {
|
||||
check = SK_MaxS32;
|
||||
} else if (check < -SK_MaxS32) {
|
||||
check = SK_MinS32;
|
||||
}
|
||||
REPORTER_ASSERT(reporter, result == (int32_t)check);
|
||||
|
||||
result = SkFractDiv(numer, denom);
|
||||
check = ((SkLONGLONG)numer << 30) / denom;
|
||||
|
||||
REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
|
||||
if (check > SK_MaxS32) {
|
||||
check = SK_MaxS32;
|
||||
} else if (check < -SK_MaxS32) {
|
||||
check = SK_MinS32;
|
||||
}
|
||||
REPORTER_ASSERT(reporter, result == (int32_t)check);
|
||||
|
||||
// make them <= 2^24, so we don't overflow in fixmul
|
||||
numer = numer << 8 >> 8;
|
||||
denom = denom << 8 >> 8;
|
||||
|
||||
result = SkFixedMul(numer, denom);
|
||||
SkFixed r2 = symmetric_fixmul(numer, denom);
|
||||
// SkASSERT(result == r2);
|
||||
|
||||
result = SkFixedMul(numer, numer);
|
||||
r2 = SkFixedSquare(numer);
|
||||
REPORTER_ASSERT(reporter, result == r2);
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
if (numer >= 0 && denom >= 0) {
|
||||
SkFixed mean = SkFixedMean(numer, denom);
|
||||
float fm = sk_float_sqrt(sk_float_abs(SkFixedToFloat(numer) * SkFixedToFloat(denom)));
|
||||
SkFixed mean2 = SkFloatToFixed(fm);
|
||||
int diff = SkAbs32(mean - mean2);
|
||||
REPORTER_ASSERT(reporter, diff <= 1);
|
||||
}
|
||||
|
||||
{
|
||||
SkFixed mod = SkFixedMod(numer, denom);
|
||||
float n = SkFixedToFloat(numer);
|
||||
float d = SkFixedToFloat(denom);
|
||||
float m = sk_float_mod(n, d);
|
||||
REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0)); // ensure the same sign
|
||||
int diff = SkAbs32(mod - SkFloatToFixed(m));
|
||||
REPORTER_ASSERT(reporter, (diff >> 7) == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
for (i = 0; i < 100000; i++) {
|
||||
SkFract x = rand.nextU() >> 1;
|
||||
double xx = (double)x / SK_Fract1;
|
||||
SkFract xr = SkFractSqrt(x);
|
||||
SkFract check = SkFloatToFract(sqrt(xx));
|
||||
REPORTER_ASSERT(reporter, xr == check || xr == check-1 || xr == check+1);
|
||||
|
||||
xr = SkFixedSqrt(x);
|
||||
xx = (double)x / SK_Fixed1;
|
||||
check = SkFloatToFixed(sqrt(xx));
|
||||
REPORTER_ASSERT(reporter, xr == check || xr == check-1);
|
||||
|
||||
xr = SkSqrt32(x);
|
||||
xx = (double)x;
|
||||
check = (int32_t)sqrt(xx);
|
||||
REPORTER_ASSERT(reporter, xr == check || xr == check-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SK_SCALAR_IS_FLOAT) && defined(SK_CAN_USE_FLOAT)
|
||||
{
|
||||
SkFixed s, c;
|
||||
s = SkFixedSinCos(0, &c);
|
||||
REPORTER_ASSERT(reporter, s == 0);
|
||||
REPORTER_ASSERT(reporter, c == SK_Fixed1);
|
||||
}
|
||||
|
||||
int maxDiff = 0;
|
||||
for (i = 0; i < 10000; i++) {
|
||||
SkFixed rads = rand.nextS() >> 10;
|
||||
double frads = SkFixedToFloat(rads);
|
||||
|
||||
SkFixed s, c;
|
||||
s = SkScalarSinCos(rads, &c);
|
||||
|
||||
double fs = sin(frads);
|
||||
double fc = cos(frads);
|
||||
|
||||
SkFixed is = SkFloatToFixed(fs);
|
||||
SkFixed ic = SkFloatToFixed(fc);
|
||||
|
||||
maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
|
||||
maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
|
||||
}
|
||||
SkDebugf("SinCos: maximum error = %d\n", maxDiff);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace skiatest {
|
||||
|
||||
class MathTest : public Test {
|
||||
public:
|
||||
static Test* Factory(void*) {
|
||||
return SkNEW(MathTest);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onGetName(SkString* name) {
|
||||
name->set("Math");
|
||||
}
|
||||
|
||||
virtual void onRun(Reporter* reporter) {
|
||||
TestMath(reporter);
|
||||
}
|
||||
};
|
||||
|
||||
static TestRegistry gReg(MathTest::Factory);
|
||||
}
|
||||
|
119
tests/MatrixTest.cpp
Normal file
119
tests/MatrixTest.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "Test.h"
|
||||
#include "SkMatrix.h"
|
||||
|
||||
static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
const float tolerance = 0.000005f;
|
||||
#else
|
||||
const int32_t tolerance = 3;
|
||||
#endif
|
||||
|
||||
return SkScalarAbs(a - b) <= tolerance;
|
||||
}
|
||||
|
||||
static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (!nearly_equal_scalar(a[i], b[i])) {
|
||||
printf("not equal %g %g\n", a[i], b[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_identity(const SkMatrix& m) {
|
||||
SkMatrix identity;
|
||||
identity.reset();
|
||||
return nearly_equal(m, identity);
|
||||
}
|
||||
|
||||
void TestMatrix(skiatest::Reporter* reporter) {
|
||||
SkMatrix mat, inverse, iden1, iden2;
|
||||
|
||||
mat.reset();
|
||||
mat.setTranslate(SK_Scalar1, SK_Scalar1);
|
||||
mat.invert(&inverse);
|
||||
iden1.setConcat(mat, inverse);
|
||||
REPORTER_ASSERT(reporter, is_identity(iden1));
|
||||
|
||||
mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
|
||||
mat.invert(&inverse);
|
||||
iden1.setConcat(mat, inverse);
|
||||
REPORTER_ASSERT(reporter, is_identity(iden1));
|
||||
|
||||
mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
|
||||
mat.invert(&inverse);
|
||||
iden1.setConcat(mat, inverse);
|
||||
REPORTER_ASSERT(reporter, is_identity(iden1));
|
||||
|
||||
mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
|
||||
mat.postRotate(SkIntToScalar(25));
|
||||
REPORTER_ASSERT(reporter, mat.invert(NULL));
|
||||
mat.invert(&inverse);
|
||||
iden1.setConcat(mat, inverse);
|
||||
REPORTER_ASSERT(reporter, is_identity(iden1));
|
||||
iden2.setConcat(inverse, mat);
|
||||
REPORTER_ASSERT(reporter, is_identity(iden2));
|
||||
|
||||
// rectStaysRect test
|
||||
{
|
||||
static const struct {
|
||||
SkScalar m00, m01, m10, m11;
|
||||
bool mStaysRect;
|
||||
}
|
||||
gRectStaysRectSamples[] = {
|
||||
{ 0, 0, 0, 0, false },
|
||||
{ 0, 0, 0, SK_Scalar1, false },
|
||||
{ 0, 0, SK_Scalar1, 0, false },
|
||||
{ 0, 0, SK_Scalar1, SK_Scalar1, false },
|
||||
{ 0, SK_Scalar1, 0, 0, false },
|
||||
{ 0, SK_Scalar1, 0, SK_Scalar1, false },
|
||||
{ 0, SK_Scalar1, SK_Scalar1, 0, true },
|
||||
{ 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false },
|
||||
{ SK_Scalar1, 0, 0, 0, false },
|
||||
{ SK_Scalar1, 0, 0, SK_Scalar1, true },
|
||||
{ SK_Scalar1, 0, SK_Scalar1, 0, false },
|
||||
{ SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false },
|
||||
{ SK_Scalar1, SK_Scalar1, 0, 0, false },
|
||||
{ SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false },
|
||||
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false },
|
||||
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
|
||||
SkMatrix m;
|
||||
|
||||
m.reset();
|
||||
m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
|
||||
m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01);
|
||||
m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10);
|
||||
m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
|
||||
REPORTER_ASSERT(reporter,
|
||||
m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace skiatest {
|
||||
|
||||
class MatrixTest : public Test {
|
||||
public:
|
||||
static Test* Factory(void*) {
|
||||
return SkNEW(MatrixTest);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onGetName(SkString* name) {
|
||||
name->set("Matrix");
|
||||
}
|
||||
|
||||
virtual void onRun(Reporter* reporter) {
|
||||
TestMatrix(reporter);
|
||||
}
|
||||
};
|
||||
|
||||
static TestRegistry gReg(MatrixTest::Factory);
|
||||
}
|
||||
|
144
tests/PackBitsTest.cpp
Normal file
144
tests/PackBitsTest.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
#include "Test.h"
|
||||
#include "SkPackBits.h"
|
||||
|
||||
static const uint16_t gTest0[] = { 0, 0, 1, 1 };
|
||||
static const uint16_t gTest1[] = { 1, 2, 3, 4, 5, 6 };
|
||||
static const uint16_t gTest2[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
|
||||
static const uint16_t gTest3[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
|
||||
|
||||
#include "SkRandom.h"
|
||||
static SkRandom gRand;
|
||||
static void rand_fill(uint16_t buffer[], int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
buffer[i] = (uint16_t)gRand.nextU();
|
||||
}
|
||||
|
||||
static void test_pack16(skiatest::Reporter* reporter) {
|
||||
static const struct {
|
||||
const uint16_t* fSrc;
|
||||
int fCount;
|
||||
} gTests[] = {
|
||||
{ gTest0, SK_ARRAY_COUNT(gTest0) },
|
||||
{ gTest1, SK_ARRAY_COUNT(gTest1) },
|
||||
{ gTest2, SK_ARRAY_COUNT(gTest2) },
|
||||
{ gTest3, SK_ARRAY_COUNT(gTest3) }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); i++) {
|
||||
uint8_t dst[100];
|
||||
size_t dstSize = SkPackBits::Pack16(gTests[i].fSrc,
|
||||
gTests[i].fCount, dst);
|
||||
uint16_t src[100];
|
||||
int srcCount = SkPackBits::Unpack16(dst, dstSize, src);
|
||||
bool match = gTests[i].fCount == srcCount && memcmp(gTests[i].fSrc, src,
|
||||
gTests[i].fCount * sizeof(uint16_t)) == 0;
|
||||
REPORTER_ASSERT(reporter, match);
|
||||
}
|
||||
|
||||
for (int n = 1000; n; n--) {
|
||||
size_t size = 50;
|
||||
uint16_t src[100], src2[100];
|
||||
uint8_t dst[200];
|
||||
rand_fill(src, size);
|
||||
|
||||
size_t dstSize = SkPackBits::Pack16(src, size, dst);
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize16(size);
|
||||
REPORTER_ASSERT(reporter, maxSize >= dstSize);
|
||||
|
||||
int srcCount = SkPackBits::Unpack16(dst, dstSize, src2);
|
||||
REPORTER_ASSERT(reporter, size == srcCount);
|
||||
bool match = memcmp(src, src2, size * sizeof(uint16_t)) == 0;
|
||||
REPORTER_ASSERT(reporter, match);
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t gTest80[] = { 0, 0, 1, 1 };
|
||||
static const uint8_t gTest81[] = { 1, 2, 3, 4, 5, 6 };
|
||||
static const uint8_t gTest82[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
|
||||
static const uint8_t gTest83[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
|
||||
static const uint8_t gTest84[] = { 1, 0, 3, 0, 0, 0, 2, 1, 1, 2 };
|
||||
|
||||
static void rand_fill(uint8_t buffer[], int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
buffer[i] = (uint8_t)((gRand.nextU() >> 8) & 0x3);
|
||||
}
|
||||
|
||||
static void test_pack8(skiatest::Reporter* reporter) {
|
||||
static const struct {
|
||||
const uint8_t* fSrc;
|
||||
int fCount;
|
||||
} gTests[] = {
|
||||
{ gTest80, SK_ARRAY_COUNT(gTest80) },
|
||||
{ gTest81, SK_ARRAY_COUNT(gTest81) },
|
||||
{ gTest82, SK_ARRAY_COUNT(gTest82) },
|
||||
{ gTest83, SK_ARRAY_COUNT(gTest83) },
|
||||
{ gTest84, SK_ARRAY_COUNT(gTest84) }
|
||||
};
|
||||
|
||||
for (size_t i = 4; i < SK_ARRAY_COUNT(gTests); i++) {
|
||||
uint8_t dst[100];
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize8(gTests[i].fCount);
|
||||
size_t dstSize = SkPackBits::Pack8(gTests[i].fSrc,
|
||||
gTests[i].fCount, dst);
|
||||
REPORTER_ASSERT(reporter, dstSize <= maxSize);
|
||||
uint8_t src[100];
|
||||
int srcCount = SkPackBits::Unpack8(dst, dstSize, src);
|
||||
bool match = gTests[i].fCount == srcCount &&
|
||||
memcmp(gTests[i].fSrc, src,
|
||||
gTests[i].fCount * sizeof(uint8_t)) == 0;
|
||||
REPORTER_ASSERT(reporter, match);
|
||||
}
|
||||
|
||||
for (size_t size = 1; size <= 512; size += 1) {
|
||||
for (int n = 200; n; n--) {
|
||||
uint8_t src[600], src2[600];
|
||||
uint8_t dst[600];
|
||||
rand_fill(src, size);
|
||||
|
||||
size_t dstSize = SkPackBits::Pack8(src, size, dst);
|
||||
size_t maxSize = SkPackBits::ComputeMaxSize8(size);
|
||||
REPORTER_ASSERT(reporter, maxSize >= dstSize);
|
||||
|
||||
int srcCount = SkPackBits::Unpack8(dst, dstSize, src2);
|
||||
REPORTER_ASSERT(reporter, size == srcCount);
|
||||
bool match = memcmp(src, src2, size * sizeof(uint8_t)) == 0;
|
||||
REPORTER_ASSERT(reporter, match);
|
||||
|
||||
for (int j = 0; j < 200; j++) {
|
||||
size_t skip = gRand.nextU() % size;
|
||||
size_t write = gRand.nextU() % size;
|
||||
if (skip + write > size) {
|
||||
write = size - skip;
|
||||
}
|
||||
SkPackBits::Unpack8(src, skip, write, dst);
|
||||
bool match = memcmp(src, src2 + skip, write) == 0;
|
||||
REPORTER_ASSERT(reporter, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace skiatest {
|
||||
|
||||
class PackBitsTest : public Test {
|
||||
public:
|
||||
static Test* Factory(void*) {
|
||||
return SkNEW(PackBitsTest);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onGetName(SkString* name) {
|
||||
name->set("PackBits");
|
||||
}
|
||||
|
||||
virtual void onRun(Reporter* reporter) {
|
||||
test_pack8(reporter);
|
||||
test_pack16(reporter);
|
||||
}
|
||||
};
|
||||
|
||||
static TestRegistry gReg(PackBitsTest::Factory);
|
||||
}
|
||||
|
60
tests/Test.cpp
Normal file
60
tests/Test.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "Test.h"
|
||||
|
||||
using namespace skiatest;
|
||||
|
||||
Reporter::Reporter() {
|
||||
this->resetReporting();
|
||||
}
|
||||
|
||||
void Reporter::resetReporting() {
|
||||
fCurrTest = NULL;
|
||||
fTestCount = 0;
|
||||
bzero(fResultCount, sizeof(fResultCount));
|
||||
}
|
||||
|
||||
void Reporter::startTest(Test* test) {
|
||||
SkASSERT(NULL == fCurrTest);
|
||||
fCurrTest = test;
|
||||
this->onStart(test);
|
||||
fTestCount += 1;
|
||||
}
|
||||
|
||||
void Reporter::report(const char desc[], Result result) {
|
||||
if (NULL == desc) {
|
||||
desc = "<no description>";
|
||||
}
|
||||
this->onReport(desc, result);
|
||||
fResultCount[result] += 1;
|
||||
}
|
||||
|
||||
void Reporter::endTest(Test* test) {
|
||||
SkASSERT(test == fCurrTest);
|
||||
this->onEnd(test);
|
||||
fCurrTest = NULL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Test::Test() : fReporter(NULL) {}
|
||||
|
||||
Test::~Test() {
|
||||
fReporter->safeUnref();
|
||||
}
|
||||
|
||||
void Test::setReporter(Reporter* r) {
|
||||
SkRefCnt_SafeAssign(fReporter, r);
|
||||
}
|
||||
|
||||
const char* Test::getName() {
|
||||
if (fName.size() == 0) {
|
||||
this->onGetName(&fName);
|
||||
}
|
||||
return fName.c_str();
|
||||
}
|
||||
|
||||
void Test::run() {
|
||||
fReporter->startTest(this);
|
||||
this->onRun(fReporter);
|
||||
fReporter->endTest(this);
|
||||
}
|
||||
|
98
tests/Test.h
Normal file
98
tests/Test.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef skiatest_Test_DEFINED
|
||||
#define skiatest_Test_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTRegistry.h"
|
||||
|
||||
namespace skiatest {
|
||||
|
||||
class Test;
|
||||
|
||||
class Reporter : public SkRefCnt {
|
||||
public:
|
||||
Reporter();
|
||||
|
||||
enum Result {
|
||||
kPassed, // must begin with 0
|
||||
kFailed,
|
||||
/////
|
||||
kLastResult = kFailed
|
||||
};
|
||||
|
||||
void resetReporting();
|
||||
int countTests() const { return fTestCount; }
|
||||
int countResults(Result r) {
|
||||
SkASSERT((unsigned)r <= kLastResult);
|
||||
return fResultCount[r];
|
||||
}
|
||||
|
||||
void startTest(Test*);
|
||||
void report(const char testDesc[], Result);
|
||||
void endTest(Test*);
|
||||
|
||||
// helpers for tests
|
||||
void assertTrue(bool cond, const char desc[]) {
|
||||
if (!cond) {
|
||||
this->report(desc, kFailed);
|
||||
}
|
||||
}
|
||||
void assertFalse(bool cond, const char desc[]) {
|
||||
if (cond) {
|
||||
this->report(desc, kFailed);
|
||||
}
|
||||
}
|
||||
void reportFailed(const char desc[]) {
|
||||
this->report(desc, kFailed);
|
||||
}
|
||||
void reportFailed(const SkString& desc) {
|
||||
this->report(desc.c_str(), kFailed);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onStart(Test*) {}
|
||||
virtual void onReport(const char desc[], Result) {}
|
||||
virtual void onEnd(Test*) {}
|
||||
|
||||
private:
|
||||
Test* fCurrTest;
|
||||
int fTestCount;
|
||||
int fResultCount[kLastResult+1];
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
class Test {
|
||||
public:
|
||||
Test();
|
||||
virtual ~Test();
|
||||
|
||||
Reporter* getReporter() const { return fReporter; }
|
||||
void setReporter(Reporter*);
|
||||
|
||||
const char* getName();
|
||||
void run();
|
||||
|
||||
protected:
|
||||
virtual void onGetName(SkString*) = 0;
|
||||
virtual void onRun(Reporter*) = 0;
|
||||
|
||||
private:
|
||||
Reporter* fReporter;
|
||||
SkString fName;
|
||||
};
|
||||
|
||||
typedef SkTRegistry<Test*, void*> TestRegistry;
|
||||
}
|
||||
|
||||
#define REPORTER_ASSERT(r, cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
SkString desc; \
|
||||
desc.printf("%s:%d: %s", __FILE__, __LINE__, #cond); \
|
||||
r->reportFailed(desc); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif
|
333
tests/TestXCode/Tests.xcodeproj/project.pbxproj
Normal file
333
tests/TestXCode/Tests.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,333 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 44;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00857F860F56F8EE0078BE26 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00857F730F56F71B0078BE26 /* libcore.a */; };
|
||||
00857F920F56F9170078BE26 /* libmaccore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00857F910F56F9150078BE26 /* libmaccore.a */; };
|
||||
00857FAA0F56F9620078BE26 /* Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FA80F56F9620078BE26 /* Test.cpp */; };
|
||||
00857FAB0F56F9620078BE26 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FA90F56F9620078BE26 /* main.cpp */; };
|
||||
00857FB70F56FD340078BE26 /* MathTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FB60F56FD340078BE26 /* MathTest.cpp */; };
|
||||
008634DC0F579B7A0044DA64 /* PackBitsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */; };
|
||||
008634F10F579E410044DA64 /* MatrixTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008634F00F579E410044DA64 /* MatrixTest.cpp */; };
|
||||
0086350F0F57A3140044DA64 /* UtilsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0086350E0F57A3140044DA64 /* UtilsTest.cpp */; };
|
||||
8DD76F6A0486A84900D96B5E /* Tests.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859E8B029090EE04C91782 /* Tests.1 */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
00857F720F56F71B0078BE26 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = D2AAC046055464E500DB518D;
|
||||
remoteInfo = core;
|
||||
};
|
||||
00857F900F56F9150078BE26 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = D2AAC046055464E500DB518D;
|
||||
remoteInfo = maccore;
|
||||
};
|
||||
0086351C0F57A51A0044DA64 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2AAC045055464E500DB518D /* core */;
|
||||
remoteInfo = core;
|
||||
};
|
||||
0086351E0F57A5200044DA64 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2AAC045055464E500DB518D /* maccore */;
|
||||
remoteInfo = maccore;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
8DD76F6A0486A84900D96B5E /* Tests.1 in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
00857F630F56F4220078BE26 /* Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Test.h; path = ../Test.h; sourceTree = SOURCE_ROOT; };
|
||||
00857F6B0F56F71B0078BE26 /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = core.xcodeproj; path = ../../xcode/core/core.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||
00857F890F56F9150078BE26 /* maccore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = maccore.xcodeproj; path = ../../xcode/maccore/maccore.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||
00857FA80F56F9620078BE26 /* Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Test.cpp; path = ../Test.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00857FA90F56F9620078BE26 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../main.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00857FB60F56FD340078BE26 /* MathTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MathTest.cpp; path = ../MathTest.cpp; sourceTree = SOURCE_ROOT; };
|
||||
008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PackBitsTest.cpp; path = ../PackBitsTest.cpp; sourceTree = SOURCE_ROOT; };
|
||||
008634F00F579E410044DA64 /* MatrixTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MatrixTest.cpp; path = ../MatrixTest.cpp; sourceTree = SOURCE_ROOT; };
|
||||
0086350E0F57A3140044DA64 /* UtilsTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UtilsTest.cpp; path = ../UtilsTest.cpp; sourceTree = SOURCE_ROOT; };
|
||||
8DD76F6C0486A84900D96B5E /* Tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Tests; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C6859E8B029090EE04C91782 /* Tests.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = Tests.1; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8DD76F660486A84900D96B5E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00857F860F56F8EE0078BE26 /* libcore.a in Frameworks */,
|
||||
00857F920F56F9170078BE26 /* libmaccore.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
00857F6C0F56F71B0078BE26 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00857F730F56F71B0078BE26 /* libcore.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00857F8A0F56F9150078BE26 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00857F910F56F9150078BE26 /* libmaccore.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7794FE84155DC02AAC07 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00857F890F56F9150078BE26 /* maccore.xcodeproj */,
|
||||
00857F6B0F56F71B0078BE26 /* core.xcodeproj */,
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
C6859E8C029090F304C91782 /* Documentation */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = Tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00857FA80F56F9620078BE26 /* Test.cpp */,
|
||||
00857FA90F56F9620078BE26 /* main.cpp */,
|
||||
00857F630F56F4220078BE26 /* Test.h */,
|
||||
00857FB60F56FD340078BE26 /* MathTest.cpp */,
|
||||
0086350E0F57A3140044DA64 /* UtilsTest.cpp */,
|
||||
008634F00F579E410044DA64 /* MatrixTest.cpp */,
|
||||
008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8DD76F6C0486A84900D96B5E /* Tests */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C6859E8C029090F304C91782 /* Documentation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C6859E8B029090EE04C91782 /* Tests.1 */,
|
||||
);
|
||||
name = Documentation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76F620486A84900D96B5E /* Tests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Tests" */;
|
||||
buildPhases = (
|
||||
8DD76F640486A84900D96B5E /* Sources */,
|
||||
8DD76F660486A84900D96B5E /* Frameworks */,
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0086351D0F57A51A0044DA64 /* PBXTargetDependency */,
|
||||
0086351F0F57A5200044DA64 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Tests;
|
||||
productInstallPath = "$(HOME)/bin";
|
||||
productName = Tests;
|
||||
productReference = 8DD76F6C0486A84900D96B5E /* Tests */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Tests" */;
|
||||
compatibilityVersion = "Xcode 3.0";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* Tests */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 00857F6C0F56F71B0078BE26 /* Products */;
|
||||
ProjectRef = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00857F8A0F56F9150078BE26 /* Products */;
|
||||
ProjectRef = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8DD76F620486A84900D96B5E /* Tests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
00857F730F56F71B0078BE26 /* libcore.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libcore.a;
|
||||
remoteRef = 00857F720F56F71B0078BE26 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00857F910F56F9150078BE26 /* libmaccore.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libmaccore.a;
|
||||
remoteRef = 00857F900F56F9150078BE26 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8DD76F640486A84900D96B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00857FAA0F56F9620078BE26 /* Test.cpp in Sources */,
|
||||
00857FAB0F56F9620078BE26 /* main.cpp in Sources */,
|
||||
00857FB70F56FD340078BE26 /* MathTest.cpp in Sources */,
|
||||
008634DC0F579B7A0044DA64 /* PackBitsTest.cpp in Sources */,
|
||||
008634F10F579E410044DA64 /* MatrixTest.cpp in Sources */,
|
||||
0086350F0F57A3140044DA64 /* UtilsTest.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0086351D0F57A51A0044DA64 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = core;
|
||||
targetProxy = 0086351C0F57A51A0044DA64 /* PBXContainerItemProxy */;
|
||||
};
|
||||
0086351F0F57A5200044DA64 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = maccore;
|
||||
targetProxy = 0086351E0F57A5200044DA64 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DEB923208733DC60010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_GLIBCXX_DEBUG=1",
|
||||
"_GLIBCXX_DEBUG_PEDANTIC=1",
|
||||
);
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
PRODUCT_NAME = Tests;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB923308733DC60010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
PRODUCT_NAME = Tests;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB923608733DC60010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "../../../**";
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
PREBINDING = NO;
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
|
||||
VALID_ARCHS = "i386 x86_64";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB923708733DC60010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "../../../**";
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
PREBINDING = NO;
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
|
||||
VALID_ARCHS = "i386 x86_64";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB923208733DC60010E9CD /* Debug */,
|
||||
1DEB923308733DC60010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB923608733DC60010E9CD /* Debug */,
|
||||
1DEB923708733DC60010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
}
|
130
tests/UtilsTest.cpp
Normal file
130
tests/UtilsTest.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include "Test.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkTSearch.h"
|
||||
#include "SkTSort.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
#define kSEARCH_COUNT 91
|
||||
|
||||
static void test_search(skiatest::Reporter* reporter) {
|
||||
int i, array[kSEARCH_COUNT];
|
||||
SkRandom rand;
|
||||
|
||||
for (i = 0; i < kSEARCH_COUNT; i++) {
|
||||
array[i] = rand.nextS();
|
||||
}
|
||||
|
||||
SkTHeapSort<int>(array, kSEARCH_COUNT);
|
||||
// make sure we got sorted properly
|
||||
for (i = 1; i < kSEARCH_COUNT; i++) {
|
||||
REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
|
||||
}
|
||||
|
||||
// make sure we can find all of our values
|
||||
for (i = 0; i < kSEARCH_COUNT; i++) {
|
||||
int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
|
||||
REPORTER_ASSERT(reporter, index == i);
|
||||
}
|
||||
|
||||
// make sure that random values are either found, or the correct
|
||||
// insertion index is returned
|
||||
for (i = 0; i < 10000; i++) {
|
||||
int value = rand.nextS();
|
||||
int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
|
||||
|
||||
if (index >= 0) {
|
||||
REPORTER_ASSERT(reporter,
|
||||
index < kSEARCH_COUNT && array[index] == value);
|
||||
} else {
|
||||
index = ~index;
|
||||
REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
|
||||
if (index < kSEARCH_COUNT) {
|
||||
REPORTER_ASSERT(reporter, value < array[index]);
|
||||
if (index > 0) {
|
||||
REPORTER_ASSERT(reporter, value > array[index - 1]);
|
||||
}
|
||||
} else {
|
||||
// we should append the new value
|
||||
REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_utf16(skiatest::Reporter* reporter) {
|
||||
static const SkUnichar gUni[] = {
|
||||
0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
|
||||
};
|
||||
|
||||
uint16_t buf[2];
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) {
|
||||
size_t count = SkUTF16_FromUnichar(gUni[i], buf);
|
||||
REPORTER_ASSERT(reporter, count == 2);
|
||||
size_t count2 = SkUTF16_CountUnichars(buf, 2);
|
||||
REPORTER_ASSERT(reporter, count2 == 1);
|
||||
const uint16_t* ptr = buf;
|
||||
SkUnichar c = SkUTF16_NextUnichar(&ptr);
|
||||
REPORTER_ASSERT(reporter, c == gUni[i]);
|
||||
REPORTER_ASSERT(reporter, ptr - buf == 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void TestUTF(skiatest::Reporter* reporter) {
|
||||
static const struct {
|
||||
const char* fUtf8;
|
||||
SkUnichar fUni;
|
||||
} gTest[] = {
|
||||
{ "a", 'a' },
|
||||
{ "\x7f", 0x7f },
|
||||
{ "\xC2\x80", 0x80 },
|
||||
{ "\xC3\x83", (3 << 6) | 3 },
|
||||
{ "\xDF\xBF", 0x7ff },
|
||||
{ "\xE0\xA0\x80", 0x800 },
|
||||
{ "\xE0\xB0\xB8", 0xC38 },
|
||||
{ "\xE3\x83\x83", (3 << 12) | (3 << 6) | 3 },
|
||||
{ "\xEF\xBF\xBF", 0xFFFF },
|
||||
{ "\xF0\x90\x80\x80", 0x10000 },
|
||||
{ "\xF3\x83\x83\x83", (3 << 18) | (3 << 12) | (3 << 6) | 3 }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) {
|
||||
const char* p = gTest[i].fUtf8;
|
||||
int n = SkUTF8_CountUnichars(p);
|
||||
SkUnichar u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
|
||||
SkUnichar u1 = SkUTF8_NextUnichar(&p);
|
||||
|
||||
REPORTER_ASSERT(reporter, n == 1);
|
||||
REPORTER_ASSERT(reporter, u0 == u1);
|
||||
REPORTER_ASSERT(reporter, u0 == gTest[i].fUni);
|
||||
REPORTER_ASSERT(reporter,
|
||||
p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
|
||||
}
|
||||
|
||||
test_utf16(reporter);
|
||||
test_search(reporter);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace skiatest {
|
||||
|
||||
class UtfTest : public Test {
|
||||
public:
|
||||
static Test* Factory(void*) {
|
||||
return SkNEW(UtfTest);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onGetName(SkString* name) {
|
||||
name->set("UTF");
|
||||
}
|
||||
|
||||
virtual void onRun(Reporter* reporter) {
|
||||
TestUTF(reporter);
|
||||
}
|
||||
};
|
||||
|
||||
static TestRegistry gReg(UtfTest::Factory);
|
||||
}
|
||||
|
67
tests/main.cpp
Normal file
67
tests/main.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
using namespace skiatest;
|
||||
|
||||
class Iter {
|
||||
public:
|
||||
Iter(Reporter* r) : fReporter(r) {
|
||||
r->ref();
|
||||
fReg = TestRegistry::Head();
|
||||
}
|
||||
|
||||
~Iter() {
|
||||
fReporter->unref();
|
||||
}
|
||||
|
||||
Test* next() {
|
||||
if (fReg) {
|
||||
TestRegistry::Factory fact = fReg->factory();
|
||||
fReg = fReg->next();
|
||||
Test* test = fact(NULL);
|
||||
test->setReporter(fReporter);
|
||||
return test;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
Reporter* fReporter;
|
||||
const TestRegistry* fReg;
|
||||
};
|
||||
|
||||
static const char* result2string(Reporter::Result result) {
|
||||
return result == Reporter::kPassed ? "passed" : "FAILED";
|
||||
}
|
||||
|
||||
class PrintfReporter : public Reporter {
|
||||
protected:
|
||||
virtual void onStart(Test* test) {
|
||||
printf("Running %s...\n", test->getName());
|
||||
}
|
||||
virtual void onReport(const char desc[], Reporter::Result result) {
|
||||
printf("\t%s: %s\n", result2string(result), desc);
|
||||
}
|
||||
virtual void onEnd(Test* test) {}
|
||||
};
|
||||
|
||||
int main (int argc, char * const argv[]) {
|
||||
PrintfReporter reporter;
|
||||
Iter iter(&reporter);
|
||||
Test* test;
|
||||
|
||||
while ((test = iter.next()) != NULL) {
|
||||
test->run();
|
||||
SkDELETE(test);
|
||||
}
|
||||
|
||||
int total = reporter.countTests();
|
||||
int passed = reporter.countResults(Reporter::kPassed);
|
||||
int failed = reporter.countResults(Reporter::kFailed);
|
||||
printf("Tests=%d Passed=%d (%g%%) Failed=%d (%g%%)\n", total,
|
||||
passed, passed * 100.f / total,
|
||||
failed, failed * 100.f / total);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user