spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← All files
name: tests/Formulas/TextTest.ts
-rw-r--r--
21634
  1import {
  2  ARABIC,
  3  CHAR,
  4  CODE,
  5  CONCATENATE,
  6  SPLIT,
  7  CONVERT,
  8  TRIM,
  9  LOWER,
 10  UPPER,
 11  T,
 12  ROMAN,
 13  TEXT,
 14  FIND,
 15  JOIN,
 16  LEN,
 17  LEFT,
 18  RIGHT,
 19  SEARCH,
 20  REPT,
 21  VALUE,
 22  CLEAN,
 23  MID,
 24  PROPER,
 25  REPLACE,
 26  SUBSTITUTE
 27} from "../../src/Formulas/Text";
 28import * as ERRORS from "../../src/Errors";
 29import {
 30  assertEquals,
 31  assertArrayEquals,
 32  catchAndAssertEquals,
 33  test,
 34  lockDate
 35} from "../Utils/Asserts";
 36
 37
 38test("SPLIT", function(){
 39  assertArrayEquals(SPLIT("1,2,3", ","), ['1', '2', '3']);
 40  assertArrayEquals(SPLIT("little kitty cat", "i"), ['l', 'ttle k', 'tty cat']);
 41  assertArrayEquals(SPLIT("father sister berzerker", "er", true), ['fath', ' sist', ' b', 'z', 'k']);
 42  assertArrayEquals(SPLIT("father sister berzerker", "er", [true]), ['fath', ' sist', ' b', 'z', 'k']);
 43  assertArrayEquals(SPLIT("father  sister   berzerker", "er", true), ['fath', '  sist', '   b', 'z', 'k']);
 44  assertArrayEquals(SPLIT(["father sister berzerker"], ["er"], true), ['fath', ' sist', ' b', 'z', 'k']);
 45  catchAndAssertEquals(function() {
 46    SPLIT([], "er");
 47  }, ERRORS.REF_ERROR);
 48  catchAndAssertEquals(function() {
 49    SPLIT.apply(this, ["er", "er", true, 10]);
 50  }, ERRORS.NA_ERROR);
 51});
 52
 53
 54test("CHAR", function(){
 55  assertEquals(CHAR(97), "a");
 56  assertEquals(CHAR("97"), "a");
 57  assertEquals(CHAR([97, "m"]), "a");
 58  assertEquals(CHAR([[97], "m"]), "a");
 59  catchAndAssertEquals(function() {
 60    CHAR([[], [97], "m"]);
 61  }, ERRORS.REF_ERROR);
 62  catchAndAssertEquals(function() {
 63    CHAR(false);
 64  }, ERRORS.NUM_ERROR);
 65  catchAndAssertEquals(function() {
 66    CHAR(10000000);
 67  }, ERRORS.NUM_ERROR);
 68  catchAndAssertEquals(function() {
 69    CHAR(0);
 70  }, ERRORS.NUM_ERROR);
 71  catchAndAssertEquals(function() {
 72    CHAR.apply(this, []);
 73  }, ERRORS.NA_ERROR);
 74});
 75
 76
 77test("CODE", function(){
 78  assertEquals(CODE('a'), 97);
 79  assertEquals(CODE('aa'), 97);
 80  assertEquals(CODE('aM'), 97);
 81  assertEquals(CODE('#'), 35);
 82  assertEquals(CODE(false), 70);
 83  assertEquals(CODE(true), 84);
 84  assertEquals(CODE(['a']), 97);
 85  assertEquals(CODE([['a'], 'p']), 97);
 86  catchAndAssertEquals(function() {
 87    CODE.apply(this, []);
 88  }, ERRORS.NA_ERROR);
 89  catchAndAssertEquals(function() {
 90    CODE.apply(this, ["a", "m"]);
 91  }, ERRORS.NA_ERROR);
 92  catchAndAssertEquals(function() {
 93    CODE("");
 94  }, ERRORS.VALUE_ERROR);
 95
 96});
 97
 98
 99test("CONCATENATE", function(){
100  assertEquals(CONCATENATE("hey", " ", "there"), "hey there");
101  assertEquals(CONCATENATE(["hey", " ", "there"]), "hey there");
102  assertEquals(CONCATENATE("hey"), "hey");
103  assertEquals(CONCATENATE("hey", 2), "hey2");
104  assertEquals(CONCATENATE("hey", false), "heyFALSE");
105  assertEquals(CONCATENATE([22, 14, "m", false]), "2214mFALSE");
106  assertEquals(CONCATENATE([22, 14, ["m", false]]), "2214mFALSE");
107  catchAndAssertEquals(function() {
108    CONCATENATE.apply(this, []);
109  }, ERRORS.NA_ERROR);
110  catchAndAssertEquals(function() {
111    CONCATENATE("10", 4, false, []);
112  }, ERRORS.REF_ERROR);
113  catchAndAssertEquals(function() {
114    CONCATENATE([]);
115  }, ERRORS.REF_ERROR);
116});
117
118
119test("CONVERT", function(){
120  assertEquals(CONVERT(5.1, "mm", "m"), 0.0050999999999999995);
121  assertEquals(CONVERT(5.1, "mm", "km"), 0.0000050999999999999995);
122  assertEquals(CONVERT(5.1, "g", "kg"), 0.0050999999999999995);
123  assertEquals(CONVERT(35.7, "in^2", "m^2"), 0.023032212);
124  assertEquals(CONVERT(100, "ft3", "in3"), 172800);
125  assertEquals(CONVERT(100, "in3", "ft3"), 0.057870370370370364);
126  assertEquals(CONVERT(0.0001, "ly", "ft"), 3103914197040.945);
127  assertEquals(CONVERT(44, "m/h", "m/s"), 0.01222222222222232);
128  assertEquals(CONVERT(10, "mph", "m/s"), 4.4704);
129  assertEquals(CONVERT(10, "mmHg", "Pa"), 1333.22);
130  assertEquals(CONVERT(10, "PS", "W"), 7354.987499999999);
131  assertEquals(CONVERT(10, "ton", "stone"), 1428.5714285714287);
132  assertEquals(CONVERT(10, "tspm", "bushel"), 0.0014188796696394089);
133  assertEquals(CONVERT(10, "c", "Wh"), 0.011622222222222223);
134  catchAndAssertEquals(function() {
135    CONVERT.apply(this, []);
136  }, ERRORS.NA_ERROR);
137  catchAndAssertEquals(function() {
138    CONVERT.apply(this, [5.1, "mm", "m", 10]);
139  }, ERRORS.NA_ERROR);
140});
141
142
143test("ARABIC", function(){
144  assertEquals(ARABIC("XIV"), 14);
145  assertEquals(ARABIC("M"), 1000);
146  assertEquals(ARABIC("-IV"), -4);
147  catchAndAssertEquals(function() {
148    ARABIC("b");
149  }, ERRORS.VALUE_ERROR);
150  catchAndAssertEquals(function() {
151    ARABIC(false);
152  }, ERRORS.VALUE_ERROR);
153  catchAndAssertEquals(function() {
154    ARABIC(10);
155  }, ERRORS.VALUE_ERROR);
156});
157
158
159test("TRIM", function(){
160  assertEquals(TRIM(" test  "), "test");
161  assertEquals(TRIM(5), "5");
162  assertEquals(TRIM(false), "FALSE");
163  catchAndAssertEquals(function() {
164    TRIM.apply(this, []);
165  }, ERRORS.NA_ERROR);
166  catchAndAssertEquals(function() {
167    TRIM.apply(this, ["test", 5]);
168  }, ERRORS.NA_ERROR);
169});
170
171
172test("LOWER", function(){
173  assertEquals(LOWER("TEST"), "test");
174  assertEquals(LOWER(5), "5");
175  assertEquals(LOWER(false), "false");
176  catchAndAssertEquals(function() {
177    LOWER.apply(this, []);
178  }, ERRORS.NA_ERROR);
179  catchAndAssertEquals(function() {
180    LOWER.apply(this, ["test", 5]);
181  }, ERRORS.NA_ERROR);
182});
183
184
185test("UPPER", function(){
186  assertEquals(UPPER("test"), "TEST");
187  assertEquals(UPPER(5), "5");
188  assertEquals(UPPER(false), "FALSE");
189  catchAndAssertEquals(function() {
190    UPPER.apply(this, []);
191  }, ERRORS.NA_ERROR);
192  catchAndAssertEquals(function() {
193    UPPER.apply(this, ["test", 5]);
194  }, ERRORS.NA_ERROR);
195});
196
197
198test("T", function(){
199  assertEquals(T("test"), "test");
200  assertEquals(T(["test"]), "test");
201  assertEquals(T(5), "");
202  assertEquals(T(false), "");
203  catchAndAssertEquals(function() {
204    T.apply(this, []);
205  }, ERRORS.NA_ERROR);
206});
207
208test("ROMAN", function(){
209  assertEquals(ROMAN(419), "CDXIX");
210  assertEquals(ROMAN(1), "I");
211  assertEquals(ROMAN(3999), "MMMCMXCIX");
212  assertEquals(ROMAN(300), "CCC");
213  catchAndAssertEquals(function() {
214    ROMAN(0);
215  }, ERRORS.VALUE_ERROR);
216  catchAndAssertEquals(function() {
217    ROMAN.apply(this, []);
218  }, ERRORS.NA_ERROR);
219});
220
221test("TEXT", function(){
222  lockDate(2012, 1, 9, 10, 22, 33);
223  assertEquals(TEXT("01/09/2012 10:22:33AM", "dd mm yyyy"), "09 01 2012");
224  assertEquals(TEXT("01/09/2012 10:22:33AM", "dddd dd mm yyyy"), "Monday 09 01 2012");
225  assertEquals(TEXT("01/09/2012 10:22:33AM", "dddd"), "Monday");
226  assertEquals(TEXT("01/10/2012 10:22:33AM", "dddd"), "Tuesday");
227  assertEquals(TEXT("01/11/2012 10:22:33AM", "dddd"), "Wednesday");
228  assertEquals(TEXT("01/12/2012 10:22:33AM", "dddd"), "Thursday");
229  assertEquals(TEXT("01/13/2012 10:22:33AM", "dddd"), "Friday");
230  assertEquals(TEXT("01/14/2012 10:22:33AM", "dddd"), "Saturday");
231  assertEquals(TEXT("01/15/2012 10:22:33AM", "dddd"), "Sunday");
232  assertEquals(TEXT("01/09/2012 10:22:33AM", "dDDd"), "Monday");
233  assertEquals(TEXT("01/09/2012 10:22:33AM", "ddd"), "Mon");
234  assertEquals(TEXT("01/10/2012 10:22:33AM", "ddd"), "Tue");
235  assertEquals(TEXT("01/11/2012 10:22:33AM", "ddd"), "Wed");
236  assertEquals(TEXT("01/12/2012 10:22:33AM", "ddd"), "Thu");
237  assertEquals(TEXT("01/13/2012 10:22:33AM", "ddd"), "Fri");
238  assertEquals(TEXT("01/14/2012 10:22:33AM", "ddd"), "Sat");
239  assertEquals(TEXT("01/15/2012 10:22:33AM", "ddd"), "Sun");
240  assertEquals(TEXT("01/15/2012 10:22:33AM", "DDD"), "Sun");
241  assertEquals(TEXT("01/09/2012 10:22:33AM", "dd"), "09");
242  assertEquals(TEXT("01/09/2012 10:22:33AM", "DD"), "09");
243  assertEquals(TEXT("01/09/2012 10:22:33AM", "d"), "1");
244  assertEquals(TEXT("01/09/2012 10:22:33AM", "D"), "1");
245  assertEquals(TEXT("01/09/2012 10:22:33AM", "mmmmm"), "J");
246  assertEquals(TEXT("02/09/2012 10:22:33AM", "mmmmm"), "F");
247  assertEquals(TEXT("02/09/2012 10:22:33AM", "MMMMM"), "F");
248  assertEquals(TEXT("01/09/2012 10:22:33AM", "mmmm"), "January");
249  assertEquals(TEXT("02/09/2012 10:22:33AM", "mmmm"), "February");
250  assertEquals(TEXT("02/09/2012 10:22:33AM", "MMMM"), "February");
251  assertEquals(TEXT("01/09/2012 10:22:33AM", "mmm"), "Jan");
252  assertEquals(TEXT("02/09/2012 10:22:33AM", "mmm"), "Feb");
253  assertEquals(TEXT("02/09/2012 10:22:33AM", "MMM"), "Feb");
254  assertEquals(TEXT("01/09/2012 10:22:33AM", "mm"), "01");
255  assertEquals(TEXT("02/09/2012 10:22:33AM", "mm"), "02");
256  assertEquals(TEXT("02/09/2012 10:22:33AM", "MM"), "02");
257  assertEquals(TEXT("01/09/2012 10:04:33AM", "HH mm"), "10 04");
258  assertEquals(TEXT("01/09/2012 10:04:33AM", "HH m"), "10 4");
259  assertEquals(TEXT("01/09/2012 10:04:33AM", "hh m"), "10 4");
260  assertEquals(TEXT("01/09/2012 10:04:33AM", "m"), "1");
261  assertEquals(TEXT("01/09/2012 10:04:33AM", "yyyy"), "2012");
262  assertEquals(TEXT("01/09/2012 10:04:33AM", "YYYY"), "2012");
263  assertEquals(TEXT("01/09/2012 10:04:33AM", "yy"), "12");
264  assertEquals(TEXT("01/09/2012 10:04:33AM", "YY"), "12");
265  assertEquals(TEXT("01/09/1912 10:04:33AM", "yy"), "12");
266  assertEquals(TEXT("01/09/2012 10:04:33PM", "HH"), "22");
267  assertEquals(TEXT("01/09/2012 10:04:33PM", "hh"), "10");
268  // TODO: This will be fixed as soon as we allow sub-second date-string parsing in TypeConverter.
269  // assertEquals(TEXT("01/09/2012 10:04:33.123", "ss.000"), "33.123");
270  assertEquals(TEXT("01/09/2012 10:04:33AM", "ss"), "33");
271  assertEquals(TEXT("01/09/2012 10:04:33AM", "AM/PM"), "AM");
272  assertEquals(TEXT("01/09/2012 10:04:33PM", "AM/PM"), "PM");
273  assertEquals(TEXT("01/09/2012 10:04:33AM", "A/P"), "A");
274  assertEquals(TEXT("01/09/2012 10:04:33PM", "A/P"), "P");
275  assertEquals(TEXT("01/09/2012 10:04:33AM", "mmmm-dd-yyyy, hh:mm A/P"), "January-09-2012, 10:04 A");
276  assertEquals(TEXT("01/09/2012 10:04:33PM", "mmmm-dd-yyyy, HH:mm A/P"), "January-09-2012, 22:04 P");
277  assertEquals(TEXT(44564.111, "dd mm yyyy HH:mm:ss"), "03 01 2022 02:39:50");
278  assertEquals(TEXT(44564.111, "dd mmmm yyyy HH:mm:ss"), "03 January 2022 02:39:50");
279  assertEquals(TEXT(44564, "dd mmmm yyyy HH:mm:ss"), "03 January 2022 00:00:00");
280  assertEquals(TEXT(64, "dd mmmm yyyy HH:mm:ss"), "04 March 1900 00:00:00");
281  assertEquals(TEXT(false, "dd mmmm yyyy HH:mm:ss"), "FALSE");
282  assertEquals(TEXT(true, "dd mmmm yyyy HH:mm:ss"), "TRUE");
283  assertEquals(TEXT(-164, "dd mmmm yyyy HH:mm:ss"), "19 July 1899 00:00:00");
284  // "##.##" formatting
285  assertEquals(TEXT(12.3, "###.##"), "12.3");
286  assertEquals(TEXT(12.3333, "###.##"), "12.33");
287  assertEquals(TEXT(0.001, "#.###############"), "0.001");
288  assertEquals(TEXT(0, "#.#"), ".");
289  assertEquals(TEXT(0.99, "#"), "1");
290  assertEquals(TEXT(0, "$#.#"), "$.");
291  assertEquals(TEXT(1231213131.32232, "######,###.#"), "1,231,213,131.3");
292  assertEquals(TEXT(123333333333, "######,###.#"), "123,333,333,333");
293  assertEquals(TEXT(1224324333.36543, ",###.#"), "1,224,324,333.4");
294  assertEquals(TEXT(-12.3, "###.##"), "-12.3");
295  assertEquals(TEXT(-12.3333, "###.##"), "-12.33");
296  assertEquals(TEXT(-0.001, "#.###############"), "-0.001");
297  assertEquals(TEXT(-1231213131.32232, "######,###.#"), "-1,231,213,131.3");
298  assertEquals(TEXT(-123333333333, "######,###.#"), "-123,333,333,333");
299  assertEquals(TEXT(-1224324333.36543, ",###.#"), "-1,224,324,333.4");
300  assertEquals(TEXT(12.3, "$###.##"), "$12.3");
301  assertEquals(TEXT(12.3, "%###.##"), "%12.3");
302  assertEquals(TEXT(12.3, "$+-+%###.##$+-+"), "$+-+%12.3$+-+");
303  // "00.00" formatting
304  assertEquals(TEXT(12.3, "00"), "12");
305  assertEquals(TEXT(12.9, "00"), "13");
306  assertEquals(TEXT(12.3, "00.0"), "12.3");
307  assertEquals(TEXT(12.3, "000.0"), "012.3");
308  assertEquals(TEXT(12.3, "000.00"), "012.30");
309  assertEquals(TEXT(-12.3, "00"), "-12");
310  assertEquals(TEXT(-12.9, "00"), "-13");
311  assertEquals(TEXT(-12.3, "00.0"), "-12.3");
312  assertEquals(TEXT(-12.3, "000.0"), "-012.3");
313  assertEquals(TEXT(-12.3, "000.00"), "-012.30");
314  assertEquals(TEXT(-12.3, "+-$%000.0"), "-+-$%012.3");
315  assertEquals(TEXT(-12.3, "+-$%00.0"), "-+-$%12.3");
316  assertEquals(TEXT(-12.3, "+-$%00.0+-$"), "-+-$%12.3+-$");
317  assertEquals(TEXT(12.3, "000000000000000.0000000000000"), "000000000000012.3000000000000");
318  assertEquals(TEXT(12.33, "000000000000000.0000000000000"), "000000000000012.3300000000000");
319  assertEquals(TEXT(12.33555, "000000000000000.0000000000000"), "000000000000012.3355500000000");
320  assertEquals(TEXT(12.33555, "000000000000000.0000"), "000000000000012.3356");
321  assertEquals(TEXT(12.3, "+-$%000.0"), "+-$%012.3");
322  assertEquals(TEXT(12.3, "+-$%00.0"), "+-$%12.3");
323  assertEquals(TEXT(12.3, "+-$%00.0+-$"), "+-$%12.3+-$");
324  assertEquals(TEXT(12, "0,000.0"), "0,012.0");
325  assertEquals(TEXT(123342424, "0000000,000.0"), "0,123,342,424.0");
326  assertEquals(TEXT(0.01, "00.0"), "00.0");
327  assertEquals(TEXT(0.01, "00.0"), "00.0");
328  assertEquals(TEXT(0.01, "00.0"), "00.0");
329  assertEquals(TEXT(12, "00"), "12");
330  assertEquals(TEXT(12.3, "00"), "12");
331  assertEquals(TEXT(12, "00.00"), "12.00");
332  assertEquals(TEXT(0.99, "0.00"), "0.99");
333  assertEquals(TEXT(0.99, ".00"), ".99");
334  assertEquals(TEXT(0.99, "00.00"), "00.99");
335  assertEquals(TEXT(0.99, "0000.00"), "0000.99");
336  assertEquals(TEXT(0.99, "0.0000"), "0.9900");
337  assertEquals(TEXT(0.99, "0.0"), "1.0");
338  assertEquals(TEXT(0.88, "0.0"), "0.9");
339  assertEquals(TEXT(0.88, "00.0"), "00.9");
340  assertEquals(TEXT(0.88, "00.00"), "00.88");
341  assertEquals(TEXT(0.88, "00.000"), "00.880");
342  assertEquals(TEXT(1.88, "00.000"), "01.880");
343  assertEquals(TEXT(1.99, "00.0"), "02.0");
344  assertEquals(TEXT(1234223.3324224, "0000000000.0"), "0001234223.3");
345  assertEquals(TEXT(12, "%00%"), "%12%");
346  assertEquals(TEXT(12.3, "00.0%"), "12.3%");
347  assertEquals(TEXT(12.3, "$+-00.0$+-"), "$+-12.3$+-");
348  assertEquals(TEXT(123456789, "0,0.0"), "123,456,789.0");
349  assertEquals(TEXT(123456789.99, "0,0.0"), "123,456,790.0");
350  assertEquals(TEXT(0.99, "0,000.00"), "0,000.99");
351  assertEquals(TEXT(0.99, "0,000.0"), "0,001.0");
352  catchAndAssertEquals(function() {
353    TEXT(0.99, "0.00#");
354  }, ERRORS.VALUE_ERROR);
355  catchAndAssertEquals(function() {
356    TEXT(0.99, "#0.00");
357  }, ERRORS.VALUE_ERROR);
358  catchAndAssertEquals(function() {
359    TEXT.apply(this, [100]);
360  }, ERRORS.NA_ERROR);
361  catchAndAssertEquals(function() {
362    TEXT.apply(this, [100, "0", 10]);
363  }, ERRORS.NA_ERROR);
364});
365
366test("FIND", function(){
367  assertEquals(FIND("s", "soup", 1), 1);
368  assertEquals(FIND("s", "soup"), 1);
369  assertEquals(FIND("o", "soup"), 2);
370  assertEquals(FIND("u", "soup"), 3);
371  assertEquals(FIND("p", "soup"), 4);
372  assertEquals(FIND("s", "soup soup", 5), 6);
373  assertEquals(FIND("o", "soup soup", 5), 7);
374  assertEquals(FIND("u", "soup soup", 5), 8);
375  assertEquals(FIND("p", "soup soup", 5), 9);
376  assertEquals(FIND("p", "soup soup", 4), 4);
377  catchAndAssertEquals(function() {
378    FIND("m", "soup", -1);
379  }, ERRORS.VALUE_ERROR);
380  catchAndAssertEquals(function() {
381    FIND("m", "soup");
382  }, ERRORS.VALUE_ERROR);
383  catchAndAssertEquals(function() {
384    FIND.apply(this, [2]);
385  }, ERRORS.NA_ERROR);
386  catchAndAssertEquals(function() {
387    FIND.apply(this, [2, 3, 4, 5])
388  }, ERRORS.NA_ERROR);
389});
390
391test("JOIN", function(){
392  assertEquals(JOIN(",", [1, 2, 3, 4, 5]), "1,2,3,4,5");
393  assertEquals(JOIN(",", 1, 2, 3, 4, 5), "1,2,3,4,5");
394  assertEquals(JOIN(",", 1, [2], [3, 4, 5]), "1,2,3,4,5");
395  assertEquals(JOIN("", [1, 2, 3, 4, 5]), "12345");
396  assertEquals(JOIN(true, [1, 2, 3, 4, 5]), "1TRUE2TRUE3TRUE4TRUE5");
397  catchAndAssertEquals(function() {
398    JOIN.apply(this, [2]);
399  }, ERRORS.NA_ERROR);
400});
401
402test("LEN", function(){
403  assertEquals(LEN("soup"), 4);
404  assertEquals(LEN("jja sdkj lkasj lkajlskaj dlj lask"), 33);
405  assertEquals(LEN(""), 0);
406  assertEquals(LEN(4), 1);
407  assertEquals(LEN(44), 2);
408  assertEquals(LEN(true), 4);
409  catchAndAssertEquals(function() {
410    LEN.apply(this, []);
411  }, ERRORS.NA_ERROR);
412  catchAndAssertEquals(function() {
413    LEN.apply(this, [2, 4]);
414  }, ERRORS.NA_ERROR);
415});
416
417test("LEFT", function(){
418  assertEquals(LEFT("soup"), "s");
419  assertEquals(LEFT("soup", 0), "");
420  assertEquals(LEFT("soup", 1), "s");
421  assertEquals(LEFT("soup", 2), "so");
422  assertEquals(LEFT("soup", 3), "sou");
423  assertEquals(LEFT("soup", 4), "soup");
424  assertEquals(LEFT("soup", 5), "soup");
425  assertEquals(LEFT("", 1000), "");
426  catchAndAssertEquals(function() {
427    LEFT("soup", -1);
428  }, ERRORS.VALUE_ERROR);
429  catchAndAssertEquals(function() {
430    LEFT.apply(this, []);
431  }, ERRORS.NA_ERROR);
432  catchAndAssertEquals(function() {
433    LEFT.apply(this, [1, 2, 3]);
434  }, ERRORS.NA_ERROR);
435});
436
437test("RIGHT", function(){
438  assertEquals(RIGHT("soup"), "p");
439  assertEquals(RIGHT("soup", 0), "");
440  assertEquals(RIGHT("soup", 1), "p");
441  assertEquals(RIGHT("soup", 2), "up");
442  assertEquals(RIGHT("soup", 3), "oup");
443  assertEquals(RIGHT("soup", 4), "soup");
444  assertEquals(RIGHT("soup", 5), "soup");
445  assertEquals(RIGHT("", 1000), "");
446  catchAndAssertEquals(function() {
447    RIGHT("soup", -1);
448  }, ERRORS.VALUE_ERROR);
449  catchAndAssertEquals(function() {
450    RIGHT.apply(this, []);
451  }, ERRORS.NA_ERROR);
452  catchAndAssertEquals(function() {
453    RIGHT.apply(this, [1, 2, 3]);
454  }, ERRORS.NA_ERROR);
455});
456
457test("SEARCH", function(){
458  assertEquals(SEARCH("soup", "where is the soup?"), 14);
459  assertEquals(SEARCH("SOUP", "where is the soup?"), 14);
460  assertEquals(SEARCH("soup", "where Is ThE sOUp?"), 14);
461  assertEquals(SEARCH("soup", "soup?"), 1);
462  assertEquals(SEARCH("oup", "soup?"), 2);
463  assertEquals(SEARCH("soup", "soup, where is the soup?", 14), 20);
464  catchAndAssertEquals(function() {
465    SEARCH("beef", "soup?");
466  }, ERRORS.VALUE_ERROR);
467  catchAndAssertEquals(function() {
468    SEARCH("beef", "beef", -10);
469  }, ERRORS.VALUE_ERROR);
470  catchAndAssertEquals(function() {
471    SEARCH.apply(this, [1]);
472  }, ERRORS.NA_ERROR);
473  catchAndAssertEquals(function() {
474    SEARCH.apply(this, [1, 2, 3, 4]);
475  }, ERRORS.NA_ERROR);
476});
477
478test("REPT", function(){
479  assertEquals(REPT("s", 0), "");
480  assertEquals(REPT("s", 1), "s");
481  assertEquals(REPT("s", 10), "ssssssssss");
482  catchAndAssertEquals(function() {
483    REPT("s", -1);
484  }, ERRORS.VALUE_ERROR);
485  catchAndAssertEquals(function() {
486    REPT.apply(this, [1]);
487  }, ERRORS.NA_ERROR);
488  catchAndAssertEquals(function() {
489    REPT.apply(this, [1, 2, 3]);
490  }, ERRORS.NA_ERROR);
491});
492
493test("VALUE", function(){
494  assertEquals(VALUE("10"), 10);
495  assertEquals(VALUE(10), 10);
496  assertEquals(VALUE(10.1), 10.1);
497  assertEquals(VALUE([10]), 10);
498  assertEquals(VALUE("7/20/1966"), 24308);
499  // TODO: Should pass once we're able to parse timestamp strings.
500  // assertEquals(VALUE("12:00:00"), 0.5);
501  catchAndAssertEquals(function() {
502    VALUE(true);
503  }, ERRORS.VALUE_ERROR);
504  catchAndAssertEquals(function() {
505    VALUE("str");
506  }, ERRORS.VALUE_ERROR);
507  catchAndAssertEquals(function() {
508    VALUE.apply(this, [1, 2]);
509  }, ERRORS.NA_ERROR);
510});
511
512test("CLEAN", function(){
513  assertEquals(CLEAN("hello"), "hello");
514  assertEquals(CLEAN("hello¿Ãš"), "hello¿Ãš");
515  assertEquals(CLEAN("hello"+CHAR(31)), "hello");
516  assertEquals(CLEAN("hello\n"), "hello");
517  assertEquals(CLEAN(10), "10");
518  catchAndAssertEquals(function() {
519    CLEAN.apply(this, []);
520  }, ERRORS.NA_ERROR);
521  catchAndAssertEquals(function() {
522    CLEAN.apply(this, [1, 2]);
523  }, ERRORS.NA_ERROR);
524});
525
526test("MID", function(){
527  assertEquals(MID("hey there", 5, 4), "ther");
528  assertEquals(MID("hey there", 5, 1), "t");
529  assertEquals(MID("hey there", 5, 0), "");
530  assertEquals(MID("hey there", 50, 10), "");
531  catchAndAssertEquals(function () {
532    MID("", 1, -1);
533  }, ERRORS.VALUE_ERROR);
534  catchAndAssertEquals(function () {
535    MID("", 0, 1);
536  }, ERRORS.NUM_ERROR);
537  catchAndAssertEquals(function () {
538    MID.apply(this, [1, 2, 3, 4]);
539  }, ERRORS.NA_ERROR);
540  catchAndAssertEquals(function () {
541    MID.apply(this, [1, 2]);
542  }, ERRORS.NA_ERROR);
543});
544
545test("PROPER", function(){
546  assertEquals(PROPER("hey there"), "Hey There");
547  assertEquals(PROPER("hEY tHERE"), "Hey There");
548  assertEquals(PROPER("there once was a man, and he lived on the moon."), "There Once Was A Man, And He Lived On The Moon.");
549  assertEquals(PROPER("my name is h.s. thompson"), "My Name Is H.s. Thompson");
550  assertEquals(PROPER(true), "True");
551  assertEquals(PROPER(10), "10");
552  catchAndAssertEquals(function () {
553    PROPER.apply(this, []);
554  }, ERRORS.NA_ERROR);
555  catchAndAssertEquals(function () {
556    PROPER.apply(this, [1, 2]);
557  }, ERRORS.NA_ERROR);
558});
559
560test("PROPER", function(){
561  assertEquals(REPLACE("Hey there", 1, 3, "Hello"), "Hello there");
562  assertEquals(REPLACE("Hey there", 2, 1, "Hello"), "HHelloy there");
563  assertEquals(REPLACE("Hey there", 1, 1100, "Hello"), "Hello");
564  assertEquals(REPLACE("Hey", 10, 11, "Hello"), "HeyHello");
565  catchAndAssertEquals(function () {
566    REPLACE.apply(this, ["Hey there", 1, 1]);
567  }, ERRORS.NA_ERROR);
568  catchAndAssertEquals(function () {
569    REPLACE.apply(this, ["Hey there", 1, 1, "replace me", "me too!"]);
570  }, ERRORS.NA_ERROR);
571  catchAndAssertEquals(function () {
572    REPLACE("Hey there", 0, 3, "Hello")
573  }, ERRORS.VALUE_ERROR);
574  catchAndAssertEquals(function () {
575    REPLACE("Hey there", 1, -1, "Hello")
576  }, ERRORS.VALUE_ERROR);
577});
578
579test("SUBSTITUTE", function(){
580  assertEquals(SUBSTITUTE("Hey darkness my old friend", "Hey", "Hello"), "Hello darkness my old friend");
581  assertEquals(SUBSTITUTE("Hey darkness my old friend... Hey.", "Hey", "Hello"), "Hello darkness my old friend... Hello.");
582  assertEquals(SUBSTITUTE("Hey darkness my old friend... Hey.", "Hey", "Hello", 1), "Hello darkness my old friend... Hey.");
583  catchAndAssertEquals(function () {
584    SUBSTITUTE.apply(this, ["a", "b"]);
585  }, ERRORS.NA_ERROR);
586  catchAndAssertEquals(function () {
587    SUBSTITUTE.apply(this, ["a", "b", "c", 1, 2]);
588  }, ERRORS.NA_ERROR);
589  catchAndAssertEquals(function () {
590    SUBSTITUTE("Hey there", "hey", "hello", -1);
591  }, ERRORS.VALUE_ERROR);
592});