Add emoji-heatmap.js utility module with tests

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-24 22:57:19 +00:00
parent 4ac6f42b38
commit f1b267a12a
2 changed files with 120 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
// bot/utils/emoji-heatmap.js
module.exports = function calculateEmojiStats(reactions = []) {
const stats = {
"✅": 0,
"❌": 0,
"🛟": 0,
"🤔": 0,
total: 0,
};
reactions.forEach(({ content }) => {
if (stats.hasOwnProperty(content)) {
stats[content]++;
stats.total++;
}
});
const percent = (count) =>
stats.total > 0 ? `${Math.round((count / stats.total) * 100)}%` : "0%";
return {
total: stats.total,
confirmed: stats["✅"],
blocked: stats["❌"],
escalated: stats["🛟"],
review: stats["🤔"],
report: {
"✅": percent(stats["✅"]),
"❌": percent(stats["❌"]),
"🛟": percent(stats["🛟"]),
"🤔": percent(stats["🤔"]),
},
};
};

View File

@@ -0,0 +1,85 @@
import { describe, it, expect } from "vitest";
const calculateEmojiStats = require("../bot/utils/emoji-heatmap");
describe("calculateEmojiStats", () => {
it("calculates stats for sample reactions", () => {
const sampleReactions = [
{ content: "✅" },
{ content: "✅" },
{ content: "❌" },
{ content: "🛟" },
];
const result = calculateEmojiStats(sampleReactions);
expect(result.total).toBe(4);
expect(result.confirmed).toBe(2);
expect(result.blocked).toBe(1);
expect(result.escalated).toBe(1);
expect(result.review).toBe(0);
expect(result.report["✅"]).toBe("50%");
expect(result.report["❌"]).toBe("25%");
expect(result.report["🛟"]).toBe("25%");
expect(result.report["🤔"]).toBe("0%");
});
it("returns zero stats for empty reactions", () => {
const result = calculateEmojiStats([]);
expect(result.total).toBe(0);
expect(result.confirmed).toBe(0);
expect(result.blocked).toBe(0);
expect(result.escalated).toBe(0);
expect(result.review).toBe(0);
expect(result.report["✅"]).toBe("0%");
expect(result.report["❌"]).toBe("0%");
expect(result.report["🛟"]).toBe("0%");
expect(result.report["🤔"]).toBe("0%");
});
it("handles default parameter (undefined)", () => {
const result = calculateEmojiStats();
expect(result.total).toBe(0);
expect(result.confirmed).toBe(0);
expect(result.blocked).toBe(0);
expect(result.escalated).toBe(0);
expect(result.review).toBe(0);
});
it("ignores untracked reactions", () => {
const mixedReactions = [
{ content: "✅" },
{ content: "🤔" },
{ content: "👍" }, // not tracked
{ content: "❌" },
{ content: "🛟" },
];
const result = calculateEmojiStats(mixedReactions);
expect(result.total).toBe(4); // 👍 is not counted
expect(result.confirmed).toBe(1);
expect(result.blocked).toBe(1);
expect(result.escalated).toBe(1);
expect(result.review).toBe(1);
expect(result.report["✅"]).toBe("25%");
expect(result.report["❌"]).toBe("25%");
expect(result.report["🛟"]).toBe("25%");
expect(result.report["🤔"]).toBe("25%");
});
it("rounds percentages correctly", () => {
const reactions = [
{ content: "✅" },
{ content: "✅" },
{ content: "❌" },
];
const result = calculateEmojiStats(reactions);
expect(result.total).toBe(3);
expect(result.report["✅"]).toBe("67%"); // 2/3 = 66.67% rounded
expect(result.report["❌"]).toBe("33%"); // 1/3 = 33.33% rounded
});
});