package main

import (
	"testing"
	"time"
)

func TestScaleSI(t *testing.T) {
	for _, c := range []struct {
		in   float64
		want string
	}{
		{0, "0.00"},
		{999, "999.00"},
		{1000, "1.00 k"},
		{1234567, "1.23 M"},
		{1e12, "1.00 T"},
		{1e15, "1.00 P"},
	} {
		if got := scaleSI(c.in); got != c.want {
			t.Errorf("scaleSI(%v) = %q, want %q", c.in, got, c.want)
		}
	}
}

// Below a thousand a count is the count, since two decimals on a quantity that
// cannot have them read as precision that is not there.
func TestScaleCount(t *testing.T) {
	for _, c := range []struct {
		in   uint64
		want string
	}{
		{0, "0"},
		{999, "999"},
		{1000, "1.00 k"},
	} {
		if got := scaleCount(c.in); got != c.want {
			t.Errorf("scaleCount(%d) = %q, want %q", c.in, got, c.want)
		}
	}
}

func TestScaleTime(t *testing.T) {
	for _, c := range []struct {
		in   time.Duration
		want string
	}{
		{1500 * time.Millisecond, "1.50 s"},
		{90 * time.Second, "1.50 m"},
		{90 * time.Minute, "1.50 h"},
		{36 * time.Hour, "1.50 d"},
	} {
		if got := scaleTime(c.in); got != c.want {
			t.Errorf("scaleTime(%v) = %q, want %q", c.in, got, c.want)
		}
	}
}

func TestCommas(t *testing.T) {
	for _, c := range []struct {
		in   uint64
		want string
	}{
		{0, "0"},
		{999, "999"},
		{1000, "1,000"},
		{1234567, "1,234,567"},
	} {
		if got := commas(c.in); got != c.want {
			t.Errorf("commas(%d) = %q, want %q", c.in, got, c.want)
		}
	}
}

// The table only lines up if colour codes are not counted as width.
func TestPadIgnoresColour(t *testing.T) {
	if got := visWidth(paint("ok", cGreen)); got != 2 {
		t.Errorf("visWidth = %d, want 2", got)
	}
	if got := visWidth(pad(paint("ok", cGreen), 6, true)); got != 6 {
		t.Errorf("padded width = %d, want 6", got)
	}
}

// The break between the two halves of the row has to be the same width on the
// header, the rule and every value line, or the columns drift apart.
func TestStreamTableBreakAligns(t *testing.T) {
	tbl := &streamTable{cols: intervalCols}
	lines := tbl.headerLines()
	row := tbl.emit(make([]string, len(intervalCols)))
	widths := map[string]int{}
	for _, l := range append(lines, row...) {
		widths[l] = visWidth(l)
	}
	var first int
	for _, w := range widths {
		if first == 0 {
			first = w
			continue
		}
		if w != first {
			t.Fatalf("header and value lines disagree on width: %v", widths)
		}
	}
	if first != tbl.width() {
		t.Errorf("lines are %d wide, width() reports %d", first, tbl.width())
	}
}
