feat(ui): replace emoji complexity indicators with clean filled circle characters

Replace 🟢, 🟡, 🔴 emojis with ● character in getComplexityWithColor function

Update corresponding unit tests to expect ● instead of emojis

Improves UI continuity
This commit is contained in:
Eyal Toledano
2025-06-07 12:57:45 -04:00
parent ee0be04302
commit bf2053e140
4 changed files with 1953 additions and 1953 deletions

View File

@@ -2,245 +2,245 @@
* UI module tests
*/
import { jest } from '@jest/globals';
import { jest } from "@jest/globals";
import {
getStatusWithColor,
formatDependenciesWithStatus,
createProgressBar,
getComplexityWithColor
} from '../../scripts/modules/ui.js';
import { sampleTasks } from '../fixtures/sample-tasks.js';
getStatusWithColor,
formatDependenciesWithStatus,
createProgressBar,
getComplexityWithColor,
} from "../../scripts/modules/ui.js";
import { sampleTasks } from "../fixtures/sample-tasks.js";
// Mock dependencies
jest.mock('chalk', () => {
const origChalkFn = (text) => text;
const chalk = origChalkFn;
chalk.green = (text) => text; // Return text as-is for status functions
chalk.yellow = (text) => text;
chalk.red = (text) => text;
chalk.cyan = (text) => text;
chalk.blue = (text) => text;
chalk.gray = (text) => text;
chalk.white = (text) => text;
chalk.bold = (text) => text;
chalk.dim = (text) => text;
jest.mock("chalk", () => {
const origChalkFn = (text) => text;
const chalk = origChalkFn;
chalk.green = (text) => text; // Return text as-is for status functions
chalk.yellow = (text) => text;
chalk.red = (text) => text;
chalk.cyan = (text) => text;
chalk.blue = (text) => text;
chalk.gray = (text) => text;
chalk.white = (text) => text;
chalk.bold = (text) => text;
chalk.dim = (text) => text;
// Add hex and other methods
chalk.hex = () => origChalkFn;
chalk.rgb = () => origChalkFn;
// Add hex and other methods
chalk.hex = () => origChalkFn;
chalk.rgb = () => origChalkFn;
return chalk;
return chalk;
});
jest.mock('figlet', () => ({
textSync: jest.fn(() => 'Task Master Banner')
jest.mock("figlet", () => ({
textSync: jest.fn(() => "Task Master Banner"),
}));
jest.mock('boxen', () => jest.fn((text) => `[boxed: ${text}]`));
jest.mock("boxen", () => jest.fn((text) => `[boxed: ${text}]`));
jest.mock('ora', () =>
jest.fn(() => ({
start: jest.fn(),
succeed: jest.fn(),
fail: jest.fn(),
stop: jest.fn()
}))
jest.mock("ora", () =>
jest.fn(() => ({
start: jest.fn(),
succeed: jest.fn(),
fail: jest.fn(),
stop: jest.fn(),
}))
);
jest.mock('cli-table3', () =>
jest.fn().mockImplementation(() => ({
push: jest.fn(),
toString: jest.fn(() => 'Table Content')
}))
jest.mock("cli-table3", () =>
jest.fn().mockImplementation(() => ({
push: jest.fn(),
toString: jest.fn(() => "Table Content"),
}))
);
jest.mock('gradient-string', () => jest.fn(() => jest.fn((text) => text)));
jest.mock("gradient-string", () => jest.fn(() => jest.fn((text) => text)));
jest.mock('../../scripts/modules/utils.js', () => ({
CONFIG: {
projectName: 'Test Project',
projectVersion: '1.0.0'
},
log: jest.fn(),
findTaskById: jest.fn(),
readJSON: jest.fn(),
readComplexityReport: jest.fn(),
truncate: jest.fn((text) => text)
jest.mock("../../scripts/modules/utils.js", () => ({
CONFIG: {
projectName: "Test Project",
projectVersion: "1.0.0",
},
log: jest.fn(),
findTaskById: jest.fn(),
readJSON: jest.fn(),
readComplexityReport: jest.fn(),
truncate: jest.fn((text) => text),
}));
jest.mock('../../scripts/modules/task-manager.js', () => ({
findNextTask: jest.fn(),
analyzeTaskComplexity: jest.fn()
jest.mock("../../scripts/modules/task-manager.js", () => ({
findNextTask: jest.fn(),
analyzeTaskComplexity: jest.fn(),
}));
describe('UI Module', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe("UI Module", () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('getStatusWithColor function', () => {
test('should return done status with emoji for console output', () => {
const result = getStatusWithColor('done');
expect(result).toMatch(/done/);
expect(result).toContain('✅');
});
describe("getStatusWithColor function", () => {
test("should return done status with emoji for console output", () => {
const result = getStatusWithColor("done");
expect(result).toMatch(/done/);
expect(result).toContain("✅");
});
test('should return pending status with emoji for console output', () => {
const result = getStatusWithColor('pending');
expect(result).toMatch(/pending/);
expect(result).toContain('⏱️');
});
test("should return pending status with emoji for console output", () => {
const result = getStatusWithColor("pending");
expect(result).toMatch(/pending/);
expect(result).toContain("⏱️");
});
test('should return deferred status with emoji for console output', () => {
const result = getStatusWithColor('deferred');
expect(result).toMatch(/deferred/);
expect(result).toContain('⏱️');
});
test("should return deferred status with emoji for console output", () => {
const result = getStatusWithColor("deferred");
expect(result).toMatch(/deferred/);
expect(result).toContain("⏱️");
});
test('should return in-progress status with emoji for console output', () => {
const result = getStatusWithColor('in-progress');
expect(result).toMatch(/in-progress/);
expect(result).toContain('🔄');
});
test("should return in-progress status with emoji for console output", () => {
const result = getStatusWithColor("in-progress");
expect(result).toMatch(/in-progress/);
expect(result).toContain("🔄");
});
test('should return unknown status with emoji for console output', () => {
const result = getStatusWithColor('unknown');
expect(result).toMatch(/unknown/);
expect(result).toContain('❌');
});
test("should return unknown status with emoji for console output", () => {
const result = getStatusWithColor("unknown");
expect(result).toMatch(/unknown/);
expect(result).toContain("❌");
});
test('should use simple icons when forTable is true', () => {
const doneResult = getStatusWithColor('done', true);
expect(doneResult).toMatch(/done/);
expect(doneResult).toContain('✓');
test("should use simple icons when forTable is true", () => {
const doneResult = getStatusWithColor("done", true);
expect(doneResult).toMatch(/done/);
expect(doneResult).toContain("✓");
const pendingResult = getStatusWithColor('pending', true);
expect(pendingResult).toMatch(/pending/);
expect(pendingResult).toContain('○');
const pendingResult = getStatusWithColor("pending", true);
expect(pendingResult).toMatch(/pending/);
expect(pendingResult).toContain("○");
const inProgressResult = getStatusWithColor('in-progress', true);
expect(inProgressResult).toMatch(/in-progress/);
expect(inProgressResult).toContain('►');
const inProgressResult = getStatusWithColor("in-progress", true);
expect(inProgressResult).toMatch(/in-progress/);
expect(inProgressResult).toContain("►");
const deferredResult = getStatusWithColor('deferred', true);
expect(deferredResult).toMatch(/deferred/);
expect(deferredResult).toContain('x');
});
});
const deferredResult = getStatusWithColor("deferred", true);
expect(deferredResult).toMatch(/deferred/);
expect(deferredResult).toContain("x");
});
});
describe('formatDependenciesWithStatus function', () => {
test('should format dependencies as plain IDs when forConsole is false (default)', () => {
const dependencies = [1, 2, 3];
const allTasks = [
{ id: 1, status: 'done' },
{ id: 2, status: 'pending' },
{ id: 3, status: 'deferred' }
];
describe("formatDependenciesWithStatus function", () => {
test("should format dependencies as plain IDs when forConsole is false (default)", () => {
const dependencies = [1, 2, 3];
const allTasks = [
{ id: 1, status: "done" },
{ id: 2, status: "pending" },
{ id: 3, status: "deferred" },
];
const result = formatDependenciesWithStatus(dependencies, allTasks);
const result = formatDependenciesWithStatus(dependencies, allTasks);
// With recent changes, we expect just plain IDs when forConsole is false
expect(result).toBe('1, 2, 3');
});
// With recent changes, we expect just plain IDs when forConsole is false
expect(result).toBe("1, 2, 3");
});
test('should format dependencies with status indicators when forConsole is true', () => {
const dependencies = [1, 2, 3];
const allTasks = [
{ id: 1, status: 'done' },
{ id: 2, status: 'pending' },
{ id: 3, status: 'deferred' }
];
test("should format dependencies with status indicators when forConsole is true", () => {
const dependencies = [1, 2, 3];
const allTasks = [
{ id: 1, status: "done" },
{ id: 2, status: "pending" },
{ id: 3, status: "deferred" },
];
const result = formatDependenciesWithStatus(dependencies, allTasks, true);
const result = formatDependenciesWithStatus(dependencies, allTasks, true);
// We can't test for exact color formatting due to our chalk mocks
// Instead, test that the result contains all the expected IDs
expect(result).toContain('1');
expect(result).toContain('2');
expect(result).toContain('3');
// We can't test for exact color formatting due to our chalk mocks
// Instead, test that the result contains all the expected IDs
expect(result).toContain("1");
expect(result).toContain("2");
expect(result).toContain("3");
// Test that it's a comma-separated list
expect(result.split(', ').length).toBe(3);
});
// Test that it's a comma-separated list
expect(result.split(", ").length).toBe(3);
});
test('should return "None" for empty dependencies', () => {
const result = formatDependenciesWithStatus([], []);
expect(result).toBe('None');
});
test('should return "None" for empty dependencies', () => {
const result = formatDependenciesWithStatus([], []);
expect(result).toBe("None");
});
test('should handle missing tasks in the task list', () => {
const dependencies = [1, 999];
const allTasks = [{ id: 1, status: 'done' }];
test("should handle missing tasks in the task list", () => {
const dependencies = [1, 999];
const allTasks = [{ id: 1, status: "done" }];
const result = formatDependenciesWithStatus(dependencies, allTasks);
expect(result).toBe('1, 999 (Not found)');
});
});
const result = formatDependenciesWithStatus(dependencies, allTasks);
expect(result).toBe("1, 999 (Not found)");
});
});
describe('createProgressBar function', () => {
test('should create a progress bar with the correct percentage', () => {
const result = createProgressBar(50, 10, {
pending: 20,
'in-progress': 15,
blocked: 5
});
expect(result).toContain('50%');
});
describe("createProgressBar function", () => {
test("should create a progress bar with the correct percentage", () => {
const result = createProgressBar(50, 10, {
pending: 20,
"in-progress": 15,
blocked: 5,
});
expect(result).toContain("50%");
});
test('should handle 0% progress', () => {
const result = createProgressBar(0, 10);
expect(result).toContain('0%');
});
test("should handle 0% progress", () => {
const result = createProgressBar(0, 10);
expect(result).toContain("0%");
});
test('should handle 100% progress', () => {
const result = createProgressBar(100, 10);
expect(result).toContain('100%');
});
test("should handle 100% progress", () => {
const result = createProgressBar(100, 10);
expect(result).toContain("100%");
});
test('should handle invalid percentages by clamping', () => {
const result1 = createProgressBar(0, 10);
expect(result1).toContain('0%');
test("should handle invalid percentages by clamping", () => {
const result1 = createProgressBar(0, 10);
expect(result1).toContain("0%");
const result2 = createProgressBar(100, 10);
expect(result2).toContain('100%');
});
const result2 = createProgressBar(100, 10);
expect(result2).toContain("100%");
});
test('should support status breakdown in the progress bar', () => {
const result = createProgressBar(30, 10, {
pending: 30,
'in-progress': 20,
blocked: 10,
deferred: 5,
cancelled: 5
});
test("should support status breakdown in the progress bar", () => {
const result = createProgressBar(30, 10, {
pending: 30,
"in-progress": 20,
blocked: 10,
deferred: 5,
cancelled: 5,
});
expect(result).toContain('40%');
});
});
expect(result).toContain("40%");
});
});
describe('getComplexityWithColor function', () => {
test('should return high complexity in red', () => {
const result = getComplexityWithColor(8);
expect(result).toMatch(/8/);
expect(result).toContain('🔴');
});
describe("getComplexityWithColor function", () => {
test("should return high complexity in red", () => {
const result = getComplexityWithColor(8);
expect(result).toMatch(/8/);
expect(result).toContain("●");
});
test('should return medium complexity in yellow', () => {
const result = getComplexityWithColor(5);
expect(result).toMatch(/5/);
expect(result).toContain('🟡');
});
test("should return medium complexity in yellow", () => {
const result = getComplexityWithColor(5);
expect(result).toMatch(/5/);
expect(result).toContain("●");
});
test('should return low complexity in green', () => {
const result = getComplexityWithColor(3);
expect(result).toMatch(/3/);
expect(result).toContain('🟢');
});
test("should return low complexity in green", () => {
const result = getComplexityWithColor(3);
expect(result).toMatch(/3/);
expect(result).toContain("●");
});
test('should handle non-numeric inputs', () => {
const result = getComplexityWithColor('high');
expect(result).toMatch(/high/);
expect(result).toContain('🔴');
});
});
test("should handle non-numeric inputs", () => {
const result = getComplexityWithColor("high");
expect(result).toMatch(/high/);
expect(result).toContain("●");
});
});
});