<!DOCTYPE html>
<!--
Copyright (c) 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="/core/analysis/memory_dump_sub_view_util.html">
<link rel="import" href="/core/test_utils.html">
<link rel="import" href="/core/trace_model/attribute.html">

<script>
'use strict';

tv.b.unittest.testSuite(function() {
  var MemoryColumn = tv.c.analysis.MemoryColumn;
  var ScalarMemoryColumn = tv.c.analysis.ScalarMemoryColumn;
  var MemoryCell = tv.c.analysis.MemoryCell;
  var fieldGetter = tv.c.analysis.fieldGetter;
  var StringAttribute = tv.c.trace_model.StringAttribute;
  var ScalarAttribute = tv.c.trace_model.ScalarAttribute;

  function checkPercent(string, expectedPercent) {
    assert.equal(Number(string.slice(0, -1)), expectedPercent);
    assert.equal(string.slice(-1), '%');
  }

  function buildStringCell(value, units) {
    return new MemoryCell(new StringAttribute(value, units));
  }

  function buildScalarCell(value, units) {
    return new MemoryCell(new ScalarAttribute(value, units));
  }

  test('checkMemoryColumn_fromRows', function() {
    var rows = [
      {
        title: 'Row 1',
        attributes: {
          'cpu_temperature': buildStringCell('C', 'below zero')
        },
        subRows: [
          {
            title: 'Row 1A',
            attributes: {
              'page_size': buildScalarCell('bytes', 1024)
            }
          },
          {
            title: 'Row 1B',
            attributes: {
              'page_size': buildScalarCell('bytes', 512),
              'mixed': buildStringCell('ms', '0.01')
            }
          }
        ]
      },
      {
        title: 'Row 2',
        attributes: {
          'cpu_temperature': undefined,
          'mixed': buildScalarCell('ms', 0.99)
        }
      }
    ];

    var columns = MemoryColumn.fromRows(rows, 'attributes');
    assert.lengthOf(columns, 3);

    var cpuTemperatureColumn = columns[0];
    assert.equal(cpuTemperatureColumn.title, 'cpu_temperature');
    assert.equal(cpuTemperatureColumn.units, 'C');
    assert.instanceOf(cpuTemperatureColumn, MemoryColumn);
    assert.notInstanceOf(cpuTemperatureColumn, ScalarMemoryColumn);

    var pageSizeColumn = columns[1];
    assert.equal(pageSizeColumn.title, 'page_size');
    assert.equal(pageSizeColumn.units, 'bytes');
    assert.instanceOf(pageSizeColumn, ScalarMemoryColumn);

    var mixedColumn = columns[2];
    assert.equal(mixedColumn.title, 'mixed');
    assert.isUndefined(mixedColumn.units);
    assert.instanceOf(mixedColumn, MemoryColumn);
    assert.notInstanceOf(mixedColumn, ScalarMemoryColumn);
  });

  test('checkMemoryColumn_fromAttributeTraits', function() {
    // String attribute.
    var traits = {
      constructor: StringAttribute,
      units: 'Mbps'
    };
    var column = MemoryColumn.fromAttributeTraits(
        'First Column', traits, fieldGetter('x'));
    assert.instanceOf(column, MemoryColumn);
    assert.equal(column.title, 'First Column');
    assert.isUndefined(column.width);
    assert.equal(column.value({x: buildStringCell('Mbps', 'very fast')}),
        'very fast');
    assert.isAbove(column.cmp({x: buildStringCell('Mbps', 'slow')},
        {x: buildStringCell('Mbps', 'fast')}), 0);

    // Scalar attribute.
    var traits = {
      constructor: ScalarAttribute,
      units: 'bytes'
    };
    var column = MemoryColumn.fromAttributeTraits(
        'Second Column', traits, fieldGetter('x'));
    assert.instanceOf(column, MemoryColumn);
    assert.equal(column.title, 'Second Column');
    assert.isUndefined(column.width);
    assert.equal(column.value({x: buildScalarCell('bytes', 1024)}).numBytes,
        1024);
    assert.isAbove(column.cmp({x: buildScalarCell('bytes', 100)},
        {x: buildScalarCell('bytes', 99.99)}), 0);
  });

  test('checkMemoryColumn_spaceEqually', function() {
    // Zero columns.
    var columns = [];
    MemoryColumn.spaceEqually(columns);

    // One column.
    var columns = [
      {
        title: 'First Column',
        value: function(row) { return row.firstData; }
      }
    ];
    MemoryColumn.spaceEqually(columns);
    checkPercent(columns[0].width, 100);

    // Two columns.
    var columns = [
      {
        title: 'First Column',
        value: function(row) { return row.firstData; }
      },
      {
        title: 'Second Column',
        value: function(row) { return row.firstData; }
      }
    ];
    MemoryColumn.spaceEqually(columns);
    checkPercent(columns[0].width, 50);
    checkPercent(columns[1].width, 50);
  });

  test('checkMemoryColumn_attr', function() {
    var c = new MemoryColumn('Test Column', 'ms', fieldGetter('x'));

    // Undefined cell.
    var row = {};
    assert.isUndefined(c.attr(row));

    // Undefined attribute inside cell.
    var row = {x: new MemoryCell(undefined)};
    assert.isUndefined(c.attr(row));

    // Defined attribute inside cell.
    var attr = new ScalarAttribute('hPa', 1013.25);
    var row = {x: new MemoryCell(attr)};
    assert.strictEqual(c.attr(row), attr);
  });

  test('checkMemoryColumn_value', function() {
    var c = new MemoryColumn('Test Column', 'ms', fieldGetter('x'));
    assert.equal(c.title, 'Test Column');
    assert.isUndefined(c.width);

    // Undefined cell.
    var row = {};
    assert.equal(c.value(row), '');

    // Defined cell.
    var row = {x: buildScalarCell('ms', 123)};
    assert.equal(c.value(row), '123');
  });

  test('checkMemoryColumn_cmp', function() {
    var c = new MemoryColumn('Test Column', 'ms', fieldGetter('x'));

    // Cell (or the associated attribute) undefined in one or both rows.
    assert.equal(c.cmp({}, {y: new MemoryCell(undefined)}), 0);
    assert.isAbove(c.cmp({x: buildStringCell('ms', 'negative')}, {}), 0);
    assert.isBelow(c.cmp({}, {x: buildStringCell('ms', 'positive')}), 0);

    // Cell defined in both rows
    assert.equal(c.cmp({x: buildStringCell('t', 'equal')},
        {x: buildStringCell('t', 'equal')}), 0);
    assert.isAbove(c.cmp({x: buildStringCell('u', 'bigger')},
        {x: buildStringCell('u', 'BIG')}), 0);
    assert.isBelow(c.cmp({x: buildStringCell('v', 'small')},
        {x: buildStringCell('v', 'smaLL')}), 0);
  });

  test('checkScalarMemoryColumn_value', function() {
    var c = new ScalarMemoryColumn('Test Column', 'bytes', fieldGetter('x'));
    assert.equal(c.title, 'Test Column');
    assert.isUndefined(c.width);

    // Undefined cell.
    var row = {};
    assert.equal(c.value(row), '');

    // Defined cell.
    var row = {x: buildScalarCell('bytes', 1024)};
    assert.equal(c.value(row).numBytes, 1024);
  });

  test('checkScalarMemoryColumn_cmp', function() {
    var c = new ScalarMemoryColumn('Test Column', 'ms', fieldGetter('x'));

    // Cell (or the associated attribute) undefined in one or both rows.
    assert.equal(c.cmp({}, {y: new MemoryCell(undefined)}), 0);
    assert.isAbove(c.cmp({x: buildScalarCell('ms', -10)}, {}), 0);
    assert.isBelow(c.cmp({}, {x: buildScalarCell('ms', 20)}), 0);

    // Cell defined in both rows
    assert.equal(c.cmp({x: buildScalarCell('ms', 0.01)},
        {x: buildScalarCell('ms', 0.01)}), 0);
    assert.isAbove(c.cmp({x: buildScalarCell('ms', -1)},
        {x: buildScalarCell('ms', -2)}), 0);
    assert.isBelow(c.cmp({x: buildScalarCell('ms', 999)},
        {x: buildScalarCell('ms', 1000)}), 0);
  });

  test('checkFieldGetter', function() {
    // Zero cells.
    var f = fieldGetter();
    var row = {a: 5};
    assert.equal(f(row), row);

    // One cell.
    var f = fieldGetter('p2');
    assert.equal(f({p1: 'wrong', p2: 'right'}), 'right');
    assert.isUndefined(f({p1: 'wrong'}));

    // Multiple cells.
    var f = fieldGetter('b', 'd', 'f');
    assert.equal(f({a: 0, b: {c: 0, d: {e: 0, f: 42}}}), 42);
  });
});
</script>
