Skip to content

Commit 7246ad8

Browse files
committed
Refactor spacesRenderer functions to be module-level exported: getTabDetailsString() and getDefaultSpaceTitle() and add unit tests for them.
1 parent 915d180 commit 7246ad8

File tree

4 files changed

+81
-25
lines changed

4 files changed

+81
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ All notable changes to this project will be documented in this file.
1010
- Updated all code to modern JavaScript and improved documentation.
1111
- Fixed [issue #3](https://github.com/codedread/spaces/issues/3) by escaping
1212
HTML for all extension content.
13-
- Increased unit test coverage from 0% to 7.51%.
13+
- Increased unit test coverage from 0% to ???%.

js/spacesRenderer.js

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
import { escapeHtml } from './utils.js';
22

3+
export function getDefaultSpaceTitle(space) {
4+
const count = space.tabs && space.tabs.length;
5+
if (!count) return '';
6+
const firstTitle = space.tabs[0].title;
7+
if (count === 1) {
8+
return `[${escapeHtml(firstTitle)}]`;
9+
}
10+
return firstTitle.length > 30
11+
? `[${escapeHtml(firstTitle.slice(0, 21))}…] +${count - 1} more`
12+
: `[${escapeHtml(firstTitle)}] +${count - 1} more`;
13+
}
14+
15+
export function getTabDetailsString(space) {
16+
const count = space.tabs && space.tabs.length;
17+
const open = space.windowId;
18+
19+
if (open) {
20+
return '';
21+
}
22+
return `(${count} tab${count !== 1 ? 's' : ''})`;
23+
}
24+
325
// eslint-disable-next-line no-var
426
export const spacesRenderer = {
527
nodes: {},
@@ -56,8 +78,8 @@ export const spacesRenderer = {
5678
listDetail.className = 'spaceDetail';
5779

5880
listTitle.innerHTML =
59-
space.name || spacesRenderer.getDefaultSpaceTitle(space);
60-
listDetail.innerHTML = spacesRenderer.getTabDetailsString(space);
81+
space.name || getDefaultSpaceTitle(space);
82+
listDetail.innerHTML = getTabDetailsString(space);
6183

6284
listContainer.appendChild(listTitle);
6385
listContainer.appendChild(listDetail);
@@ -147,28 +169,6 @@ export const spacesRenderer = {
147169
}
148170
},
149171

150-
getDefaultSpaceTitle(space) {
151-
const count = space.tabs && space.tabs.length;
152-
if (!count) return '';
153-
const firstTitle = space.tabs[0].title;
154-
if (count === 1) {
155-
return `[${escapeHtml(firstTitle)}]`;
156-
}
157-
return firstTitle.length > 30
158-
? `[${escapeHtml(firstTitle.slice(0, 21))}…] +${count - 1} more`
159-
: `[${escapeHtml(firstTitle)}] +${count - 1} more`;
160-
},
161-
162-
getTabDetailsString(space) {
163-
const count = space.tabs && space.tabs.length;
164-
const open = space.windowId;
165-
166-
if (open) {
167-
return '';
168-
}
169-
return `(${count} tab${count > 1 ? 's' : ''})`;
170-
},
171-
172172
updateSpacesList() {
173173
const query = spacesRenderer.nodes.moveInput.value;
174174
let match = false;

tests/getDefaultSpaceTitle.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { getDefaultSpaceTitle } from '../js/spacesRenderer.js';
2+
3+
describe('getDefaultSpaceTitle', () => {
4+
test('should return an empty string if there are no tabs', () => {
5+
const space = { tabs: [] };
6+
expect(getDefaultSpaceTitle(space)).toBe('');
7+
});
8+
9+
test('should return the title of the single tab', () => {
10+
const space = { tabs: [{ title: 'Test Tab' }] };
11+
expect(getDefaultSpaceTitle(space)).toBe('[Test Tab]');
12+
});
13+
14+
test('should return the title of the first tab and a count of the others', () => {
15+
const space = { tabs: [{ title: 'Test Tab' }, { title: 'Another Tab' }] };
16+
expect(getDefaultSpaceTitle(space)).toBe('[Test Tab] +1 more');
17+
});
18+
19+
test('should truncate long titles', () => {
20+
const space = {
21+
tabs: [
22+
{ title: 'This is a very long tab title that should be truncated' },
23+
{ title: 'Another Tab' }
24+
]
25+
};
26+
expect(getDefaultSpaceTitle(space)).toBe('[This is a very long t…] +1 more');
27+
});
28+
29+
test('should escape HTML in the title', () => {
30+
const space = { tabs: [{ title: '<script>alert("xss")</script>' }] };
31+
expect(getDefaultSpaceTitle(space)).toBe('[&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;]');
32+
});
33+
});

tests/getTabDetailsString.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { getTabDetailsString } from '../js/spacesRenderer.js';
2+
3+
describe('getTabDetailsString', () => {
4+
test('should return an empty string if the space is open', () => {
5+
const space = { windowId: 123, tabs: [{ title: 'Test Tab' }] };
6+
expect(getTabDetailsString(space)).toBe('');
7+
});
8+
9+
test('should return (0 tabs) if the space is not open and has no tabs', () => {
10+
const space = { windowId: false, tabs: [] };
11+
expect(getTabDetailsString(space)).toBe('(0 tabs)');
12+
});
13+
14+
test('should return (1 tab) if the space is not open and has one tab', () => {
15+
const space = { windowId: false, tabs: [{ title: 'Test Tab' }] };
16+
expect(getTabDetailsString(space)).toBe('(1 tab)');
17+
});
18+
19+
test('should return (n tabs) if the space is not open and has multiple tabs', () => {
20+
const space = { windowId: false, tabs: [{ title: 'Test Tab' }, { title: 'Another Tab' }] };
21+
expect(getTabDetailsString(space)).toBe('(2 tabs)');
22+
});
23+
});

0 commit comments

Comments
 (0)