12904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
22904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// Redistribution and use in source and binary forms, with or without
32904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// modification, are permitted provided that the following conditions are
42904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// met:
52904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//
62904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//     * Redistributions of source code must retain the above copyright
72904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       notice, this list of conditions and the following disclaimer.
82904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//     * Redistributions in binary form must reproduce the above
92904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       copyright notice, this list of conditions and the following
102904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       disclaimer in the documentation and/or other materials provided
112904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       with the distribution.
122904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//     * Neither the name of Google Inc. nor the names of its
132904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       contributors may be used to endorse or promote products derived
142904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//       from this software without specific prior written permission.
152904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org//
162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
282904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// This file emulates Mocha test framework used in promises-aplus tests.
292904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
302904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar describe;
312904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar it;
322904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar specify;
332904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar before;
342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar after;
352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar beforeEach;
362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar afterEach;
372904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar RunAllTests;
382904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
392904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar assert = require('assert');
402904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
412904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org(function() {
422904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar TIMEOUT = 1000;
432904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgfunction PostMicrotask(fn) {
452904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var o = {};
462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  Object.observe(o, function() {
472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    fn();
482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  });
492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // Change something to enqueue a microtask.
502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  o.x = 'hello';
512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvar context = {
542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  beingDescribed: undefined,
552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  currentSuiteIndex: 0,
562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  suites: []
572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org};
582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgfunction Run() {
602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  function current() {
612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    while (context.currentSuiteIndex < context.suites.length &&
622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org           context.suites[context.currentSuiteIndex].hasRun) {
632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      ++context.currentSuiteIndex;
642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
652904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (context.suites.length == context.currentSuiteIndex) {
662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      return undefined;
672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
682904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return context.suites[context.currentSuiteIndex];
692904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
702904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var suite = current();
712904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (!suite) {
722904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    // done
732904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    print('All tests have run.');
742904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return;
752904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
762904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  suite.Run();
772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
782904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
792904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgRunAllTests = function() {
802904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.currentSuiteIndex = 0;
812904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var numRegularTestCases = 0;
822904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  for (var i = 0; i < context.suites.length; ++i) {
832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    numRegularTestCases += context.suites[i].numRegularTestCases();
842904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
852904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  print(context.suites.length + ' suites and ' + numRegularTestCases +
862904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        ' test cases are found');
872904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  Run();
882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org};
892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgfunction TestCase(name, before, fn, after, isRegular) {
912904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.name = name;
922904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.before = before;
932904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.fn = fn;
942904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.after = after;
952904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.isRegular = isRegular;
962904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.hasDone = false;
972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
982904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
992904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestCase.prototype.RunFunction = function(suite, fn, postAction) {
1002904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (!fn) {
1012904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    postAction();
1022904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return;
1032904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
1042904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  try {
1052904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (fn.length === 0) {
1062904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      // synchronous
1072904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      fn();
1082904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      postAction();
1092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    } else {
1102904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      // asynchronous
1112904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      fn(postAction);
1122904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
1132904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  } catch (e) {
1142904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    suite.ReportError(this, e);
1152904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
1162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
1172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestCase.prototype.MarkAsDone = function() {
1192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.hasDone = true;
1202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  clearTimeout(this.timer);
1212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
1222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestCase.prototype.Run = function(suite, postAction) {
1242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  print('Running ' + suite.description + '#' + this.name + ' ...');
1252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  assert.clear();
1262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.timer = setTimeout(function() {
1282904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    suite.ReportError(this, Error('timeout'));
1292904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }.bind(this), TIMEOUT);
1302904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1312904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.RunFunction(suite, this.before, function(e) {
1322904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (this.hasDone) {
1332904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      return;
1342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
1352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (e instanceof Error) {
1362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      return suite.ReportError(this, e);
1372904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
1382904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (assert.fails.length > 0) {
1392904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      return suite.ReportError(this, assert.fails[0]);
1402904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
1412904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    this.RunFunction(suite, this.fn, function(e) {
1422904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      if (this.hasDone) {
1432904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return;
1442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
1452904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      if (e instanceof Error) {
1462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return suite.ReportError(this, e);
1472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
1482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      if (assert.fails.length > 0) {
1492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return suite.ReportError(this, assert.fails[0]);
1502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
1512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      this.RunFunction(suite, this.after, function(e) {
1522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        if (this.hasDone) {
1532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org          return;
1542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        }
1552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        if (e instanceof Error) {
1562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org          return suite.ReportError(this, e);
1572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        }
1582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        if (assert.fails.length > 0) {
1592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org          return suite.ReportError(this, assert.fails[0]);
1602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        }
1612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        this.MarkAsDone();
1622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        if (this.isRegular) {
1632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org          print('PASS: ' + suite.description + '#' + this.name);
1642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        }
1652904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        PostMicrotask(postAction);
1662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }.bind(this));
1672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }.bind(this));
1682904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }.bind(this));
1692904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org};
1702904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1712904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgfunction TestSuite(described) {
1722904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.description = described.description;
1732904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.cases = [];
1742904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.currentIndex = 0;
1752904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.hasRun = false;
1762904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (described.before) {
1782904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    this.cases.push(new TestCase(this.description + ' :before', undefined,
1792904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 described.before, undefined, false));
1802904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
1812904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  for (var i = 0; i < described.cases.length; ++i) {
1822904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    this.cases.push(new TestCase(described.cases[i].description,
1832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 described.beforeEach,
1842904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 described.cases[i].fn,
1852904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 described.afterEach,
1862904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 true));
1872904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
1882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (described.after) {
1892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    this.cases.push(new TestCase(this.description + ' :after',
1902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 undefined, described.after, undefined, false));
1912904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
1922904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
1932904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
1942904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestSuite.prototype.Run = function() {
1952904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.hasRun = this.currentIndex === this.cases.length;
1962904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (this.hasRun) {
1972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    PostMicrotask(Run);
1982904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return;
1992904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
2002904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2012904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // TestCase.prototype.Run cannot throw an exception.
2022904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.cases[this.currentIndex].Run(this, function() {
2032904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    ++this.currentIndex;
2042904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    PostMicrotask(Run);
2052904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }.bind(this));
2062904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org};
2072904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2082904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestSuite.prototype.numRegularTestCases = function() {
2092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var n = 0;
2102904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  for (var i = 0; i < this.cases.length; ++i) {
2112904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (this.cases[i].isRegular) {
2122904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      ++n;
2132904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
2142904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
2152904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  return n;
2162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgTestSuite.prototype.ReportError = function(testCase, e) {
2192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (testCase.hasDone) {
2202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return;
2212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
2222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  testCase.MarkAsDone();
2232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  this.hasRun = this.currentIndex === this.cases.length;
2242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  print('FAIL: ' + this.description + '#' + testCase.name + ': ' +
2252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        e.name  + ' (' + e.message + ')');
2262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  ++this.currentIndex;
2272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  PostMicrotask(Run);
2282904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org};
2292904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2302904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgdescribe = function(description, fn) {
2312904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var parent = context.beingDescribed;
2322904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  var incomplete = {
2332904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    cases: [],
2342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    description: parent ? parent.description + ' ' + description : description,
2352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    parent: parent,
2362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  };
2372904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed = incomplete;
2382904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  fn();
2392904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed = parent;
2402904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2412904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.suites.push(new TestSuite(incomplete));
2422904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2432904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgspecify = it = function(description, fn) {
2452904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed.cases.push({description: description, fn: fn});
2462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgbefore = function(fn) {
2492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed.before = fn;
2502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgafter = function(fn) {
2532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed.after = fn;
2542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgbeforeEach = function(fn) {
2572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed.beforeEach = fn;
2582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgafterEach = function(fn) {
2612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  context.beingDescribed.afterEach = fn;
2622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
2632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
2642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}());
265