/* global describe, it */
import {guessDateFormat, guessDateFormats, parseDate, parseDateStrict, parseDateTime} from 'app/common/parseDate';
import {assert} from 'chai';
import * as moment from 'moment-timezone';

const today = new Date();
const year = today.getUTCFullYear();
const month = String(today.getUTCMonth() + 1).padStart(2, '0');

/**
 * Assert that parseDate and parseDateStrict parse `input` correctly,
 * returning a date that looks like expectedDateStr in ISO format.
 * parseDate should always produce a parsed date from `input`.
 * parseDateStrict should return at most one date, i.e. the formats it tries shouldn't allow ambiguity.
 *
 * fallback=true indicates the date cannot be parsed strictly with the given format
 * so parseDate has to fallback to another format and parseDateStrict gives no results.
 *
 * Otherwise, parseDateStrict should return a result
 * unless no dateFormat is given in which case it may or may not.
 */
function testParse(dateFormat: string|null, input: string, expectedDateStr: string, fallback: boolean = false) {
  assertDateEqual(parseDate(input, dateFormat ? {dateFormat} : {}), expectedDateStr);

  const strict = new Set<number>();
  parseDateStrict(input, dateFormat, strict);
  assert.include([0, 1], strict.size);

  // fallback=true indicates the date cannot be parsed strictly with the given format
  // so it has to fallback to another format.
  if (fallback) {
    assert.isEmpty(strict);
  } else if (dateFormat) {
    assert.equal(strict.size, 1);
  }

  if (strict.size) {
    const strictParsed = [...strict][0];
    assertDateEqual(strictParsed, expectedDateStr);
    assertDateEqual(parseDateTime(input, dateFormat ? {dateFormat} : {})!, expectedDateStr);
  }
}

function assertDateEqual(parsed: number|null, expectedDateStr: string) {
  const formatted = parsed === null ? null : new Date(parsed * 1000).toISOString().slice(0, 10);
  assert.equal(formatted, expectedDateStr);
}

function testTimeParse(input: string, expectedUTCTimeStr: string | null, timezone?: string) {
  const parsed1 = parseDateTime('1993-04-02T' + input,
    {timeFormat: 'Z', timezone, dateFormat: 'YYYY-MM-DD'}) || null;
  const parsed2 = parseDate('1993-04-02', {time: input, timeFormat: 'UNUSED', timezone});
  for (const parsed of [parsed1, parsed2]) {
    if (expectedUTCTimeStr === null) {
      assert.isNull(parsed);
      return;
    }
    const output = new Date(parsed! * 1000).toISOString().slice(11, 19);
    assert.equal(output, expectedUTCTimeStr, `testTimeParse(${input}, ${timezone})`);
  }
}

function testDateTimeParse(
  date: string, time: string, expectedUTCTimeStr: string | null, timezone: string, dateFormat?: string
) {
  const parsed1 = parseDateTime(date + ' ' + time,
    {timeFormat: 'Z', timezone, dateFormat: dateFormat || 'YYYY-MM-DD'}) || null;

  // This is for testing the combination of date and time which is important when daylight savings is involved
  const parsed2 = parseDate(date, {time, timeFormat: 'UNUSED', timezone, dateFormat});

  for (const parsed of [parsed1, parsed2]) {
    if (expectedUTCTimeStr === null) {
      assert.isNull(parsed);
      return;
    }
    const output = new Date(parsed! * 1000).toISOString().slice(0, 19).replace("T", " ");
    assert.equal(output, expectedUTCTimeStr);
  }
}

function testDateTimeStringParse(
  dateTime: string, expectedUTCTimeStr: string | null, dateFormat: string, timezone?: string,
) {
  const parsed = parseDateTime(dateTime, {timezone, dateFormat});

  if (expectedUTCTimeStr === null) {
    assert.isUndefined(parsed);
    return;
  }
  const output = new Date(parsed! * 1000).toISOString().slice(0, 19).replace("T", " ");
  assert.equal(output, expectedUTCTimeStr);
}

