This commit is contained in:
Rob Lourens 2015-10-29 15:08:16 -07:00
Родитель 0351251148
Коммит dd4fff0130
2 изменённых файлов: 97 добавлений и 12 удалений

Просмотреть файл

@ -2,6 +2,7 @@
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import * as sinon from 'sinon';
import * as mockery from 'mockery';
import * as assert from 'assert';
@ -14,9 +15,9 @@ suite('Utilities', () => {
mockery.enable({ useCleanCache: true, warnOnReplace: false });
mockery.registerMock('fs', { statSync: () => { } });
mockery.registerMock('os', { platform: () => 'win32' });
mockery.registerMock('url', { });
mockery.registerMock('path', { });
mockery.registerAllowable(MODULE_UNDER_TEST);
mockery.registerAllowables([
'url', 'path', MODULE_UNDER_TEST]);
});
teardown(() => {
@ -178,4 +179,82 @@ suite('Utilities', () => {
});
});
});
suite('webkitUrlToClientUrl()', () => {
const TEST_CLIENT_PATH = 'c:/site/scripts/a.js';
const TEST_WEBKIT_LOCAL_URL = 'file:///' + TEST_CLIENT_PATH;
const TEST_WEBKIT_HTTP_URL = 'http://site.com/page/scripts/a.js';
const TEST_CWD = 'c:/site';
function Utilities(): typeof _Utilities {
return require(MODULE_UNDER_TEST);
}
test('file:/// urls are returned canonicalized', () => {
assert.equal(Utilities().webkitUrlToClientUrl('', TEST_WEBKIT_LOCAL_URL), TEST_CLIENT_PATH);
});
test('an empty string is returned for a missing url', () => {
assert.equal(Utilities().webkitUrlToClientUrl('', ''), '');
});
test('an empty string is returned when the cwd is missing', () => {
assert.equal(Utilities().webkitUrlToClientUrl(null, TEST_WEBKIT_HTTP_URL), '');
});
test('a url without a path returns an empty string', () => {
assert.equal(Utilities().webkitUrlToClientUrl(TEST_CWD, 'http://site.com'), '');
});
test('it searches the disk for a path that exists, built from the url', () => {
const statSync = (path: string) => {
if (path !== TEST_CLIENT_PATH) throw new Error('Not found');
};
mockery.registerMock('fs', { statSync });
assert.equal(Utilities().webkitUrlToClientUrl(TEST_CWD, TEST_WEBKIT_HTTP_URL), TEST_CLIENT_PATH);
});
test(`returns an empty string when it can't resolve a url`, () => {
const statSync = (path: string) => {
throw new Error('Not found');
};
mockery.registerMock('fs', { statSync });
const Utilities = require(MODULE_UNDER_TEST);
assert.equal(Utilities.webkitUrlToClientUrl(TEST_CWD, TEST_WEBKIT_HTTP_URL), '');
});
});
suite('canonicalizeUrl()', () => {
function testCanUrl(inUrl: string, expectedUrl: string): void {
const Utilities: typeof _Utilities = require(MODULE_UNDER_TEST);
assert.equal(Utilities.canonicalizeUrl(inUrl), expectedUrl);
}
test('removes file:///', () => {
testCanUrl('file:///c:/file.js', 'c:/file.js');
});
test('enforces forward slash', () => {
testCanUrl('c:\\thing\\file.js', 'c:/thing/file.js');
});
test('removes file:///', () => {
testCanUrl('file:///c:/file.js', 'c:/file.js');
});
test('ensures local path starts with / on OSX', () => {
mockery.registerMock('os', { platform: () => 'darwin' });
testCanUrl('file:///Users/scripts/app.js', '/Users/scripts/app.js');
});
test('force lowercase drive letter on Win to match VS Code', () => {
// note default 'os' mock is win32
testCanUrl('file:///D:/FILE.js', 'd:/FILE.js');
});
test('http:// url - no change', () => {
const url = 'http://site.com/My/Cool/Site/script.js?stuff';
testCanUrl(url, url);
})
});
});

Просмотреть файл

@ -160,7 +160,9 @@ export class Logger {
}
/**
* http://localhost/app/scripts/code.js => d:/scripts/code.js
* Maps a url from webkit to an absolute local path.
* If not given an absolute path (with file: prefix), searches the current working directory for a matching file.
* http://localhost/scripts/code.js => d:/app/scripts/code.js
* file:///d:/scripts/code.js => d:/scripts/code.js
*/
export function webkitUrlToClientUrl(cwd: string, url: string): string {
@ -181,15 +183,16 @@ export function webkitUrlToClientUrl(cwd: string, url: string): string {
// Search the filesystem under our cwd for the file that best matches the given url
const pathName = nodeUrl.parse(canonicalizeUrl(url)).pathname;
if (!pathName) {
if (!pathName || pathName === '/') {
return '';
}
const pathParts = pathName.split('/');
while (pathParts.length > 0) {
const clientUrl = path.join(cwd, pathParts.join('/'));
if (existsSync(clientUrl)) {
return canonicalizeUrl(clientUrl); // path.join will change / to \
const canClientUrl = canonicalizeUrl(clientUrl); // path.join will change / to \
if (existsSync(canClientUrl)) {
return canonicalizeUrl(canClientUrl);
}
pathParts.shift();
@ -199,18 +202,21 @@ export function webkitUrlToClientUrl(cwd: string, url: string): string {
}
/**
* Modify a url either from the ODP client or the webkit target to a canonical version for comparing.
* The ODP client can handle urls in this format too.
* file:///d:\\scripts\\code.js => d:/scripts/code.js
* Modify a url either from the client or the webkit target to a platform-independent format for comparing.
* The client can handle urls in this format too.
* file:///D:\\scripts\\code.js => d:/scripts/code.js
* file:///Users/me/project/code.js => /Users/me/project/code.js
* c:\scripts\code.js => c:/scripts/code.js
* http://site.com/scripts/code.js => (no change)
*/
export function canonicalizeUrl(url: string): string {
url = url
.replace('file:///', '')
.replace(/\\/g, '/'); // \ to /
// Ensure osx path starts with /, it can be removed when file:/// was stripped
if (url[0] !== '/' && getPlatform() === Platform.OSX) {
// Ensure osx path starts with /, it can be removed when file:/// was stripped.
// Don't add if the url still has a protocol
if (url[0] !== '/' && url.indexOf(':') < 0 && getPlatform() === Platform.OSX) {
url = '/' + url;
}