c1e597579f
fix: tab bars no longer shown in overview. Tab bars show name of app with pipe and then title of the app
261 lines
7.4 KiB
TypeScript
261 lines
7.4 KiB
TypeScript
import { describe, test, expect, jest, beforeEach } from '@jest/globals';
|
|
|
|
// Mock the dependencies
|
|
jest.mock('../utils/logger.js', () => ({
|
|
Logger: {
|
|
log: jest.fn(),
|
|
info: jest.fn(),
|
|
debug: jest.fn(),
|
|
warn: jest.fn(),
|
|
error: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock('../utils/events.js', () => ({
|
|
default: jest.fn(),
|
|
}));
|
|
|
|
// Since we can't import the actual WindowContainer that depends on GNOME APIs,
|
|
// we'll test the logic patterns used in the container
|
|
|
|
describe('Container Logic Tests', () => {
|
|
describe('Orientation Toggle Logic', () => {
|
|
enum Layout {
|
|
HORIZONTAL = 0,
|
|
VERTICAL = 1,
|
|
TABBED = 2,
|
|
}
|
|
|
|
const toggleOrientation = (current: Layout): Layout => {
|
|
if (current === Layout.TABBED) return Layout.HORIZONTAL;
|
|
return current === Layout.HORIZONTAL
|
|
? Layout.VERTICAL
|
|
: Layout.HORIZONTAL;
|
|
};
|
|
|
|
test('should toggle from HORIZONTAL to VERTICAL', () => {
|
|
const result = toggleOrientation(Layout.HORIZONTAL);
|
|
expect(result).toBe(Layout.VERTICAL);
|
|
});
|
|
|
|
test('should toggle from VERTICAL to HORIZONTAL', () => {
|
|
const result = toggleOrientation(Layout.VERTICAL);
|
|
expect(result).toBe(Layout.HORIZONTAL);
|
|
});
|
|
|
|
test('should toggle from TABBED to HORIZONTAL', () => {
|
|
const result = toggleOrientation(Layout.TABBED);
|
|
expect(result).toBe(Layout.HORIZONTAL);
|
|
});
|
|
|
|
test('enum reverse mapping should return string names', () => {
|
|
expect(Layout[Layout.HORIZONTAL]).toBe('HORIZONTAL');
|
|
expect(Layout[Layout.VERTICAL]).toBe('VERTICAL');
|
|
expect(Layout[Layout.TABBED]).toBe('TABBED');
|
|
});
|
|
});
|
|
|
|
describe('Window Bounds Calculation', () => {
|
|
test('should calculate horizontal bounds correctly', () => {
|
|
const workArea = { x: 0, y: 0, width: 1000, height: 500 };
|
|
const itemCount = 3;
|
|
const windowWidth = Math.floor(workArea.width / itemCount);
|
|
|
|
const bounds = Array.from({ length: itemCount }, (_, index) => ({
|
|
x: workArea.x + (index * windowWidth),
|
|
y: workArea.y,
|
|
width: windowWidth,
|
|
height: workArea.height,
|
|
}));
|
|
|
|
expect(bounds.length).toBe(3);
|
|
expect(bounds[0].x).toBe(0);
|
|
expect(bounds[1].x).toBe(333);
|
|
expect(bounds[2].x).toBe(666);
|
|
expect(bounds[0].width).toBe(333);
|
|
});
|
|
|
|
test('should calculate vertical bounds correctly', () => {
|
|
const workArea = { x: 0, y: 0, width: 1000, height: 900 };
|
|
const itemCount = 3;
|
|
const windowHeight = Math.floor(workArea.height / itemCount);
|
|
|
|
const bounds = Array.from({ length: itemCount }, (_, index) => ({
|
|
x: workArea.x,
|
|
y: workArea.y + (index * windowHeight),
|
|
width: workArea.width,
|
|
height: windowHeight,
|
|
}));
|
|
|
|
expect(bounds.length).toBe(3);
|
|
expect(bounds[0].y).toBe(0);
|
|
expect(bounds[1].y).toBe(300);
|
|
expect(bounds[2].y).toBe(600);
|
|
expect(bounds[0].height).toBe(300);
|
|
});
|
|
|
|
test('should handle single window bounds', () => {
|
|
const workArea = { x: 100, y: 50, width: 800, height: 600 };
|
|
const itemCount = 1;
|
|
const windowWidth = Math.floor(workArea.width / itemCount);
|
|
|
|
const bounds = [{
|
|
x: workArea.x,
|
|
y: workArea.y,
|
|
width: windowWidth,
|
|
height: workArea.height,
|
|
}];
|
|
|
|
expect(bounds[0].x).toBe(100);
|
|
expect(bounds[0].y).toBe(50);
|
|
expect(bounds[0].width).toBe(800);
|
|
expect(bounds[0].height).toBe(600);
|
|
});
|
|
});
|
|
|
|
describe('Tabbed Bounds Calculation', () => {
|
|
const TAB_BAR_HEIGHT = 24;
|
|
|
|
test('should give all items the same content rect in tabbed mode', () => {
|
|
const workArea = { x: 100, y: 0, width: 1000, height: 500 };
|
|
const itemCount = 3;
|
|
|
|
const contentRect = {
|
|
x: workArea.x,
|
|
y: workArea.y + TAB_BAR_HEIGHT,
|
|
width: workArea.width,
|
|
height: workArea.height - TAB_BAR_HEIGHT,
|
|
};
|
|
|
|
const bounds = Array.from({ length: itemCount }, () => contentRect);
|
|
|
|
expect(bounds.length).toBe(3);
|
|
// All bounds should be identical
|
|
bounds.forEach(b => {
|
|
expect(b.x).toBe(100);
|
|
expect(b.y).toBe(TAB_BAR_HEIGHT);
|
|
expect(b.width).toBe(1000);
|
|
expect(b.height).toBe(500 - TAB_BAR_HEIGHT);
|
|
});
|
|
});
|
|
|
|
test('tab bar rect should occupy top of work area', () => {
|
|
const workArea = { x: 200, y: 50, width: 800, height: 600 };
|
|
|
|
const tabBarRect = {
|
|
x: workArea.x,
|
|
y: workArea.y,
|
|
width: workArea.width,
|
|
height: TAB_BAR_HEIGHT,
|
|
};
|
|
|
|
expect(tabBarRect.x).toBe(200);
|
|
expect(tabBarRect.y).toBe(50);
|
|
expect(tabBarRect.width).toBe(800);
|
|
expect(tabBarRect.height).toBe(TAB_BAR_HEIGHT);
|
|
});
|
|
|
|
test('active tab index should clamp after removal', () => {
|
|
let activeTabIndex = 2;
|
|
const itemCount = 2; // after removing one from 3
|
|
|
|
if (activeTabIndex >= itemCount) {
|
|
activeTabIndex = itemCount - 1;
|
|
}
|
|
|
|
expect(activeTabIndex).toBe(1);
|
|
});
|
|
|
|
test('active tab index should stay at 0 when first item removed', () => {
|
|
let activeTabIndex = 0;
|
|
const itemCount = 2; // after removing one from 3
|
|
|
|
if (activeTabIndex >= itemCount) {
|
|
activeTabIndex = itemCount - 1;
|
|
}
|
|
|
|
expect(activeTabIndex).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('Window Index Finding', () => {
|
|
test('should find window index in array', () => {
|
|
const windows = [
|
|
{ id: 1, title: 'Window 1' },
|
|
{ id: 2, title: 'Window 2' },
|
|
{ id: 3, title: 'Window 3' },
|
|
];
|
|
|
|
const findIndex = (id: number) => {
|
|
for (let i = 0; i < windows.length; i++) {
|
|
if (windows[i].id === id) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
expect(findIndex(2)).toBe(1);
|
|
expect(findIndex(3)).toBe(2);
|
|
expect(findIndex(999)).toBe(-1);
|
|
});
|
|
|
|
test('should safely remove window by index', () => {
|
|
const windows = [
|
|
{ id: 1, title: 'Window 1' },
|
|
{ id: 2, title: 'Window 2' },
|
|
{ id: 3, title: 'Window 3' },
|
|
];
|
|
|
|
const removeWindow = (id: number) => {
|
|
const index = windows.findIndex(w => w.id === id);
|
|
if (index !== -1) {
|
|
windows.splice(index, 1);
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const removed = removeWindow(2);
|
|
expect(removed).toBe(true);
|
|
expect(windows.length).toBe(2);
|
|
expect(windows.find(w => w.id === 2)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('Container Item Reordering', () => {
|
|
test('should reorder items correctly', () => {
|
|
const items = ['A', 'B', 'C', 'D'];
|
|
const originalIndex = 1; // 'B'
|
|
const newIndex = 3;
|
|
|
|
// Remove from original position and insert at new position
|
|
const [item] = items.splice(originalIndex, 1);
|
|
items.splice(newIndex, 0, item);
|
|
|
|
expect(items).toEqual(['A', 'C', 'D', 'B']);
|
|
});
|
|
|
|
test('should handle reordering to same position', () => {
|
|
const items = ['A', 'B', 'C'];
|
|
const originalIndex = 1;
|
|
const newIndex = 1;
|
|
|
|
if (originalIndex !== newIndex) {
|
|
const [item] = items.splice(originalIndex, 1);
|
|
items.splice(newIndex, 0, item);
|
|
}
|
|
|
|
expect(items).toEqual(['A', 'B', 'C']);
|
|
});
|
|
|
|
test('should handle moving first item to last', () => {
|
|
const items = ['A', 'B', 'C'];
|
|
const [item] = items.splice(0, 1);
|
|
items.splice(2, 0, item);
|
|
|
|
expect(items).toEqual(['B', 'C', 'A']);
|
|
});
|
|
});
|
|
});
|