describe('parseDate', function() {
  this.timeout(5000);

  it('should allow parsing common date formats', function() {
    testParse(null, 'November 18th, 1994',  '1994-11-18');
    testParse(null, 'nov 18 1994',          '1994-11-18');
    testParse(null, '11-18-94',             '1994-11-18');
    testParse(null, '11-18-1994',           '1994-11-18');
    testParse(null, '1994-11-18',           '1994-11-18');
    testParse(null, 'November 18, 1994',    '1994-11-18');
    testParse('DD/MM/YY', '18/11/94',       '1994-11-18');
    // fallback format is used because 18 is not a valid month
    testParse('MM/DD/YY', '18/11/94',       '1994-11-18', true);

    testParse(null,       '18/11/94',       '1994-11-18');
    testParse(null,       '12/11/94',       '1994-12-11');
    testParse('DD/MM/YY', '12/11/94',       '1994-11-12');
    testParse('MM/DD/YY', '11/12/94',       '1994-11-12');

    testParse(null, '25', `${year}-${month}-25`);
    testParse(null, '10', `${year}-${month}-10`);
    testParse('DD/MM/YY', '10', `${year}-${month}-10`);
    testParse('DD/MM/YY', '3/4', `${year}-04-03`);
    // Separators in the format should not affect the parsing (for better or worse).
    testParse('YY-DD/MM', '3/4', `${year}-04-03`);
    testParse('YY/DD-MM', '3/4', `${year}-04-03`);
    testParse('MM/DD/YY', '3/4', `${year}-03-04`);
    testParse('YY/MM/DD', '3/4', `${year}-03-04`);
    testParse(null, '3/4', `${year}-03-04`);

    // Single number gets parse according to the most specific item in the format string.
    testParse('DD',     '10',   `${year}-${month}-10`);
    testParse('DD/MM',  '10',   `${year}-${month}-10`);
    testParse('MM',     '10',   `${year}-10-01`);
    testParse('MM/YY',  '10',   `${year}-10-01`);
    testParse('MMM',    '10',   `${year}-10-01`);
    testParse('YY',     '10',   `2010-01-01`);
    testParse('YYYY',   '10',   `2010-01-01`);

    testParse('YY',   '05',     `2005-01-01`);
    testParse('YY',   '5',      `${year}-05-01`, true);   // Not a valid year, so falls back to "M" format
    testParse('YYYY', '1910',   `1910-01-01`);
    testParse('YY',   '3/4',    `${year}-03-04`, true);   // Falls back to another format
    testParse('DD/MM', '3/4',   `${year}-04-03`);
    testParse('MM/YY', '3/04',  `2004-03-01`);
    testParse('MM/YY', '3/4',   `${year}-03-04`, true);   // Not a valid year, so falls back to "M/D" format

    testParse(null, '4/2/93',           '1993-04-02');
    testParse(null, '04-02-1993',       '1993-04-02');
    testParse(null, '4-02-93',          '1993-04-02');
    testParse(null, 'April 2nd, 1993',  '1993-04-02');

    testParse('DD MMM YY',   '15-Jan 99',   '1999-01-15');
    testParse('DD MMM YYYY', '15-Jan 1999', '1999-01-15');
    testParse('DD MMM',      '15-Jan 1999', '1999-01-15');

    testParse('MMMM Do, YYYY', 'April 2nd, 1993',  '1993-04-02');
    testParse('MMM Do YYYY', 'Apr 2nd 1993',  `1993-04-02`);
    testParse('Do MMMM YYYY', '2nd April 1993',  `1993-04-02`);
    testParse('Do MMM YYYY', '2nd Apr 1993',  `1993-04-02`);
    testParse('MMMM D, YYYY', 'April 2, 1993',  '1993-04-02');
    testParse('MMM D YYYY', 'Apr 2 1993',  `1993-04-02`);
    testParse('D MMMM YYYY', '2 April 1993',  `1993-04-02`);
    testParse('D MMM YYYY', '2 Apr 1993',  `1993-04-02`);
    testParse('MMMM Do, ', 'April 2nd, 1993',  '1993-04-02');
    testParse('MMM Do ', 'Apr 2nd 1993',  `1993-04-02`);
    testParse('Do MMMM ', '2nd April 1993',  `1993-04-02`);
    testParse('Do MMM ', '2nd Apr 1993',  `1993-04-02`);
    testParse('MMMM D, ', 'April 2, 1993',  '1993-04-02');
    testParse('MMM D ', 'Apr 2 1993',  `1993-04-02`);
    testParse('D MMMM ', '2 April 1993',  `1993-04-02`);
    testParse('D MMM ', '2 Apr 1993',  `1993-04-02`);
    testParse('MMMM Do, ', 'April 2nd',  `${year}-04-02`);
    testParse('MMM Do ', 'Apr 2nd',  `${year}-04-02`);
    testParse('Do MMMM ', '2nd April',  `${year}-04-02`);
    testParse('Do MMM ', '2nd Apr',  `${year}-04-02`);
    testParse('MMMM D, ', 'April 2',  `${year}-04-02`);
    testParse('MMM D ', 'Apr 2',  `${year}-04-02`);
    testParse('D MMMM ', '2 April',  `${year}-04-02`);
    testParse('D MMM ', '2 Apr',  `${year}-04-02`);

    // Test the combination of Do and YY, which was buggy at one point.
    testParse('MMMM Do, YY', 'April 2nd, 93',  '1993-04-02');
    testParse('MMM Do, YY', 'Apr 2nd, 93',  '1993-04-02');
    testParse('Do MMMM YY', '2nd April 93',  `1993-04-02`);
    testParse('Do MMM YY', '2nd Apr 93',  `1993-04-02`);

    testParse('  D   MMM   ', ' 2  Apr ',  `${year}-04-02`);
    testParse('D MMM', ' 2  Apr ',  `${year}-04-02`);
    testParse('  D   MMM   ', '2 Apr',  `${year}-04-02`);

    testParse(null, '  11-18-94     ',       '1994-11-18');
    testParse('   DD   MM   YY', '18/11/94', '1994-11-18');
  });

  it('should allow parsing common date-time formats', function() {
    // These are the test cases from before.
    testTimeParse('22:18:04', '22:18:04');
    testTimeParse('8pm',      '20:00:00');
    testTimeParse('22:18:04', '22:18:04', 'UTC');
    testTimeParse('22:18:04', '03:18:04', 'America/New_York');
    testTimeParse('22:18:04', '06:18:04', 'America/Los_Angeles');
    testTimeParse('22:18:04', '13:18:04', 'Japan');

    // Weird time formats are no longer parsed
    // testTimeParse('HH-mm',    '1-15',     '01:15:00');
    // testTimeParse('ss mm HH', '4 23 3',   '03:23:04');

    // The current behavior parses any standard-like format (with HH:MM:SS components in the usual
    // order) regardless of the format requested.

    // Test a few variations of spelling AM/PM.
    for (const [am, pm] of [['A', ' p'], ['  am', 'pM'], ['AM', ' PM']]) {
      testTimeParse('1', '01:00:00');
      testTimeParse('1' + am, '01:00:00');
      testTimeParse('1' + pm, '13:00:00');
      testTimeParse('22', '22:00:00');
      testTimeParse('22' + am, '22:00:00');   // Best guess for 22am/22pm is 22:00.
      testTimeParse('22' + pm, '22:00:00');
      testTimeParse('0', '00:00:00');
      testTimeParse('0' + am, '00:00:00');
      testTimeParse('0' + pm, '00:00:00');
      testTimeParse('12', '12:00:00');        // 12:00 is more likely 12pm than 12am
      testTimeParse('12' + am, '00:00:00');
      testTimeParse('12' + pm, '12:00:00');
      testTimeParse('9:8', '09:08:00');
      testTimeParse('9:8' + am, '09:08:00');
      testTimeParse('9:8' + pm, '21:08:00');
      testTimeParse('09:08', '09:08:00');
      testTimeParse('09:08' + am, '09:08:00');
      testTimeParse('09:08' + pm, '21:08:00');
      testTimeParse('21:59', '21:59:00');
      testTimeParse('21:59' + am, '21:59:00');
      testTimeParse('21:59' + pm, '21:59:00');
      testTimeParse('10:18:04', '10:18:04');
      testTimeParse('10:18:04' + am, '10:18:04');
      testTimeParse('10:18:04' + pm, '22:18:04');
      testTimeParse('22:18:04', '22:18:04');
      testTimeParse('22:18:04' + am, '22:18:04');
      testTimeParse('22:18:04' + pm, '22:18:04');
      testTimeParse('12:18:04', '12:18:04');
      testTimeParse('12:18:04' + am, '00:18:04');
      testTimeParse('12:18:04' + pm, '12:18:04');
      testTimeParse('908', '09:08:00');
      testTimeParse('0910', '09:10:00');
      testTimeParse('2112', '21:12:00');
    }

    // Tests with time zones.
    testTimeParse('09:08', '09:08:00', 'UTC');
    testTimeParse('09:08', '14:08:00', 'America/New_York');
    testTimeParse('09:08', '00:08:00', 'Japan');
    testTimeParse('09:08 Z', '09:08:00');
    testTimeParse('09:08z', '09:08:00');
    testTimeParse('09:08 UT', '09:08:00');
    testTimeParse('09:08 UTC', '09:08:00');
    testTimeParse('09:08-05', '14:08:00');
    testTimeParse('09:08-5', '14:08:00');
    testTimeParse('09:08-0500', '14:08:00');
    testTimeParse('09:08-05:00', '14:08:00');
    testTimeParse('09:08-500', '14:08:00');
    testTimeParse('09:08-5:00', '14:08:00');
    testTimeParse('09:08+05', '04:08:00');
    testTimeParse('09:08+5', '04:08:00');
    testTimeParse('09:08+0500', '04:08:00');
    testTimeParse('09:08+5:00', '04:08:00');
    testTimeParse('09:08+05:00', '04:08:00');
  });

  it('should handle timezone abbreviations', function() {
    // New York can be abbreviated as EDT or EST depending on the time of year for daylight savings.
    // We ignore the abbreviation so it's parsed the same whichever is used.
    // However the parsed UTC time depends on the date.
    testDateTimeParse('2020-02-02', '09:45 edt', '2020-02-02 14:45:00', 'America/New_York');
    testDateTimeParse('2020-10-10', '09:45 edt', '2020-10-10 13:45:00', 'America/New_York');
    testDateTimeParse('2020-02-02', '09:45 est', '2020-02-02 14:45:00', 'America/New_York');
    testDateTimeParse('2020-10-10', '09:45 est', '2020-10-10 13:45:00', 'America/New_York');
    // Spaces and case shouldn't matter.
    testDateTimeParse('2020-10-10', '09:45 EST', '2020-10-10 13:45:00', 'America/New_York');
    testDateTimeParse('2020-10-10', '09:45EST', '2020-10-10 13:45:00', 'America/New_York');
    testDateTimeParse('2020-10-10', '09:45EDT', '2020-10-10 13:45:00', 'America/New_York');

    // Testing that AEDT is rejected in the New York timezone even though it ends with EDT which is valid.
    testTimeParse('09:45:00 aedt', null, 'America/New_York');
    testTimeParse('09:45:00AEDT',  null, 'America/New_York');
    testTimeParse('09:45:00 aedt', '23:45:00', 'Australia/ACT');
    testTimeParse('09:45:00AEDT',  '23:45:00', 'Australia/ACT');

    // Testing multiple abbreviations of US/Pacific
    testDateTimeParse('2020-02-02', '09:45 PST', null, 'America/New_York');
    testDateTimeParse('2020-02-02', '09:45 PST', '2020-02-02 17:45:00', 'US/Pacific');
    testDateTimeParse('2020-10-10', '09:45 PST', '2020-10-10 16:45:00', 'US/Pacific');
    testDateTimeParse('2020-02-02', '09:45 PDT', '2020-02-02 17:45:00', 'US/Pacific');
    testDateTimeParse('2020-10-10', '09:45 PDT', '2020-10-10 16:45:00', 'US/Pacific');
    // PWT and PPT are some obscure abbreviations apparently used at some time and thus supported by moment
    testDateTimeParse('2020-10-10', '09:45 PWT', '2020-10-10 16:45:00', 'US/Pacific');
    testDateTimeParse('2020-10-10', '09:45 PPT', '2020-10-10 16:45:00', 'US/Pacific');
    // POT is not valid
    testDateTimeParse('2020-10-10', '09:45 POT', null, 'US/Pacific');

    // Both these timezones have CST and CDT, but not COT.
    // The timezones are far apart so the parsed UTC times are too.
    testTimeParse('09:45 CST', '01:45:00', 'Asia/Shanghai');
    testTimeParse('09:45 CDT', '01:45:00', 'Asia/Shanghai');
    testTimeParse('09:45 CST', '15:45:00', 'Canada/Central');
    testTimeParse('09:45 CDT', '15:45:00', 'Canada/Central');
    testTimeParse('09:45 COT', null, 'Asia/Shanghai');
    testTimeParse('09:45 COT', null, 'Canada/Central');
  });

  it('should parse datetime strings', function() {
    for (const separator of [' ', 'T']) {
      for (let tz of ['Z', 'UTC', '+00:00', '-00', '']) {
        for (const tzSeparator of ['', ' ']) {
          tz = tzSeparator + tz;

          let expected = '2020-03-04 12:34:56';
          testDateTimeStringParse(
            ` 2020-03-04${separator}12:34:56${tz} `, expected, 'YYYY-MM-DD'
          );
          testDateTimeStringParse(
            ` 03-04-2020${separator}12:34:56${tz} `, expected, 'MM/DD/YYYY'
          );
          testDateTimeStringParse(
            ` 04-03-20${separator}12:34:56${tz} `, expected, 'DD-MM-YY'
          );
          testDateTimeStringParse(
            ` 2020-03-04${separator}12:34:56${tz} `, expected, '',
          );
          expected = '2020-03-04 12:34:00';
          testDateTimeStringParse(
            ` 04-03-20${separator}12:34${tz} `, expected, 'DD-MM-YY'
          );
        }
      }
    }
  });

  it('should handle datetimes as formatted by moment', function() {
    this.timeout(10000);  // there may be a LOT of timezone names.
    for (const date of ['2020-02-03', '2020-06-07', '2020-10-11']) {  // different months for daylight savings
      const dateTime = date + ' 12:34:56';
      const utcMoment = moment.tz(dateTime, 'UTC');
      for (const dateFormat of ['DD/MM/YY', 'MM/DD/YY']) {
        for (const tzFormat of ['z', 'Z']) {  // abbreviation (z) vs +/-HH:MM (Z)
          assert.isTrue(utcMoment.isValid());
          for (const tzName of moment.tz.names()) {
            const tzMoment = moment.tz(utcMoment, tzName);
            const formattedTime = tzMoment.format('HH:mm:ss ' + tzFormat);
            const formattedDate = tzMoment.format(dateFormat);
            testDateTimeParse(formattedDate, formattedTime, dateTime, tzName, dateFormat);
          }
        }
      }
    }
  });

  it('should be flexible in parsing the preferred format', function() {
    for (const format of ['DD-MM-YYYY', 'DD-MM-YY', 'DD-MMM-YYYY', 'DD-MMM-YY']) {
      testParse(format, '1/2/21',     '2021-02-01');
      testParse(format, '01/02/2021', '2021-02-01');
      testParse(format, '1-02-21',    '2021-02-01');
    }

    for (const format of ['MM-DD-YYYY', 'MM-DD-YY', 'MMM-DD-YYYY', 'MMM-DD-YY']) {
      testParse(format, '1/2/21',     '2021-01-02');
      testParse(format, '01/02/2021', '2021-01-02');
      testParse(format, '1-02-21',    '2021-01-02');
    }

    for (const format of ['YY-MM-DD', 'YYYY-MM-DD', 'YY-MMM-DD', 'YYYY-MMM-DD']) {
      testParse(format, '01/2/3',     '2001-02-03');
      testParse(format, '2001/02/03', '2001-02-03');
      testParse(format, '01-02-03',   '2001-02-03');
      testParse(format, '10/11',      `${year}-10-11`);
      testParse(format, '2/3',        `${year}-02-03`);
      testParse(format, '12',         `${year}-${month}-12`);
    }

    testParse('DD MMM YYYY', '1 FEB 2021', '2021-02-01');
    testParse('DD MMM YYYY', '1-feb-21',   '2021-02-01');
    testParse('DD MMM YYYY', '1/2/21',     '2021-02-01');
    testParse('DD MMM YYYY', '01/02/2021', '2021-02-01');
    testParse('DD MMM YYYY', '1-02-21',    '2021-02-01');
    testParse('DD MMM YYYY', '1 2',        `${year}-02-01`);
    testParse('DD MMM YYYY', '1 feb',      `${year}-02-01`);

    testParse('DD MMM', '1 FEB 2021', '2021-02-01');
    testParse('DD MMM', '1-feb-2021', '2021-02-01');
    testParse('DD MMM', '1/2/2021',   '2021-02-01');
    testParse('DD MMM', '01/02/2021', '2021-02-01');
    testParse('DD MMM', '1-02-2021',  '2021-02-01');
    testParse('DD MMM', '1 2 2021',   `2021-02-01`);
    testParse('DD MMM', '1 feb 2021', `2021-02-01`);
  });

  it('should support underscores as separators', async function() {
    testParse('DD_MM_YY', '3/4',      `${year}-04-03`);
    testParse('DD_MM_YY', '3_4',      `${year}-04-03`);
    testParse('DD_MM_YY', '3_4_98',   `1998-04-03`);
    testParse('DD/MM/YY', '3_4_98',   `1998-04-03`);
  });

  it('should interpret two-digit years as bootstrap datepicker does', function() {
    const yy = year % 100;
    // These checks are expected to work as long as today's year is between 2021 and 2088.
    testParse('MM-DD-YY', `1/2/${yy}`, `20${yy}-01-02`);
    testParse('MM-DD-YY', `1/2/${yy + 9}`, `20${yy + 9}-01-02`);
    testParse('MM-DD-YY', `1/2/${yy + 11}`, `19${yy + 11}-01-02`);
    // These should work until 2045 (after that 55 would be interpreted as 2055).
    testParse('MM-DD-YY', `1/2/00`, `2000-01-02`);
    testParse('MM-DD-YY', `1/2/08`, `2008-01-02`);
    testParse('MM-DD-YY', `1/2/20`, `2020-01-02`);
    testParse('MM-DD-YY', `1/2/30`, `2030-01-02`);
    testParse('MM-DD-YY', `1/2/55`, `1955-01-02`);
    testParse('MM-DD-YY', `1/2/79`, `1979-01-02`);
    testParse('MM-DD-YY', `1/2/98`, `1998-01-02`);
  });

  describe('guessDateFormat', function() {
    it('should guess date formats', function() {
      // guessDateFormats with an *s* shows all the equally likely guesses.
      // It's only directly used in tests, just to reveal the inner workings.
      // guessDateFormat picks one of those formats which is actually used in type conversion etc.

      // ISO YYYY-MM-DD is king
      assert.deepEqual(guessDateFormats(["2020-01-02"]), ["YYYY-MM-DD"]);
      assert.deepEqual(guessDateFormat(["2020-01-02"]), "YYYY-MM-DD");

      // Some ambiguous dates
      assert.deepEqual(guessDateFormats(["01/01/2020"]), ["DD/MM/YYYY", "MM/DD/YYYY"]);
      assert.deepEqual(guessDateFormats(["01/02/03"]), ['DD/MM/YY', 'MM/DD/YY', 'YY/MM/DD']);
      assert.deepEqual(guessDateFormats(["01-01-2020"]), ["DD-MM-YYYY", "MM-DD-YYYY"]);
      assert.deepEqual(guessDateFormats(["01-02-03"]), ['DD-MM-YY', 'MM-DD-YY', 'YY-MM-DD']);
      assert.deepEqual(guessDateFormat(["01/01/2020"]), "MM/DD/YYYY");
      assert.deepEqual(guessDateFormat(["01/02/03"]), 'YY/MM/DD');
      assert.deepEqual(guessDateFormat(["01-01-2020"]), "MM-DD-YYYY");
      assert.deepEqual(guessDateFormat(["01-02-03"]), 'YY-MM-DD');

      // Ambiguous date with only two parts
      assert.deepEqual(guessDateFormats(["01/02"]), ["DD/MM", "MM/DD", "YY/MM"]);
      assert.deepEqual(guessDateFormat(["01/02"]), "YY/MM");

      // First date is ambiguous, second date makes the guess unambiguous.
      assert.deepEqual(guessDateFormats(["01/01/2020", "20/01/2020"]), ["DD/MM/YYYY"]);
      assert.deepEqual(guessDateFormats(["01/01/2020", "01/20/2020"]), ["MM/DD/YYYY"]);
      assert.deepEqual(guessDateFormat(["01/01/2020", "20/01/2020"]), "DD/MM/YYYY");
      assert.deepEqual(guessDateFormat(["01/01/2020", "01/20/2020"]), "MM/DD/YYYY");

      // Not a date at all, guess YYYY-MM-DD as the default.
      assert.deepEqual(guessDateFormats(["foo bar"]), null);
      assert.deepEqual(guessDateFormat(["foo bar"]), "YYYY-MM-DD");
    });
  });
});
