174 lines
6.0 KiB
Go
174 lines
6.0 KiB
Go
package pcbuilder
|
|
|
|
import "testing"
|
|
|
|
func hasLevel(issues []Issue, level string) bool {
|
|
for _, i := range issues {
|
|
if i.Level == level {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func TestCheckEmptySelectionOnlyReportsMissing(t *testing.T) {
|
|
res := Check(map[string]*Component{}, nil)
|
|
if hasLevel(res.Issues, "error") || hasLevel(res.Issues, "warning") {
|
|
t.Errorf("empty selection should have no error/warning issues, got %+v", res.Issues)
|
|
}
|
|
if !hasLevel(res.Issues, "info") {
|
|
t.Errorf("empty selection should report missing required slots, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckSocketMismatchIsError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{Socket: "AM5"}},
|
|
"motherboard": {Type: "motherboard", Spec: Spec{Socket: "LGA1700"}},
|
|
}, nil)
|
|
if !hasLevel(res.Issues, "error") {
|
|
t.Errorf("expected a socket-mismatch error, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckMatchingSocketNoError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{Socket: "AM5"}},
|
|
"motherboard": {Type: "motherboard", Spec: Spec{Socket: "am5"}}, // case-insensitive match
|
|
}, nil)
|
|
if hasLevel(res.Issues, "error") {
|
|
t.Errorf("matching sockets (case-insensitive) should not error, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
// A CPU whose socket the scraper never extracted (server sockets like
|
|
// SP3/SP5 — see internal/scraper/spec.go's socketRe) must not read as
|
|
// "mismatched" against a board that does have a socket filled in. Missing
|
|
// data means unknown, not incompatible.
|
|
func TestCheckCPUMissingSocketNoError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{Socket: ""}},
|
|
"motherboard": {Type: "motherboard", Spec: Spec{Socket: "AM5"}},
|
|
}, nil)
|
|
if hasLevel(res.Issues, "error") {
|
|
t.Errorf("cpu with no socket data should not error against a board with one, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckMotherboardMissingSocketNoError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{Socket: "AM5"}},
|
|
"motherboard": {Type: "motherboard", Spec: Spec{Socket: ""}},
|
|
}, nil)
|
|
if hasLevel(res.Issues, "error") {
|
|
t.Errorf("motherboard with no socket data should not error against a cpu with one, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckRAMTypeMismatchIsError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"motherboard": {Type: "motherboard", Spec: Spec{RAMType: "DDR5"}},
|
|
}, map[string][]MultiEntry{
|
|
"ram": {{Component: &Component{Type: "ram", Spec: Spec{RAMType: "DDR4"}}, Qty: 1}},
|
|
})
|
|
if !hasLevel(res.Issues, "error") {
|
|
t.Errorf("expected a RAM-type-mismatch error, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckRAMTotalCapacityExceedsMaxIsWarning(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"motherboard": {Type: "motherboard", Spec: Spec{RAMType: "DDR5", MaxRAMGB: 32}},
|
|
}, map[string][]MultiEntry{
|
|
"ram": {{Component: &Component{Type: "ram", Spec: Spec{RAMType: "DDR5", RAMCapacityGB: 16}}, Qty: 3}}, // 48GB > 32GB max
|
|
})
|
|
if !hasLevel(res.Issues, "warning") {
|
|
t.Errorf("expected a RAM-capacity-exceeds-max warning, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckRAMWithinMaxCapacityNoWarning(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"motherboard": {Type: "motherboard", Spec: Spec{RAMType: "DDR5", MaxRAMGB: 128}},
|
|
}, map[string][]MultiEntry{
|
|
"ram": {{Component: &Component{Type: "ram", Spec: Spec{RAMType: "DDR5", RAMCapacityGB: 16}}, Qty: 2}}, // 32GB
|
|
})
|
|
if hasLevel(res.Issues, "warning") {
|
|
t.Errorf("RAM within max should not warn, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckMultipleStorageSumsPrice(t *testing.T) {
|
|
res := Check(map[string]*Component{}, map[string][]MultiEntry{
|
|
"storage": {
|
|
{Component: &Component{Type: "storage", Price: "5000"}, Qty: 1},
|
|
{Component: &Component{Type: "storage", Price: "3000"}, Qty: 2},
|
|
},
|
|
})
|
|
if res.TotalPrice != 11000 {
|
|
t.Errorf("TotalPrice = %v, want 11000 (5000 + 3000*2)", res.TotalPrice)
|
|
}
|
|
}
|
|
|
|
func TestCheckGPUTooLongForCaseIsError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"gpu": {Type: "gpu", Spec: Spec{LengthMM: 350}},
|
|
"case": {Type: "case", Spec: Spec{MaxGPULengthMM: 300}},
|
|
}, nil)
|
|
if !hasLevel(res.Issues, "error") {
|
|
t.Errorf("expected a GPU-too-long error, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckPSUInsufficientIsWarning(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{TDPWatts: 150}},
|
|
"gpu": {Type: "gpu", Spec: Spec{TDPWatts: 300}},
|
|
"psu": {Type: "psu", Spec: Spec{WattageW: 400}}, // 150+300+100 buffer = 550 > 400
|
|
}, nil)
|
|
if !hasLevel(res.Issues, "warning") {
|
|
t.Errorf("expected a PSU-insufficient warning, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckPSUSufficientNoWarning(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{TDPWatts: 65}},
|
|
"gpu": {Type: "gpu", Spec: Spec{TDPWatts: 150}},
|
|
"psu": {Type: "psu", Spec: Spec{WattageW: 650}},
|
|
}, nil)
|
|
if hasLevel(res.Issues, "warning") {
|
|
t.Errorf("sufficient PSU should not warn, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckTotalPriceSumsAllSelected(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Price: "20000"},
|
|
"gpu": {Type: "gpu", Price: "45000.50"},
|
|
}, nil)
|
|
if res.TotalPrice != 65000.50 {
|
|
t.Errorf("TotalPrice = %v, want 65000.50", res.TotalPrice)
|
|
}
|
|
}
|
|
|
|
func TestCheckCoolerSocketUnsupportedIsError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"cpu": {Type: "cpu", Spec: Spec{Socket: "LGA1700"}},
|
|
"cooler": {Type: "cooler", Spec: Spec{SocketsSupported: []string{"AM5", "AM4"}}},
|
|
}, nil)
|
|
if !hasLevel(res.Issues, "error") {
|
|
t.Errorf("expected a cooler-socket error, got %+v", res.Issues)
|
|
}
|
|
}
|
|
|
|
func TestCheckCaseFormFactorUnsupportedIsError(t *testing.T) {
|
|
res := Check(map[string]*Component{
|
|
"motherboard": {Type: "motherboard", Spec: Spec{FormFactor: "ATX"}},
|
|
"case": {Type: "case", Spec: Spec{FormFactorsSupported: []string{"mATX", "ITX"}}},
|
|
}, nil)
|
|
if !hasLevel(res.Issues, "error") {
|
|
t.Errorf("expected a case-form-factor error, got %+v", res.Issues)
|
|
}
|
|
}
|