Custom jshint configuration.
[string-lerp.git] / tests / string-lerp.js
1 /*global require, it, assert, assertEqual, assertNot */
2 /*jshint -W085 */ // "Don't use 'with'."
3
4 var JS = this.JS || require('jstest');
5 var stringLerp = require('../string-lerp');
6
7 var HALF_POOS = /\uD83D\uD83D|\uDCA9\uDCA9|\uD83D$/;
8 var UNUSUAL_Q = 'q\u0307\u0323';
9 var A = "Do you like green eggs and ham?";
10 var B = "I do not like them, Sam-I-am.";
11
12 function itHandlesBaseCases (parent, lerp) { with (parent) {
13 it("handles empty strings", function () { with (this) {
14 assertEqual("", lerp("", "", -1));
15 assertEqual("", lerp("", "", 0));
16 assertEqual("", lerp("", "", 0.5));
17 assertEqual("", lerp("", "", 1));
18 assertEqual("", lerp("", "", 2));
19 }});
20
21 it("maintains identity", function () { with (this) {
22 for (var i = -1; i < 2; i += 1/1024) {
23 assertEqual(A, lerp(A, A, i));
24 assertEqual(B, lerp(B, B, i));
25 }
26 }});
27 }}
28
29 function itMakesValidStrings (parent, lerp) { with (parent) {
30 it("doesn't make half a poo", function () { with (this) {
31 var poos = "\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9\uD83D\uDCA9";
32 assertEqual("\uD83D\uDCA9\uD83D\uDCA9", lerp("", poos, 0.5));
33 assertEqual("\uD83D\uDCA9", lerp("", poos, 0.35));
34
35 for (var i = 0; i <= 1; i += 1/256)
36 assertNot(lerp("", poos, i).match(HALF_POOS));
37 }});
38
39 it("doesn't misplace combining marks", function () { with (this) {
40 for (var i = 0; i <= 1; i += 1/256) {
41 var r = lerp("a", UNUSUAL_Q, i);
42 assert(r === "a" || r === UNUSUAL_Q);
43 }
44 }});
45 }}
46
47 function itDoesntOvershoot (parent, lerp) { with (parent) {
48 it("handles lows", function () { with (this) {
49 assertEqual(A, lerp(A, B, -Infinity));
50 assertEqual(A, lerp(A, B, -1));
51 assertEqual(A, lerp(A, B, 0));
52 }});
53
54 it("handles highs", function () { with (this) {
55 assertEqual(B, lerp(A, B, 1));
56 assertEqual(B, lerp(A, B, 2));
57 assertEqual(B, lerp(A, B, Infinity));
58 }});
59 }}
60
61 JS.Test.describe('fast lerp', function () { with (this) {
62 var lerp = stringLerp.fastLerp;
63
64 itHandlesBaseCases(this, lerp);
65 itMakesValidStrings(this, lerp);
66 itDoesntOvershoot(this, lerp);
67
68 it("crams strings together", function () { with (this) {
69 assertEqual("I do not ke green eggs and ham?", lerp(A, B, 0.3));
70 assertEqual("I do not like tn eggs and ham?", lerp(A, B, 0.5));
71 assertEqual("I do not like them, Sam-I-am?", lerp(A, B, 0.98));
72 }});
73
74 }});
75
76 function itEditsHumanly(parent, lerp) { with (parent) {
77 it("edits strings", function () { with (this) {
78 assertEqual(A, lerp(A, B, 0.01));
79 assertEqual("I do not like treen eggs and ham?", lerp(A, B, 0.3));
80 assertEqual("I do not like them, eggs and ham?", lerp(A, B, 0.5));
81 assertEqual("I do not like them, Sam-Iham?", lerp(A, B, 0.9));
82 assertEqual(B, lerp(A, B, 0.99));
83 }});
84
85 it("prefers ins/del to sub/sub", function () { with (this) {
86 // When the cost is uniform this string can be transformed by
87 // rewriting the whole thing for the same cost as deleting the
88 // front and adding to the back. But visually, we'd rather do
89 // the latter.
90 assertEqual("core", lerp("hard core", "core dump", 0.50));
91 }});
92
93 it("weights ins/del cheaper than sub", function () { with (this) {
94 // When the cost is uniform it is cheaper to rewrite the
95 // former into the latter. But we'd rather keep the "core" for
96 // visual reasons, so we need to make sure we have unequal
97 // costs.
98 assertEqual("core", lerp("apple core", "core dump", 0.51));
99 }});
100 }}
101
102 JS.Test.describe('diff lerp', function () { with (this) {
103 var lerp = stringLerp.diffLerp;
104
105 itHandlesBaseCases(this, lerp);
106 itMakesValidStrings(this, lerp);
107 itDoesntOvershoot(this, lerp);
108 itEditsHumanly(this, lerp);
109 }});
110
111 function itTreatsNumeralsAsNumbers(parent, lerp) { with (parent) {
112 it("handles single numbers", function () { with (this) {
113 assertEqual("0", lerp("0", "100", 0));
114 assertEqual("50", lerp("0", "100", 0.5));
115 assertEqual("100", lerp("0", "100", 1.0));
116 assertEqual("150", lerp("0", "100", 1.5));
117 }});
118
119 it("rounds integers", function () { with (this) {
120 assertEqual("12", lerp("0", "100", 0.123));
121 assertEqual("12.3", lerp("0.0", "100.0", 0.123));
122 assertEqual("12.3", lerp("0.0", "100", 0.123));
123 assertEqual("12.3", lerp("0.0", "100.0", 0.123));
124 }});
125
126 it("thinks about precision", function () { with (this) {
127 assertEqual("12.30", lerp("0.00", "100.00", 0.123));
128 assertEqual("12.300", lerp("0.000", "100.000", 0.123));
129 }});
130
131 it("computes parameters outside [0, 1]", function () { with (this) {
132 assertEqual("Giving 110%", lerp("Giving 0%", "Giving 100%", 1.1));
133 }});
134
135 it("handles multiple numbers", function () { with (this) {
136 var A = "Chapter 0. The sky was rgb(0, 0, 0).";
137 var B = "Chapter 10. The sky was rgb(0, 0, 255).";
138 assertEqual(A, lerp(A, B, 0));
139 assertEqual(B, lerp(A, B, 1));
140 assertEqual("Chapter 5. The sky was rgb(0, 0, 128).", lerp(A, B, 0.5));
141 }});
142 }}
143
144 JS.Test.describe('numeric lerp', function () { with (this) {
145 var lerp = stringLerp.numericLerp;
146
147 itHandlesBaseCases(this, lerp);
148 itTreatsNumeralsAsNumbers(this, lerp);
149 }});
150
151 JS.Test.describe('auto lerp', function () { with (this) {
152 var lerp = stringLerp.lerp;
153
154 itHandlesBaseCases(this, lerp);
155 itMakesValidStrings(this, lerp);
156 itDoesntOvershoot(this, lerp);
157 itTreatsNumeralsAsNumbers(this, lerp);
158 itEditsHumanly(this, lerp);
159 }});