152 lines
5.8 KiB
TypeScript
152 lines
5.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 AionUi (aionui.com)
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
resolveLocalFileLinkPath,
|
|
resolveLocalFileLinkReference,
|
|
toLocalFileHref,
|
|
} from '@/renderer/components/Markdown/markdownUtils';
|
|
|
|
describe('resolveLocalFileLinkPath', () => {
|
|
it('recognizes Windows absolute paths emitted as root-relative markdown links', () => {
|
|
expect(resolveLocalFileLinkPath('/C:/Users/Administrator/AppData/Roaming/AionUi/report.xlsx')).toBe(
|
|
'C:/Users/Administrator/AppData/Roaming/AionUi/report.xlsx'
|
|
);
|
|
});
|
|
|
|
it('recognizes encoded file URLs', () => {
|
|
expect(resolveLocalFileLinkPath('file:///C:/Users/Administrator/%E7%9C%8B%E6%9D%BF.xlsx')).toBe(
|
|
'C:/Users/Administrator/看板.xlsx'
|
|
);
|
|
});
|
|
|
|
it('recognizes common POSIX absolute paths', () => {
|
|
expect(resolveLocalFileLinkPath('/Users/demo/outputs/report.xlsx')).toBe('/Users/demo/outputs/report.xlsx');
|
|
});
|
|
|
|
it('recognizes file-like POSIX absolute paths outside common home and temp roots', () => {
|
|
expect(resolveLocalFileLinkPath('/opt/aionui/outputs/report.xlsx')).toBe('/opt/aionui/outputs/report.xlsx');
|
|
});
|
|
|
|
it('recognizes line suffixes without confusing Windows drive letters', () => {
|
|
const reference = resolveLocalFileLinkReference('C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421');
|
|
|
|
expect(reference).toEqual({
|
|
filePath: 'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log',
|
|
rawReference: 'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421',
|
|
line: 1421,
|
|
});
|
|
expect(resolveLocalFileLinkPath('C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421')).toBe(
|
|
'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log'
|
|
);
|
|
});
|
|
|
|
it('recognizes line and column suffixes without including the line in the file path', () => {
|
|
const reference = resolveLocalFileLinkReference(
|
|
'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421:7'
|
|
);
|
|
|
|
expect(reference).toEqual({
|
|
filePath: 'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log',
|
|
rawReference: 'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421:7',
|
|
line: 1421,
|
|
column: 7,
|
|
});
|
|
expect(resolveLocalFileLinkPath('C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log:1421:7')).toBe(
|
|
'C:/Users/Administrator/AppData/Roaming/AionUi/logs/app.log'
|
|
);
|
|
});
|
|
|
|
it('recognizes POSIX hash line references', () => {
|
|
expect(resolveLocalFileLinkReference('/Users/demo/file.ts#L10')).toEqual({
|
|
filePath: '/Users/demo/file.ts',
|
|
rawReference: '/Users/demo/file.ts#L10',
|
|
line: 10,
|
|
});
|
|
|
|
expect(resolveLocalFileLinkReference('/Users/demo/file.ts#L10-L20')).toEqual({
|
|
filePath: '/Users/demo/file.ts',
|
|
rawReference: '/Users/demo/file.ts#L10-L20',
|
|
line: 10,
|
|
endLine: 20,
|
|
});
|
|
});
|
|
|
|
it('recognizes file URL hash line references and normalizes raw references', () => {
|
|
expect(resolveLocalFileLinkReference('file:///Users/demo/file.ts#L10')).toEqual({
|
|
filePath: '/Users/demo/file.ts',
|
|
rawReference: '/Users/demo/file.ts#L10',
|
|
line: 10,
|
|
});
|
|
|
|
expect(resolveLocalFileLinkReference('file:///Users/demo/file.ts#L10-L20')).toEqual({
|
|
filePath: '/Users/demo/file.ts',
|
|
rawReference: '/Users/demo/file.ts#L10-L20',
|
|
line: 10,
|
|
endLine: 20,
|
|
});
|
|
|
|
expect(resolveLocalFileLinkReference('file:///Users/demo/My%20File.ts#L10')).toEqual({
|
|
filePath: '/Users/demo/My File.ts',
|
|
rawReference: '/Users/demo/My File.ts#L10',
|
|
line: 10,
|
|
});
|
|
|
|
expect(resolveLocalFileLinkReference('file:///Users/demo/%E6%96%87%E4%BB%B6.ts#L10')).toEqual({
|
|
filePath: '/Users/demo/文件.ts',
|
|
rawReference: '/Users/demo/文件.ts#L10',
|
|
line: 10,
|
|
});
|
|
});
|
|
|
|
it('recognizes Windows file URL hash lines and ranges', () => {
|
|
expect(resolveLocalFileLinkReference('file:///C:/Users/demo/file.ts#L10')).toEqual({
|
|
filePath: 'C:/Users/demo/file.ts',
|
|
rawReference: 'C:/Users/demo/file.ts#L10',
|
|
line: 10,
|
|
});
|
|
|
|
expect(resolveLocalFileLinkReference('file:///C:/Users/demo/file.ts#L10-L20')).toEqual({
|
|
filePath: 'C:/Users/demo/file.ts',
|
|
rawReference: 'C:/Users/demo/file.ts#L10-L20',
|
|
line: 10,
|
|
endLine: 20,
|
|
});
|
|
});
|
|
|
|
it('prioritizes hash line references over colon suffixes', () => {
|
|
expect(resolveLocalFileLinkReference('/Users/demo/file.ts:10#L20')).toEqual({
|
|
filePath: '/Users/demo/file.ts',
|
|
rawReference: '/Users/demo/file.ts#L20',
|
|
line: 20,
|
|
});
|
|
});
|
|
|
|
it('rejects unsupported hash line formats and remote hash links', () => {
|
|
expect(resolveLocalFileLinkReference('user.ts')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('./user.ts')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('../user.ts')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('/settings')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('https://aionui.com/docs#L10')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('https://github.com/org/repo/blob/main/file.ts#L10')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('/Users/demo/file.ts#l10')).toBeNull();
|
|
expect(resolveLocalFileLinkReference('/Users/demo/file.ts#L10-l20')).toBeNull();
|
|
});
|
|
|
|
it('does not treat normal web links or app routes as local files', () => {
|
|
expect(resolveLocalFileLinkPath('https://aionui.com/docs')).toBeNull();
|
|
expect(resolveLocalFileLinkPath('/settings')).toBeNull();
|
|
});
|
|
|
|
it('formats local file paths as file URLs for browser link copying', () => {
|
|
expect(toLocalFileHref('C:/Users/Administrator/AppData/Roaming/AionUi/report.xlsx')).toBe(
|
|
'file:///C:/Users/Administrator/AppData/Roaming/AionUi/report.xlsx'
|
|
);
|
|
expect(toLocalFileHref('/var/folders/demo/report.xlsx')).toBe('file:///var/folders/demo/report.xlsx');
|
|
});
|
|
});
|