package main

import (
	"strings"
	"testing"
)

// The exact list an operator's machine produced: COM1 and COM3 each claimed by
// two devices in the Windows port map, and no order to speak of. The dropdown
// showed every duplicate, and rendered its own value as "COM3COM3" because two
// entries with the same value both counted as selected.
func TestTidySerialPortsDeduplicatesAndOrders(t *testing.T) {
	got := tidySerialPorts([]string{"COM1", "COM1", "COM3", "COM8", "COM9", "COM4", "COM3"})
	want := []string{"COM1", "COM3", "COM4", "COM8", "COM9"}
	if strings.Join(got, ",") != strings.Join(want, ",") {
		t.Errorf("got %v, want %v", got, want)
	}
}

// COM10 after COM9, not between COM1 and COM2 — lexical order is how a port
// gets overlooked on a machine with a dozen of them.
func TestTidySerialPortsSortsNaturally(t *testing.T) {
	got := tidySerialPorts([]string{"COM10", "COM2", "COM1", "COM20", "COM3"})
	want := []string{"COM1", "COM2", "COM3", "COM10", "COM20"}
	if strings.Join(got, ",") != strings.Join(want, ",") {
		t.Errorf("got %v, want %v", got, want)
	}
}

// Not every port is a COMn: a device path or a Unix name must survive, after
// the numbered ones, in its own order.
func TestTidySerialPortsKeepsOtherNames(t *testing.T) {
	got := tidySerialPorts([]string{"/dev/ttyUSB1", "COM3", "/dev/ttyUSB0", "COM1", "", "  "})
	want := []string{"COM1", "COM3", "/dev/ttyUSB0", "/dev/ttyUSB1"}
	if strings.Join(got, ",") != strings.Join(want, ",") {
		t.Errorf("got %v, want %v", got, want)
	}
}

// Case is not identity on Windows: "com3" and "COM3" are one port, and letting
// both through would put the same duplicate back in the list.
func TestTidySerialPortsIgnoresCase(t *testing.T) {
	if got := tidySerialPorts([]string{"COM3", "com3"}); len(got) != 1 || got[0] != "COM3" {
		t.Errorf("got %v, want [COM3]", got)
	}
}
