Finish renaming a/b/p to source/target/amount. Start splitting up functions for array...
[string-lerp.git] / tests / string-lerp.js
index 2e7f01f..0a68921 100644 (file)
@@ -1,6 +1,9 @@
 var JS = this.JS || require('jstest');
 var m = require('../string-lerp');
 
+var HALF_POOS = /\uD83D\uD83D|\uDCA9\uDCA9|\uD83D$/;
+var UNUSUAL_Q = 'q\u0307\u0323';
+
 JS.Test.describe('fast lerp', function () { with (this) {
     var lerp = m.fastLerp;
     var A = "Do you like green eggs and ham?";
@@ -38,6 +41,22 @@ JS.Test.describe('fast lerp', function () { with (this) {
         assertEqual("I do not like tn eggs and ham?", lerp(A, B, 0.5));
         assertEqual("I do not like them, Sam-I-am?", lerp(A, B, 0.98));
     }});
+
+    it("doesn't make half a poo", function () { with (this) {
+        var poos = "\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9";
+        assertEqual("\uD83D\uDCA9\uD83D\uDCA9", lerp("", poos, 0.5));
+        assertEqual("\uD83D\uDCA9", lerp("", poos, 0.35));
+
+        for (var i = 0; i <= 1; i += 1/256)
+            assertNot(lerp("", poos, i).match(HALF_POOS));
+    }});
+
+    it("doesn't misplace combining marks", function () { with (this) {
+        for (var i = 0; i <= 1; i += 1/256) {
+            var r = lerp("a", UNUSUAL_Q, i);
+            assert(r === "a" || r === UNUSUAL_Q);
+        }
+    }});
 }});
 
 JS.Test.describe('diff lerp', function () { with (this) {
@@ -73,9 +92,43 @@ JS.Test.describe('diff lerp', function () { with (this) {
     }});
 
     it("edits strings", function () { with (this) {
-        assertEqual("Do you like green eggsSam-I-am.", lerp(A, B, 0.3));
-        assertEqual("Do you like green Sam-I-am.", lerp(A, B, 0.5));
-        assertEqual("do not like them, Sam-I-am.", lerp(A, B, 0.9));
+        assertEqual(A, lerp(A, B, 0.01));
+        assertEqual("I do not like treen eggs and ham?", lerp(A, B, 0.3));
+        assertEqual("I do not like them, eggs and ham?", lerp(A, B, 0.5));
+        assertEqual("I do not like them, Sam-Iham?", lerp(A, B, 0.9));
+        assertEqual(B, lerp(A, B, 0.99));
+    }});
+
+    it("doesn't make half a poo", function () { with (this) {
+        var poos = "\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9";
+        assertEqual("\uD83D\uDCA9\uD83D\uDCA9", lerp("", poos, 0.5));
+        assertEqual("\uD83D\uDCA9", lerp("", poos, 0.35));
+
+        for (var i = 0; i <= 1; i += 1/256)
+            assertNot(lerp("", poos, i).match(HALF_POOS));
+    }});
+
+    it("doesn't misplace combining marks", function () { with (this) {
+        for (var i = 0; i <= 1; i += 1/256) {
+            var r = lerp("a", UNUSUAL_Q, i);
+            assert(r === "a" || r === UNUSUAL_Q);
+        }
+    }});
+
+    it("prefers ins/del to sub/sub", function () { with (this) {
+        // When the cost is uniform this string can be transformed by
+        // rewriting the whole thing for the same cost as deleting the
+        // front and adding to the back. But visually, we'd rather do
+        // the latter.
+        assertEqual("core", lerp("hard core", "core dump", 0.50));
+    }});
+
+    it("weights ins/del cheaper than sub", function () { with (this) {
+        // When the cost is uniform it is cheaper to rewrite the
+        // former into the latter. But we'd rather keep the "core" for
+        // visual reasons, so we need to make sure we have unequal
+        // costs.
+        assertEqual("core", lerp("apple core", "core dump", 0.51));
     }});
 }});
 
@@ -116,3 +169,36 @@ JS.Test.describe('numeric lerp', function () { with (this) {
         assertEqual("Chapter 5. The sky was rgb(0, 0, 128).", lerp(A, B, 0.5));
     }});
 }});
+
+JS.Test.describe('fast lerp', function () { with (this) {
+    var lerp = m.lerp;
+    var A = "Do you like green eggs and ham?";
+    var B = "I do not like them, Sam-I-am.";
+
+    it("handles empty strings", function () { with (this) {
+        assertEqual("", lerp("", "", -1));
+        assertEqual("", lerp("", "", 0));
+        assertEqual("", lerp("", "", 0.5));
+        assertEqual("", lerp("", "", 1));
+        assertEqual("", lerp("", "", 2));
+    }});
+
+    it("maintains identity", function () { with (this) {
+        for (var i = -1; i < 2; i += 1/1024) {
+            assertEqual(A, lerp(A, A, i));
+            assertEqual(B, lerp(B, B, i));
+        }
+    }});
+
+    it("handles lows", function () { with (this) {
+        assertEqual(A, lerp(A, B, -Infinity));
+        assertEqual(A, lerp(A, B, -1));
+        assertEqual(A, lerp(A, B, 0));
+    }});
+
+    it("handles highs", function () { with (this) {
+        assertEqual(B, lerp(A, B, 1));
+        assertEqual(B, lerp(A, B, 2));
+        assertEqual(B, lerp(A, B, Infinity));
+    }});
+}});