Some path/sourcemap tests and cleanup

This commit is contained in:
Rob Lourens 2015-11-29 20:36:17 -08:00
Родитель e8ee15c0d8
Коммит 691b49f35d
7 изменённых файлов: 86 добавлений и 44 удалений

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

@ -35,7 +35,7 @@ export class SourceMapTransformer implements IDebugTransformer {
private init(args: ILaunchRequestArgs | IAttachRequestArgs): void {
if (args.sourceMaps) {
this._webRoot = utils.getWebRoot(args);
this._sourceMaps = new SourceMaps(utils.getWebRoot(args));
this._sourceMaps = new SourceMaps(this._webRoot);
this._requestSeqToSetBreakpointsArgs = new Map<number, DebugProtocol.SetBreakpointsArguments>();
this._allRuntimeScriptPaths = new Set<string>();
}

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

@ -16,7 +16,7 @@ function createTransformer(): _PathTransformer {
suite('PathTransformer', () => {
const TARGET_URL = 'http://mysite.com/scripts/script1.js';
const CLIENT_URL = 'c:/projects/mysite/scripts/script1.js';
const CLIENT_PATH = 'c:/projects/mysite/scripts/script1.js';
let utilsMock: Sinon.SinonMock;
@ -28,13 +28,7 @@ suite('PathTransformer', () => {
mockery.registerAllowables([MODULE_UNDER_TEST, 'path']);
// Mock the utils functions
const mockedObj = testUtils.getDefaultUtilitiesMock();
utilsMock = testUtils.getSinonMock(mockedObj);
utilsMock.expects('webkitUrlToClientPath')
.once()
.withExactArgs(/*webRoot=*/undefined, TARGET_URL).returns(CLIENT_URL);
mockery.registerMock('../webkit/utilities', mockedObj);
utilsMock = testUtils.createRegisteredSinonMock('../webkit/utilities', testUtils.getDefaultUtilitiesMock());
transformer = createTransformer();
});
@ -50,13 +44,16 @@ suite('PathTransformer', () => {
setup(() => {
// This will be modified by the test, so restore it before each
SET_BP_ARGS = { source: { path: CLIENT_URL } };
SET_BP_ARGS = { source: { path: CLIENT_PATH } };
});
test('resolves correctly when it can map the client script to the target script', () => {
utilsMock.expects('webkitUrlToClientPath')
.withExactArgs(/*webRoot=*/undefined, TARGET_URL).returns(CLIENT_PATH);
utilsMock.expects('canonicalizeUrl')
.once()
.withExactArgs(CLIENT_URL).returns(CLIENT_URL);
.returns(CLIENT_PATH);
utilsMock.expects('isURL')
.withExactArgs(CLIENT_PATH).returns(false);
transformer.scriptParsed(<any>{ body: { scriptUrl: TARGET_URL } });
return transformer.setBreakpoints(<any>SET_BP_ARGS).then(() => {
@ -66,9 +63,14 @@ suite('PathTransformer', () => {
});
test(`doesn't resolve until it can map the client script to the target script`, () => {
utilsMock.expects('webkitUrlToClientPath')
.withExactArgs(/*webRoot=*/undefined, TARGET_URL).returns(CLIENT_PATH);
utilsMock.expects('canonicalizeUrl')
.twice()
.withExactArgs(CLIENT_URL).returns(CLIENT_URL);
.returns(CLIENT_PATH);
utilsMock.expects('isURL')
.twice()
.withArgs(CLIENT_PATH).returns(false);
const setBreakpointsP = transformer.setBreakpoints(<any>SET_BP_ARGS).then(() => {
// If this assert doesn't fail, we know that it resolved at the right time because otherwise it would have no
@ -81,12 +83,26 @@ suite('PathTransformer', () => {
return setBreakpointsP;
});
test(`uses path as-is when it's a URL`, () => {
utilsMock.expects('isURL')
.withExactArgs(TARGET_URL).returns(true);
const args = <any>{ source: { path: TARGET_URL } };
return transformer.setBreakpoints(args).then(() => {
utilsMock.verify();
assert.deepEqual(args, EXPECTED_SET_BP_ARGS);
});
});
});
suite('scriptParsed', () => {
test('Modifies args.source.path of the script parsed event', () => {
utilsMock.expects('webkitUrlToClientPath')
.withExactArgs(/*webRoot=*/undefined, TARGET_URL).returns(CLIENT_PATH);
const scriptParsedArgs = <any>{ body: { scriptUrl: TARGET_URL } };
const expectedScriptParsedArgs = <any>{ body: { scriptUrl: CLIENT_URL } };
const expectedScriptParsedArgs = <any>{ body: { scriptUrl: CLIENT_PATH } };
transformer.scriptParsed(scriptParsedArgs);
assert.deepEqual(scriptParsedArgs, expectedScriptParsedArgs);
});

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

@ -4,12 +4,14 @@
import * as assert from 'assert';
import * as mockery from 'mockery';
import * as path from 'path';
import * as testUtils from '../../testUtils';
import { ISourceMaps, MappingResult } from '../../../adapter/sourceMaps/sourceMaps';
const MODULE_UNDER_TEST = '../../../adapter/sourceMaps/sourceMapTransformer';
const AUTHORED_PATH = 'authored.ts';
const RUNTIME_PATH = 'runtime.js';
const AUTHORED_PATH = 'c:/project/authored.ts';
const RUNTIME_PATH = 'c:/project/runtime.js';
const AUTHORED_LINES = [1, 2, 3];
const RUNTIME_LINES = [2, 5, 8];
const RUNTIME_COLS = [3, 7, 11];
@ -18,12 +20,16 @@ const RUNTIME_COLS = [3, 7, 11];
import {SourceMapTransformer as _SourceMapTransformer} from '../../../adapter/sourceMaps/sourceMapTransformer';
suite('SourceMapTransformer', () => {
let utilsMock: Sinon.SinonMock;
setup(() => {
testUtils.setupUnhandledRejectionListener();
// Set up mockery with SourceMaps mock
// Set up mockery
mockery.enable({ warnOnReplace: false, useCleanCache: true });
mockery.registerAllowables(['os', 'fs', 'url', 'path', '../../webkit/utilities', MODULE_UNDER_TEST]);
utilsMock = testUtils.createRegisteredSinonMock('../../webkit/utilities', testUtils.getDefaultUtilitiesMock());
mockery.registerAllowables([MODULE_UNDER_TEST, 'path']);
});
teardown(() => {
@ -37,6 +43,8 @@ suite('SourceMapTransformer', () => {
mockery.registerMock('./sourceMaps', { SourceMaps: MockSourceMaps });
}
utilsMock.expects('getWebRoot').returns(undefined);
let SourceMapTransformer = require(MODULE_UNDER_TEST).SourceMapTransformer;
const transformer = new SourceMapTransformer();
transformer.launch(<ILaunchRequestArgs><any>{
@ -80,20 +88,16 @@ suite('SourceMapTransformer', () => {
const mock = testUtils.createRegisteredSinonMock('./sourceMaps', undefined, 'SourceMaps');
mock.expects('MapPathFromSource')
.once()
.withArgs(AUTHORED_PATH).returns(null);
.withExactArgs(AUTHORED_PATH).returns(null);
mock.expects('MapPathFromSource')
.once()
.withArgs(AUTHORED_PATH).returns(RUNTIME_PATH);
.withExactArgs(AUTHORED_PATH).returns(RUNTIME_PATH);
mock.expects('AllMappedSources')
.once()
.withArgs(RUNTIME_PATH).returns([AUTHORED_PATH]);
.withExactArgs(RUNTIME_PATH).returns([AUTHORED_PATH]);
mock.expects('ProcessNewSourceMap')
.once();
.withExactArgs(RUNTIME_PATH, 'script.js.map').returns(Promise.resolve());
args.lines.forEach((line, i) => {
mock.expects('MapFromSource')
.once()
.withArgs(AUTHORED_PATH, line, 0)
.withExactArgs(AUTHORED_PATH, line, 0)
.returns({ path: RUNTIME_PATH, line: RUNTIME_LINES[i], column: RUNTIME_COLS[i] });
});
@ -149,20 +153,24 @@ suite('SourceMapTransformer', () => {
});
});
suite('stackTraceResponse', () => {
function getResponseBody(path: string, lines: number[]): IStackTraceResponseBody {
suite('stackTraceResponse()', () => {
function getResponseBody(aPath: string, lines: number[]): IStackTraceResponseBody {
return {
stackFrames: lines.map((line, i) => ({
id: i,
name: 'line ' + i,
line,
column: 0,
source: { path, name: path, sourceReference: 0 }
source: { path: aPath, name: path.basename(aPath), sourceReference: 0 }
}))
};
}
test('modifies the response stackFrames', () => {
utilsMock.expects('existsSync')
.thrice()
.withExactArgs(AUTHORED_PATH).returns(true);
const response = getResponseBody(RUNTIME_PATH, RUNTIME_LINES);
const expected = getResponseBody(AUTHORED_PATH, AUTHORED_LINES);

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

@ -55,13 +55,25 @@ export function getSinonMock(mockBase = {}): Sinon.SinonMock {
return m;
}
/**
* Creates a sinon mock and registers it with mockery.
* @param requireName - The import path to register with mockery
* @param mockInstance - The object to use as a sinon mock base object
* @param name - If specified, mock is registered as { [name]: mockInstance }. e.g. if mocking a class.
* @param asConstructor - If true, the mock instance will be returned when the named mock is called as a constructor
*/
export function createRegisteredSinonMock(requireName: string, mockInstance = {}, name?: string, asConstructor = true): Sinon.SinonMock {
const mock = getSinonMock(mockInstance);
const mockContainer = {};
if (asConstructor) {
mockContainer[name] = () => mockInstance;
let mockContainer: any;
if (name) {
mockContainer = {};
if (asConstructor) {
mockContainer[name] = () => mockInstance;
} else {
mockContainer[name] = mockInstance;
}
} else {
mockContainer[name] = mockInstance;
mockContainer = mockInstance;
}
mockery.registerMock(requireName, mockContainer);
@ -74,6 +86,17 @@ export function createRegisteredSinonMock(requireName: string, mockInstance = {}
*/
export function getDefaultUtilitiesMock(): any {
return {
Logger: { log: () => { } }
Logger: { log: () => { } },
canonicalizeUrl: url => url
};
}
export function registerEmptyMocks(moduleNames: string | string[]): void {
if (typeof moduleNames === 'string') {
moduleNames = [<string>moduleNames];
}
(<string[]>moduleNames).forEach(name => {
mockery.registerMock(name, {});
});
}

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

@ -22,6 +22,7 @@ suite('Utilities', () => {
mockery.enable({ useCleanCache: true, warnOnReplace: false });
mockery.registerMock('fs', { statSync: () => { } });
mockery.registerMock('http', {});
mockery.registerMock('os', { platform: () => 'win32' });
path.sep = '\\';

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

@ -33,12 +33,7 @@ suite('WebKitDebugAdapter', () => {
'events']);
mockery.registerMock('os', { platform: () => 'win32' });
mockery.registerMock('child_process', {});
mockery.registerMock('url', {});
mockery.registerMock('path', {});
mockery.registerMock('net', {});
mockery.registerMock('fs', {});
testUtils.registerEmptyMocks(['child_process', 'url', 'path', 'net', 'fs', 'http']);
mockWebKitConnection = testUtils.createRegisteredSinonMock('./webKitConnection', new DefaultMockWebKitConnection(), 'WebKitConnection');
});

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

@ -2,11 +2,10 @@
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import * as url from 'url';
import * as http from 'http';
import * as os from 'os';
import * as fs from 'fs';
import * as nodeUrl from 'url';
import * as url from 'url';
import * as path from 'path';
const DEFAULT_CHROME_PATH = {
@ -220,7 +219,7 @@ export function webkitUrlToClientPath(webRoot: string, aUrl: string): string {
}
// Search the filesystem under the webRoot for the file that best matches the given url
let pathName = nodeUrl.parse(canonicalizeUrl(aUrl)).pathname;
let pathName = url.parse(canonicalizeUrl(aUrl)).pathname;
if (!pathName || pathName === '/') {
return '';
}