chore(repo): initialize planarchy workspace
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
calculateAllocation,
|
||||
calculateTotalCost,
|
||||
countWorkingDays,
|
||||
isWorkday,
|
||||
} from "../allocation/calculator.js";
|
||||
|
||||
const stdAvailability = {
|
||||
monday: 8,
|
||||
tuesday: 8,
|
||||
wednesday: 8,
|
||||
thursday: 8,
|
||||
friday: 8,
|
||||
};
|
||||
|
||||
describe("isWorkday", () => {
|
||||
it("returns true for Monday", () => {
|
||||
expect(isWorkday(new Date("2025-01-06"), stdAvailability)).toBe(true); // Monday
|
||||
});
|
||||
|
||||
it("returns false for Saturday", () => {
|
||||
expect(isWorkday(new Date("2025-01-04"), stdAvailability)).toBe(false); // Saturday
|
||||
});
|
||||
|
||||
it("returns false for Sunday", () => {
|
||||
expect(isWorkday(new Date("2025-01-05"), stdAvailability)).toBe(false); // Sunday
|
||||
});
|
||||
});
|
||||
|
||||
describe("countWorkingDays", () => {
|
||||
it("counts 5 days in a Mon-Fri week", () => {
|
||||
const start = new Date("2025-01-06"); // Monday
|
||||
const end = new Date("2025-01-10"); // Friday
|
||||
expect(countWorkingDays(start, end, stdAvailability)).toBe(5);
|
||||
});
|
||||
|
||||
it("counts 10 days over two Mon-Fri weeks", () => {
|
||||
const start = new Date("2025-01-06"); // Monday
|
||||
const end = new Date("2025-01-17"); // Friday
|
||||
expect(countWorkingDays(start, end, stdAvailability)).toBe(10);
|
||||
});
|
||||
|
||||
it("counts 0 for a weekend-only range", () => {
|
||||
const start = new Date("2025-01-04"); // Saturday
|
||||
const end = new Date("2025-01-05"); // Sunday
|
||||
expect(countWorkingDays(start, end, stdAvailability)).toBe(0);
|
||||
});
|
||||
|
||||
it("counts same day as 1 if it's a workday", () => {
|
||||
const day = new Date("2025-01-06"); // Monday
|
||||
expect(countWorkingDays(day, day, stdAvailability)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("calculateAllocation", () => {
|
||||
it("calculates cost for a full week at 8h/day and 100 EUR/h (10000 cents)", () => {
|
||||
const result = calculateAllocation({
|
||||
lcrCents: 10000, // 100 EUR/h
|
||||
hoursPerDay: 8,
|
||||
startDate: new Date("2025-01-06"), // Monday
|
||||
endDate: new Date("2025-01-10"), // Friday
|
||||
availability: stdAvailability,
|
||||
});
|
||||
|
||||
expect(result.workingDays).toBe(5);
|
||||
expect(result.totalHours).toBe(40);
|
||||
// 5 days × 8h × 10000 cents/h = 400000 cents = 4000 EUR
|
||||
expect(result.totalCostCents).toBe(400000);
|
||||
expect(result.dailyCostCents).toBe(80000);
|
||||
expect(result.dailyBreakdown).toHaveLength(5);
|
||||
});
|
||||
|
||||
it("skips weekend days in breakdown", () => {
|
||||
const result = calculateAllocation({
|
||||
lcrCents: 10000,
|
||||
hoursPerDay: 8,
|
||||
startDate: new Date("2025-01-04"), // Saturday
|
||||
endDate: new Date("2025-01-12"), // Sunday
|
||||
availability: stdAvailability,
|
||||
});
|
||||
|
||||
expect(result.workingDays).toBe(5);
|
||||
const weekendDays = result.dailyBreakdown.filter((d) => !d.isWorkday);
|
||||
expect(weekendDays).toHaveLength(4); // 2 weekends
|
||||
});
|
||||
|
||||
it("caps hours at available hours if requested > available", () => {
|
||||
const limitedAvailability = { ...stdAvailability, monday: 4 };
|
||||
const result = calculateAllocation({
|
||||
lcrCents: 10000,
|
||||
hoursPerDay: 8, // Requested more than available
|
||||
startDate: new Date("2025-01-06"), // Monday only
|
||||
endDate: new Date("2025-01-06"),
|
||||
availability: limitedAvailability,
|
||||
});
|
||||
|
||||
expect(result.totalHours).toBe(4); // Capped at availability
|
||||
expect(result.totalCostCents).toBe(40000); // 4h × 10000 cents
|
||||
});
|
||||
|
||||
it("returns zero for date range with no working days", () => {
|
||||
const result = calculateAllocation({
|
||||
lcrCents: 10000,
|
||||
hoursPerDay: 8,
|
||||
startDate: new Date("2025-01-04"), // Saturday
|
||||
endDate: new Date("2025-01-05"), // Sunday
|
||||
availability: stdAvailability,
|
||||
});
|
||||
|
||||
expect(result.workingDays).toBe(0);
|
||||
expect(result.totalHours).toBe(0);
|
||||
expect(result.totalCostCents).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("calculateTotalCost", () => {
|
||||
it("calculates correctly", () => {
|
||||
// 10000 cents/h × 8h × 5 days = 400000 cents
|
||||
expect(calculateTotalCost(10000, 8, 5)).toBe(400000);
|
||||
});
|
||||
|
||||
it("returns 0 for 0 working days", () => {
|
||||
expect(calculateTotalCost(10000, 8, 0)).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user