← back to Charge And Explore

backend/test/stop-score.test.ts

70 lines

import { describe, it } from "node:test";
import assert from "node:assert/strict";
import {
  routeConvenience,
  chargerQuality,
  scoreStop,
  STOP_SCORE_WEIGHTS,
  type StopScoreComponents,
} from "../src/core/stop-score.ts";

const perfect: StopScoreComponents = {
  route: 100,
  charger: 100,
  amenity: 100,
  timeFit: 100,
  nighttime: 100,
  walkability: 100,
  basicNeeds: 100,
};

describe("routeConvenience", () => {
  it("is 100 at zero detour and decays with detour", () => {
    assert.equal(Math.round(routeConvenience(0)), 100);
    assert.ok(routeConvenience(5) > routeConvenience(20));
  });

  it("never goes negative", () => {
    assert.ok(routeConvenience(1000) >= 0);
  });
});

describe("stop score weights", () => {
  it("weights sum to 1.0", () => {
    const sum = Object.values(STOP_SCORE_WEIGHTS).reduce((a, b) => a + b, 0);
    assert.ok(Math.abs(sum - 1) < 1e-9, `weights sum to ${sum}`);
  });
});

describe("chargerQuality", () => {
  it("stays within 0–100 and rewards power most", () => {
    const highPower = chargerQuality({ power: 100, stalls: 0, reliability: 0, dynamicAvailability: 0 });
    const highAvail = chargerQuality({ power: 0, stalls: 0, reliability: 0, dynamicAvailability: 100 });
    assert.ok(highPower > highAvail);
    assert.ok(highPower <= 100);
  });
});

describe("scoreStop", () => {
  it("a perfect stop scores 100", () => {
    assert.equal(scoreStop(perfect, 1).score, 100);
  });

  it("a zeroed stop scores 0", () => {
    const zero = { ...perfect };
    (Object.keys(zero) as (keyof StopScoreComponents)[]).forEach((k) => (zero[k] = 0));
    assert.equal(scoreStop(zero, 1).score, 0);
  });

  it("labels confidence from data completeness", () => {
    assert.equal(scoreStop(perfect, 0.9).confidence, "high");
    assert.equal(scoreStop(perfect, 0.6).confidence, "limited");
    assert.equal(scoreStop(perfect, 0.2).confidence, "low");
  });

  it("clamps out-of-range component inputs", () => {
    const over = { ...perfect, charger: 999 };
    assert.ok(scoreStop(over, 1).score <= 100);
  });
});