<commit_before><!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="/base/raf.html">
<link rel="import" href="/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 (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 (global.history) {
      realGlobalHistoryPushState = global.history.pushState;
      global.history.pushState = function() {
      };
    }

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

    if (global.sessionStorage) {
      global.sessionStorage.clear();
    }

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

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

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

    if (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>
<commit_msg>Properly detect presence of globals when installing hooks<commit_after><!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="/base/raf.html">
<link rel="import" href="/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>

{'fraction_non_alphanumeric': 0.10679316888045541, 'fraction_numerical': 0.001366223908918406, 'mean_word_length': 2.372408497568467, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2550880', 'n_tokens_mistral': 3784, 'n_tokens_neox': 3632, 'n_words': 639}