<!DOCTYPE html>
<!--
Copyright 2015 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/core/test_utils.html">

<link rel="import" href="/dashboard/static/embed.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {

  var testOptions = {
    setUp: function() {
      // Reset the sample data for each test, in case they're
      // modified by some test case.
      window.GRAPH_DATA = {
        'data': [
          {'data': [[10000, 345], [12500, 345], [14000, 345]]},
          {'data': [[10000, 101], [12500, 102], [14000, 103]]}
        ],
        'annotations': {
          'series': [
            {'name': 'foo', 'units': 'ms'},
            {'name': 'bar', 'units': 'MB'}
          ],
          '0': {
            '0': {'r_foo': 'A', 'a_default_rev': 'r_foo', 'r_fizz': 123},
            '1': {'r_foo': 'B', 'a_default_rev': 'r_foo', 'r_fizz': 124},
            '2': {'r_foo': 'C', 'a_default_rev': 'r_foo', 'r_fizz': 125}
          },
          '1': {
            '0': {'r_foo': 'A', 'a_default_rev': 'r_foo', 'r_fizz': 123},
            '1': {'r_foo': 'B', 'a_default_rev': 'r_foo', 'r_fizz': 124},
            '2': {'r_foo': 'C', 'a_default_rev': 'r_foo', 'r_fizz': 125}
          }
        }
      };

      window.REVISION_INFO = {
        'r_fizz': {
           'name': 'Fizz Revision',
           'url': 'http://example.com/fizz'
        },
        'r_foo': {
           'name': 'Foo Revision',
           'url': 'http://example.com/foo'
        }
      };
    }
  };

  test('getRevisionDetails', function() {
    var data = GRAPH_DATA.data;
    var annotations = GRAPH_DATA.annotations;

    // If the different series in the graph data have different annotations,
    // but the same revision numbers, then only the annotations in the last
    // series are used. Note, the default revision is first in each list.
    assert.deepEqual(
       {
         10000: [
           {'name': 'Foo Revision', 'value': 'A'},
           {'name': 'Fizz Revision', 'value': 123}
         ],
         12500: [
           {'name': 'Foo Revision', 'value': 'B'},
           {'name': 'Fizz Revision', 'value': 124}
         ],
         14000: [
           {'name': 'Foo Revision', 'value': 'C'},
           {'name': 'Fizz Revision', 'value': 125}
         ]
       },
       embed.getRevisionDetails(data, annotations, REVISION_INFO));

    // If annotations are not provided, then default revision details are
    // still returned.
    assert.deepEqual(
       {
         10000: [{'name': 'X-Value', 'value': 10000}],
         12500: [{'name': 'X-Value', 'value': 12500}],
         14000: [{'name': 'X-Value', 'value': 14000}]
       },
       embed.getRevisionDetails(data, null, REVISION_INFO));
  }, testOptions);

  test('getDisplayRevision', function() {
    // The display revision of a revision that is a sha1 hash is truncated.
    assert.equal(
        '01234ab',
        embed.getDisplayRevision('01234abcde0123456789abcdefabcd0123456789'));
    // The display revision of other values is whatever was passed in.
    assert.equal('abcdefgh', embed.getDisplayRevision('abcdefgh'));
    assert.equal(1234567890, embed.getDisplayRevision(1234567890));
  }, testOptions);

  test('getRevisionName', function() {
    // If there's an entry in the revision info object, use the name there.
    assert.equal('Fizz Revision', embed.getRevisionName(123, 'r_fizz',
                                                        REVISION_INFO));
    assert.equal('Foo Revision', embed.getRevisionName(12345, 'r_foo',
                                                       REVISION_INFO));

    // Otherwise, just use a generic name for the revision type.
    assert.equal('X-Value', embed.getRevisionName(123, 'r_absent',
                                                  REVISION_INFO));
    assert.equal('X-Value', embed.getRevisionName(1234.5, 'r_absent',
                                                  REVISION_INFO));
    assert.equal('X-Value', embed.getRevisionName(123456, 'r_absent', null));
  }, testOptions);

  test('getRevisionLookup', function() {
    var data = GRAPH_DATA.data;
    var annotations = GRAPH_DATA.annotations;
    var revisionDetails = embed.getRevisionDetails(data, annotations,
                                                   REVISION_INFO);

    // The revision lookup array contains the x-values in order.
    assert.deepEqual(
        ['10000', '12500', '14000'],
        embed.getRevisionLookup(revisionDetails));
    assert.deepEqual([], embed.getRevisionLookup({}));
    assert.deepEqual(['100', '200'],
                     embed.getRevisionLookup({200: [], 100: []}));
  }, testOptions);

  test('makeReverseLookup', function() {
    // The makeReverseLookup function makes an object mapping items to indexes.
    assert.deepEqual({'x': 0, 'y': 1}, embed.makeReverseLookup(['x', 'y']));
    assert.deepEqual({'x': 1, 'z': 2},
                     embed.makeReverseLookup(['x', 'x', 'z']));
    assert.deepEqual({}, embed.makeReverseLookup([]));
  }, testOptions);

  test('changeXValuesToIndexes', function() {
    var data = GRAPH_DATA.data;
    var revisionLookup = ['10000', '12500', '14000'];

    // The data series start out like this:
    assert.deepEqual(
       [
         {'data': [[10000, 345], [12500, 345], [14000, 345]]},
         {'data': [[10000, 101], [12500, 102], [14000, 103]]}
       ],
       GRAPH_DATA.data);
    // After calling this function, the x values in all the data series have
    // been changed to indexes.
    embed.changeXValuesToIndexes(data, revisionLookup);
    assert.deepEqual(
       [
         {'data': [[0, 345], [1, 345], [2, 345]]},
         {'data': [[0, 101], [1, 102], [2, 103]]}
       ],
       GRAPH_DATA.data);
  }, testOptions);

  test('xAxisTickFormatter', function() {
    var revisionDetails = {
      100: [
        {'name': 'X Revision', 'value': 111},
        {'name': 'Y Revision', 'value': 'A'}
      ],
      200: [
        {'name': 'Y Revision', 'value': 'B'},
        {'name': 'Z Revision', 'value': '34.43'}
      ]
    };
    var revisionLookup = ['100', '200'];

    // The tick formatter gives the 'value' for the first revision
    // details entry. Note that the number given to the tick formatter
    // is an index in the revision lookup Array.
    assert.equal(
        '111', embed.xAxisTickFormatter(0, revisionDetails, revisionLookup));
    assert.equal(
        'B', embed.xAxisTickFormatter(1, revisionDetails, revisionLookup));

    // The tick formatter still gives values even when the given index isn't
    // an integer.
    assert.equal(
        '111', embed.xAxisTickFormatter(-1, revisionDetails, revisionLookup));
    assert.equal(
        '111', embed.xAxisTickFormatter(0.2, revisionDetails, revisionLookup));
    assert.equal(
        'B', embed.xAxisTickFormatter(0.9, revisionDetails, revisionLookup));
    assert.equal(
        'B', embed.xAxisTickFormatter(1.4, revisionDetails, revisionLookup));

    // If the index isn't found, another string is returned to indicate this.
    assert.equal(
        'undefined',
        embed.xAxisTickFormatter(2, revisionDetails, revisionLookup));
  }, testOptions);

  test('yAxisTickFormatter', function() {
    // Numbers are formatted to have no more than 3 decimal points,
    // and to have commas for the thousands (millions, billions) marker.
    assert.equal('3.142', embed.yAxisTickFormatter(3.14159));
    assert.equal('1,111.1', embed.yAxisTickFormatter(1111.1));
    assert.equal('1,111.1', embed.yAxisTickFormatter(1111.1));
    assert.equal('10,000', embed.yAxisTickFormatter(10000.00));
    assert.equal('1,000,000', embed.yAxisTickFormatter(1000000));
  }, testOptions);

});
</script>
