<!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/guid.html">
<link rel="import" href="/tracing/base/unittest/constants.html">
<script>
'use strict';

tr.exportTo('tr.b.unittest', function() {
  var TestTypes = tr.b.unittest.TestTypes;

  function TestCase(name, opt_testFn, opt_options) {
    if (!name)
      throw new Error('Name must be provided');
    this.guid_ = tr.b.GUID.allocate();
    this.suite_ = undefined; // Set by TestSuite.addTest.
    this.name_ = name;

    if (opt_options)
      this.options_ = opt_options;
    else
      this.options_ = {};

    this.testFn_ = opt_testFn;
  }

  TestCase.parseFullyQualifiedName = function(fqn) {
    var i = fqn.lastIndexOf('.');
    if (i == -1)
      throw new Error('FullyQualifiedNames must have a period in them');
    return {
      suiteName: fqn.substr(0, i),
      testCaseName: fqn.substr(i + 1)
    };
  };

  TestCase.prototype = {
    __proto__: Object.prototype,

    get guid() {
      return this.guid_;
    },

    get suite() {
      return this.suite_;
    },

    set suite(suite) {
      if (this.suite_ !== undefined)
        throw new Error('Suite can only be assigned once.');
      this.suite_ = suite;
    },

    get testType() {
      return TestTypes.UNITTEST;
    },

    get name() {
      return this.name_;
    },

    get fullyQualifiedName() {
      return this.suite_.name + '.' + this.name_;
    },

    get options() {
      return this.options_;
    },

    setUp: function() {
      if (this.options_.setUp)
        this.options_.setUp.call(this);
    },

    run: function(htmlHook) {
      return this.testFn_();
    },

    tearDown: function() {
      if (this.options_.tearDown)
        this.options_.tearDown.call(this);
    },

    // TODO(nduca): The routing of this is a bit awkward. Probably better
    // to install a global function.
    addHTMLOutput: function(element) {
      tr.b.unittest.addHTMLOutputForCurrentTest(element);
    }
  };

  function PerfTestCase(name, testFn, opt_options) {
    TestCase.call(this, name, testFn, opt_options);
    this.iterations = this.options.iterations || 10;
  }

  PerfTestCase.prototype = {
    __proto__: TestCase.prototype,

    get testType() {
      return TestTypes.PERFTEST;
    },

    run: function() {
      var durations = [];
      var iterations = this.iterations;
      for (var i = 0; i < iterations; ++i) {
        var start = window.performance.now();
        this.runOneIteration();
        var duration = window.performance.now() - start;
        durations.push(duration);
      }

      var durationStrings = durations.map(function(d) {
        return d.toFixed(2) + 'ms';
      });
      var average = tr.b.Statistics.mean(durations);
      var min = tr.b.Statistics.min(durations);

      var summaryString = ' [';
      summaryString += 'min ' + min.toFixed(2) + 'ms, ';
      summaryString += 'avg ' + average.toFixed(2) + 'ms';
      summaryString += ']';

      return durationStrings.join(', ') + summaryString;
    },

    runOneIteration: function() {
      this.testFn_();
    }
  };

  return {
    TestCase: TestCase,
    PerfTestCase: PerfTestCase
  };
});
</script>
