<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/base/raf.html">
<link rel="import" href="/tracing/base/event_target.html">
<script>
'use strict';

tr.exportTo('tr.b.unittest', function() {
  var realTvOnAnimationFrameError;
  var realGlobalOnError;
  var realGlobalHistoryPushState;

  function installGlobalTestHooks(runner) {
    realTvOnAnimationFrameError = tr.b.onAnimationFrameError;
    tr.b.onAnimationFrameError = function(error) {
      runner.results.addErrorForCurrentTest(error);
    }

    if (tr.isExported('global.onerror')) {
      realGlobalOnError = global.onerror;
      global.onerror = function(errorMsg, url, lineNumber) {
        runner.results.addErrorForCurrentTest(
            errorMsg + ' at ' + url + ':' + lineNumber);
        if (realGlobalOnError)
          return realGlobalOnError(errorMsg, url, lineNumber);
        return false;
      }
    }

    if (tr.isExported('global.history')) {
      realGlobalHistoryPushState = global.history.pushState;
      global.history.pushState = function() {
      };
    }

    tr.b.unittest.addHTMLOutputForCurrentTest = function(element) {
      runner.results.addHTMLOutputForCurrentTest(element);
    }

    if (tr.isExported('global.sessionStorage')) {
      global.sessionStorage.clear();
    }

    var e = new tr.b.Event('tr-unittest-will-run');
    TestRunner.dispatchEvent(e);
  }

  function uninstallGlobalTestHooks() {
    if (tr.isExported('global.onerror')) {
      global.onerror = realGlobalOnError;
      realGlobalOnError = undefined;
    }

    tr.b.onAnimationFrameError = realTvOnAnimationFrameError;
    realTvOnAnimationFrameError = undefined;

    if (tr.isExported('global.history')) {
      global.history.pushState = realGlobalHistoryPushState;
      realGlobalHistoryPushState = undefined;
    }

    tr.b.unittest.addHTMLOutputForCurrentTest = undefined;
  }


  function TestRunner(results, testCases) {
    this.results_ = results;
    this.testCases_ = testCases;
    this.pendingTestCases_ = [];

    this.runOneTestCaseScheduled_ = false;

    this.runCompletedPromise = undefined;
    this.runCompletedResolver_ = undefined;

    this.currentTestCase_ = undefined;
  }

  TestRunner.prototype = {
    __proto__: Object.prototype,

    beginRunning: function() {
      if (this.pendingTestCases_.length)
        throw new Error('Tests still running!');

      this.runCompletedPromise = new Promise(function(resolve, reject) {
        this.runCompletedResolver_ = {
          resolve: resolve,
          reject: reject
        };
      }.bind(this));

      this.pendingTestCases_ = this.testCases_.slice(0);

      this.scheduleRunOneTestCase_();

      return this.runCompletedPromise;
    },

    beginToStopRunning: function() {
      if (!this.runCompletedResolver_)
        throw new Error('Still running');
      this.pendingTestCases_ = [];
      return this.runCompletedPromise;
    },

    get testCases() {
      return this.testCases_;
    },

    get results() {
      return this.results_;
    },

    scheduleRunOneTestCase_: function() {
      if (this.runOneTestCaseScheduled_)
        return;
      this.runOneTestCaseScheduled_ = true;
      tr.b.requestIdleCallback(this.runOneTestCase_, this);
    },

    runOneTestCase_: function() {
      this.runOneTestCaseScheduled_ = false;

      if (this.pendingTestCases_.length == 0) {
        this.didFinishRunningAllTests_();
        return;
      }

      this.currentTestCase_ = this.pendingTestCases_.splice(0, 1)[0];

      this.results_.willRunTest(this.currentTestCase_);
      if (!this.setUpCurrentTestCase_()) {
        this.results_.didCurrentTestEnd();
        this.currentTestCase_ = undefined;
        this.scheduleRunOneTestCase_();
        return;
      }

      this.runCurrentTestCase_().then(
          function pass(result) {
            try {
              this.tearDownCurrentTestCase_(true);
              if (result)
                this.results_.setReturnValueFromCurrentTest(result);
              this.results_.didCurrentTestEnd();
              this.currentTestCase_ = undefined;
              this.scheduleRunOneTestCase_();
            } catch (e) {
              this.hadInternalError_(e);
              throw e;
            }
          }.bind(this),
          function fail(error) {
            try {
              this.results_.addErrorForCurrentTest(error);
              this.tearDownCurrentTestCase_(false);
              this.results_.didCurrentTestEnd();
              this.currentTestCase_ = undefined;
              this.scheduleRunOneTestCase_();
            } catch (e) {
              this.hadInternalError_(e);
              throw e;
            }
          }.bind(this));
    },

    setUpCurrentTestCase_: function() {
      // Try setting it up. Return true if succeeded.
      installGlobalTestHooks(this);
      try {
        this.currentTestCase_.setUp();
      } catch (error) {
        this.results_.addErrorForCurrentTest(error);
        return false;
      }
      return true;
    },

    runCurrentTestCase_: function() {
      return new Promise(function(resolve, reject) {
        try {
          var maybePromise = this.currentTestCase_.run();
        } catch (error) {
          reject(error);
          return;
        }

        if (maybePromise !== undefined && maybePromise.then) {
          maybePromise.then(
              function(result) {
                resolve(result);
              },
              function(error) {
                reject(error);
              });
        } else {
          resolve(maybePromise);
        }
      }.bind(this));
    },

    hadInternalError_: function(outerE) {
      try {
        this.results.didRunTests();
      } catch (e) {
        console.log('Had another error during hadInternalError_!');
        console.log(e.stack);
      }

      this.runCompletedResolver_.reject(outerE);
      this.runCompletedResolver_ = undefined;
    },

    tearDownCurrentTestCase_: function() {
      try {
        this.currentTestCase_.tearDown();
      } catch (error) {
        this.results_.addErrorForCurrentTest(error);
      }

      uninstallGlobalTestHooks();
    },

    didFinishRunningAllTests_: function() {
      this.results.didRunTests();
      this.runCompletedResolver_.resolve();
      this.runCompletedResolver_ = undefined;
    }
  };

  tr.b.EventTarget.decorate(TestRunner);

  return {
    TestRunner: TestRunner
  };
});
</script>
