add initial unittests for Path
add operator== for paths
still need to implement isRect!



git-svn-id: http://skia.googlecode.com/svn/trunk@99 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/Makefile b/Makefile
index 94528bb..188e915 100644
--- a/Makefile
+++ b/Makefile
@@ -91,7 +91,8 @@
 ##############################################################################
 
 TESTS_SRCS := GeometryTest.cpp MathTest.cpp MatrixTest.cpp PackBitsTest.cpp \
-              Sk64Test.cpp StringTest.cpp Test.cpp UtilsTest.cpp main.cpp
+              Sk64Test.cpp StringTest.cpp Test.cpp UtilsTest.cpp PathTest.cpp \
+              main.cpp
 TESTS_SRCS := $(addprefix tests/, $(TESTS_SRCS))
 
 TESTS_OBJS := $(TESTS_SRCS:.cpp=.o)
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index e2409ad..4cedcde 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -37,6 +37,11 @@
     ~SkPath();
 
     SkPath& operator=(const SkPath&);
+    
+    friend bool operator==(const SkPath&, const SkPath&);
+    friend bool operator!=(const SkPath& a, const SkPath& b) {
+        return !(a == b);
+    }
 
     enum FillType {
         /** Specifies that "inside" is computed by a non-zero sum of signed
@@ -538,7 +543,6 @@
 #ifdef SK_DEBUG
   /** @cond UNIT_TEST */
     void dump(bool forceClose, const char title[] = NULL) const;
-    static void UnitTest();
   /** @endcond */
 #endif
 
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp
index b2e6cbf..ff41f0c 100644
--- a/src/core/SkGraphics.cpp
+++ b/src/core/SkGraphics.cpp
@@ -344,7 +344,6 @@
         const char* fTypeName;
         void (*fUnitTest)();
     } gUnitTests[] = {
-        unittestline(SkPath),
         unittestline(SkPathMeasure),
         unittestline(SkStream),
         unittestline(SkWStream),
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 82eb980..de90896 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -114,6 +114,11 @@
     return *this;
 }
 
+bool operator==(const SkPath& a, const SkPath& b) {
+    return &a == &b ||
+        (a.fFillType == b.fFillType && a.fVerbs == b.fVerbs && a.fPts == b.fPts);
+}
+
 void SkPath::swap(SkPath& other) {
     SkASSERT(&other != NULL);
 
@@ -151,7 +156,7 @@
 
 bool SkPath::isRect(SkRect*) const {
     SkDEBUGCODE(this->validate();)
-
+    
     SkASSERT(!"unimplemented");
     return false;
 }
@@ -1287,57 +1292,6 @@
     }
 }
 
-#if 0   // test to ensure that the iterator returns the same data as the path
-void SkPath::test() const
-{
-    Iter    iter(*this, false);
-    SkPoint pts[4];
-    Verb    verb;
-
-    const uint8_t*  verbs = fVerbs.begin();
-    const SkPoint*  points = fPts.begin();
-
-    while ((verb = iter.next(pts)) != kDone_Verb)
-    {
-        SkASSERT(*verbs == verb);
-        verbs += 1;
-
-        int count;
-        switch (verb) {
-        case kMove_Verb:
-            count = 1;
-            break;
-        case kLine_Verb:
-            count = 2;
-            break;
-        case kQuad_Verb:
-            count = 3;
-            break;
-        case kCubic_Verb:
-            count = 4;
-            break;
-        case kClose_Verb:
-        default:
-            count = 0;
-            break;
-        }
-        if (count > 1)
-            points -= 1;
-        SkASSERT(memcmp(pts, points, count * sizeof(SkPoint)) == 0);
-        points += count;
-    }
-
-    int vc = fVerbs.count(), pc = fPts.count();
-    if (vc && fVerbs.begin()[vc-1] == kMove_Verb)
-    {
-        vc -= 1;
-        pc -= 1;
-    }
-    SkASSERT(verbs - fVerbs.begin() == vc);
-    SkASSERT(points - fPts.begin() == pc);
-}
-#endif
-
 void SkPath::dump(bool forceClose, const char title[]) const {
     Iter    iter(*this, forceClose);
     SkPoint pts[4];
@@ -1398,41 +1352,4 @@
     SkDebugf("path: done %s\n", title ? title : "");
 }
 
