Index: tests/ValueTest.cpp |
diff --git a/tests/ValueTest.cpp b/tests/ValueTest.cpp |
index 220ef2f9aeceb43d318a2c2f3c250a837c9c25d4..18b5e371128e317bcb45fae80cfd152da805e28b 100644 |
--- a/tests/ValueTest.cpp |
+++ b/tests/ValueTest.cpp |
@@ -5,5 +5,131 @@ |
* found in the LICENSE file. |
*/ |
-#include "Test.h" |
+#include "SkArithmeticMode.h" |
+#include "SkLerpXfermode.h" |
+#include "SkPixelXorXfermode.h" |
+#include "SkStream.h" |
#include "SkValue.h" |
+#include "SkXfermode.h" |
+#include "Test.h" |
+ |
+static void print_value(bool verbose, const SkValue&); |
+ |
+static const SkValue::Type example_type = SkValue::Type(0x80000001); |
+ |
+enum { kExampleS32, kExampleF32, kExampleU32, kExampleObject}; |
+ |
+#define EXAMPLES(FN) \ |
+ FN(kExampleS32, S32, s32, -123) \ |
+ FN(kExampleF32, F32, f32, 0.5f) \ |
+ FN(kExampleU32, U32, u32, 1234) \ |
+ |
+static SkValue make_example(skiatest::Reporter* r, int level = 4) { |
+ auto value = SkValue::Object(example_type); |
+ REPORTER_ASSERT(r, value.set(kExampleU32, SkValue::FromU32(1000))); |
+ |
+ #define FN(KEY, FNAME, MNAME, VALUE) \ |
+ REPORTER_ASSERT(r, value.set(KEY, SkValue::From##FNAME(VALUE))); |
+ EXAMPLES(FN) |
+ #undef FN |
+ if (level > 0) { |
+ value.set(kExampleObject, make_example(r, 0)); |
+ value.set(kExampleObject, make_example(r, level - 1)); // replace |
+ } |
+ return value; |
+} |
+ |
+DEF_TEST(Value_Test, r) { |
+ SkValue val = make_example(r); |
+ REPORTER_ASSERT(r, example_type == val.type()); |
+ REPORTER_ASSERT(r, val.set(4321, SkValue())); |
+ SkValue valCopy = val; |
+ REPORTER_ASSERT(r, example_type == valCopy.type()); |
+ REPORTER_ASSERT(r, !valCopy.set(12345, SkValue())); |
+ REPORTER_ASSERT(r, !val.set(123456, SkValue())); |
+ #define FN(KEY, FNAME, MNAME, VALUE) { \ |
+ const SkValue* v = val.get(KEY); \ |
+ REPORTER_ASSERT(r, v && VALUE == v->MNAME()); \ |
+ } |
+ EXAMPLES(FN) |
+ #undef FN |
+ print_value(r->verbose(), val); |
+} |
+ |
+template <class T> |
+void test_value(skiatest::Reporter* r, T* object, SkValue::Type type) { |
+ const SkValue val = object->asValue(); |
+ object->unref(); |
+ REPORTER_ASSERT(r, type == val.type()); |
+ print_value(r->verbose(), val); |
+} |
+ |
+DEF_TEST(Value_Xfermode, r) { |
+ // just test that these code paths work until we hook them up to a DM sink. |
+ test_value(r, SkXfermode::Create(SkXfermode::kDstOver_Mode), |
+ SkValue::ProcCoeffXfermode); |
+ test_value(r, SkArithmeticMode::Create(0.125f, 0.25f, 0.375f, 0.5f, true), |
+ SkValue::ArithmeticXfermode); |
+ test_value(r, SkLerpXfermode::Create(1.0f/3.0f), SkValue::LerpXfermode); |
+ test_value(r, SkPixelXorXfermode::Create(0xFF00FF00), |
+ SkValue::PixelXorXfermode); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+// Conditional print. Always evaluate the arguments. |
+static void do_nothing(const char*, ...) {} |
+#define CPRINT(DO_PRINT) ((DO_PRINT) ? SkDebugf : do_nothing) |
+ |
+static void dump(bool verbose, int indent, const SkValue&); |
+static void dump_object(bool verbose, int indent, |
+ const char* name, const SkValue& val) { |
+ CPRINT(verbose)("[ \"%s\", {\n", name); |
+ // todo: sort keys |
+ val.foreach([=](SkValue::Key k, const SkValue& v){ |
+ for (int i = 0; i < indent; ++i) { |
+ CPRINT(verbose)(" "); |
+ } |
+ CPRINT(verbose)(" \"key_%u\" : ", k); |
+ dump(verbose, indent + 1, v); |
+ CPRINT(verbose)("\n"); |
+ }); |
+ for (int i = 0; i < indent; ++i) { |
+ CPRINT(verbose)(" "); |
+ } |
+ CPRINT(verbose)("} ],"); |
+} |
+ |
+static void dump(bool verbose, int indent, const SkValue& val) { |
+ switch (val.type()) { |
+ case SkValue::Null: |
+ CPRINT(verbose)("[ \"Null\", null ],"); |
+ return; |
+ case SkValue::S32: |
+ CPRINT(verbose)("[ \"S32\", %d ],", val.s32()); |
+ return; |
+ case SkValue::U32: |
+ CPRINT(verbose)("[ \"U32\", %u ],", val.u32()); |
+ return; |
+ case SkValue::F32: |
+ CPRINT(verbose)("[ \"F32\", %.9g ],", val.f32()); |
+ return; |
+ #define FN(OBJECT) \ |
+ case SkValue::OBJECT: dump_object(verbose, indent, #OBJECT, val); return; |
+ SK_VALUE_OBJECT_TYPES(FN) |
+ #undef FN |
+ default: |
+ if (val.type() >= 0x80000000) { |
+ SkString object = SkStringPrintf("Test_0x%X", val.type()); |
+ dump_object(verbose, indent, object.c_str(), val); |
+ return; |
+ } |
+ SkASSERT(false); |
+ } |
+} |
+ |
+static void print_value(bool verbose, const SkValue& val) { |
+ CPRINT(verbose)("\n"); |
+ dump(verbose, 0, val); |
+ CPRINT(verbose)("\n"); |
+} |