-#include "SkTSort.h"
-
-void SkPath::UnitTest() {
-#ifdef SK_SUPPORT_UNITTEST
-    SkPath  p;
-    SkRect  r;
-
-    r.set(0, 0, 10, 20);
-    p.addRect(r);
-    p.dump(false);
-    p.dump(true);
-
-    {
-        int array[] = { 5, 3, 7, 2, 6, 1, 2, 9, 5, 0 };
-        int i;
-
-        for (i = 0; i < (int)SK_ARRAY_COUNT(array); i++) {
-            SkDebugf(" %d", array[i]);
-        }
-        SkDebugf("\n");
-        SkTHeapSort<int>(array, SK_ARRAY_COUNT(array));
-        for (i = 0; i < (int)SK_ARRAY_COUNT(array); i++)
-            SkDebugf(" %d", array[i]);
-        SkDebugf("\n");
-    }
-
-    {
-        SkPath  p;
-        SkPoint pt;
-
-        p.moveTo(SK_Scalar1, 0);
-        p.getLastPt(&pt);
-        SkASSERT(pt.fX == SK_Scalar1);
-    }
-#endif
-}
-
 #endif
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
new file mode 100644
index 0000000..383ad03
--- /dev/null
+++ b/tests/PathTest.cpp
@@ -0,0 +1,61 @@
+#include "Test.h"
+#include "SkPath.h"
+
+static void TestPath(skiatest::Reporter* reporter) {
+    SkPath  p, p2;
+    SkRect  bounds, bounds2;
+    
+    REPORTER_ASSERT(reporter, p.isEmpty());
+    REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
+    REPORTER_ASSERT(reporter, !p.isInverseFillType());
+    REPORTER_ASSERT(reporter, p == p2);
+    REPORTER_ASSERT(reporter, !(p != p2));
+
+    // initialize bounds to not-empty
+    bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
+    p.computeBounds(&bounds, SkPath::kFast_BoundsType);
+    REPORTER_ASSERT(reporter, bounds.isEmpty());
+    
+    bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
+    p.addRect(bounds);
+    bounds2.setEmpty();
+    p.computeBounds(&bounds2, SkPath::kFast_BoundsType);
+    REPORTER_ASSERT(reporter, bounds == bounds2);
+
+    REPORTER_ASSERT(reporter, p != p2);
+    REPORTER_ASSERT(reporter, !(p == p2));
+
+    // does getPoints return the right result
+    REPORTER_ASSERT(reporter, p.getPoints(NULL, 5) == 4);
+    SkPoint pts[4];
+    int count = p.getPoints(pts, 4);
+    REPORTER_ASSERT(reporter, count == 4);
+    bounds2.set(pts, 4);
+    REPORTER_ASSERT(reporter, bounds == bounds2);
+    
+    bounds.offset(SK_Scalar1*3, SK_Scalar1*4);
+    p.offset(SK_Scalar1*3, SK_Scalar1*4);
+    p.computeBounds(&bounds2, SkPath::kFast_BoundsType);
+    REPORTER_ASSERT(reporter, bounds == bounds2);
+
+#if 0 // isRect needs to be implemented
+    REPORTER_ASSERT(reporter, p.isRect(NULL));
+    bounds.setEmpty();
+    REPORTER_ASSERT(reporter, p.isRect(&bounds2));
+    REPORTER_ASSERT(reporter, bounds == bounds2);
+    
+    // now force p to not be a rect
+    bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2);
+    p.addRect(bounds);
+    REPORTER_ASSERT(reporter, !p.isRect(NULL));
+#endif
+
+    SkPoint pt;
+
+    p.moveTo(SK_Scalar1, 0);
+    p.getLastPt(&pt);
+    REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Path", PathTestClass, TestPath)
diff --git a/tests/TestXCode/Tests.xcodeproj/project.pbxproj b/tests/TestXCode/Tests.xcodeproj/project.pbxproj
index 7d7b924..cc2448a 100644
--- a/tests/TestXCode/Tests.xcodeproj/project.pbxproj
+++ b/tests/TestXCode/Tests.xcodeproj/project.pbxproj
@@ -18,6 +18,7 @@
 		00A9BF860F584CF30091AD2D /* Sk64Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BF850F584CF30091AD2D /* Sk64Test.cpp */; };
 		00A9BFA30F584E150091AD2D /* StringTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BFA20F584E150091AD2D /* StringTest.cpp */; };
 		00A9BFBC0F5851570091AD2D /* GeometryTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */; };
+		276D93080F5B9FEA0081B3B9 /* PathTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 276D93070F5B9FEA0081B3B9 /* PathTest.cpp */; };
 		8DD76F6A0486A84900D96B5E /* Tests.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859E8B029090EE04C91782 /* Tests.1 */; };
 /* End PBXBuildFile section */
 
@@ -79,6 +80,7 @@
 		00A9BFA20F584E150091AD2D /* StringTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringTest.cpp; path = ../StringTest.cpp; sourceTree = SOURCE_ROOT; };
 		00A9BFA60F584F200091AD2D /* TestClassDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestClassDef.h; path = ../TestClassDef.h; sourceTree = SOURCE_ROOT; };
 		00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeometryTest.cpp; path = ../GeometryTest.cpp; sourceTree = SOURCE_ROOT; };
+		276D93070F5B9FEA0081B3B9 /* PathTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathTest.cpp; path = ../PathTest.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 */
@@ -127,6 +129,7 @@
 		08FB7795FE84155DC02AAC07 /* Source */ = {
 			isa = PBXGroup;
 			children = (
+				276D93070F5B9FEA0081B3B9 /* PathTest.cpp */,
 				00A9BF850F584CF30091AD2D /* Sk64Test.cpp */,
 				00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */,
 				00A9BFA20F584E150091AD2D /* StringTest.cpp */,
@@ -239,6 +242,7 @@
 				00A9BF860F584CF30091AD2D /* Sk64Test.cpp in Sources */,
 				00A9BFA30F584E150091AD2D /* StringTest.cpp in Sources */,
 				00A9BFBC0F5851570091AD2D /* GeometryTest.cpp in Sources */,
+				276D93080F5B9FEA0081B3B9 /* PathTest.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};