This commit is contained in:
Rob Lourens 2015-10-26 19:14:42 -07:00
Родитель 7deb6f654b
Коммит e26bb495a7
7 изменённых файлов: 113 добавлений и 46 удалений

2
.vscode/launch.json поставляемый
Просмотреть файл

@ -8,7 +8,7 @@
"runtimeArgs": ["--harmony"],
"stopOnEntry": false,
"args": [ "--server=4712" ],
"sourceMaps": true,
//"sourceMaps": true,
"outDir": "out"
},
{

17
test/testUtils.ts Normal file
Просмотреть файл

@ -0,0 +1,17 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import * as assert from 'assert';
export function setupUnhandledRejectionListener(): void {
process.addListener('unhandledRejection', unhandledRejectionListener);
}
export function removeUnhandledRejectionListener(): void {
process.removeListener('unhandledRejection', unhandledRejectionListener);
}
function unhandledRejectionListener(reason, p) {
console.log(`ERROR!! Unhandled promise rejection: ${reason}`);
}

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

@ -4,32 +4,74 @@
import * as mockery from 'mockery';
import * as assert from 'assert';
import * as testUtils from '../testUtils';
/** Utilities without mocks - use for type only */
import * as _Utilities from '../../webkit/webKitDebugAdapter';
import {WebKitDebugAdapter as _WebKitDebugAdapter} from '../../webkit/webKitDebugAdapter';
const MODULE_UNDER_TEST = '../../webkit/webKitDebugAdapter';
suite('WebKitDebugAdapter', () => {
setup(() => {
testUtils.setupUnhandledRejectionListener();
mockery.enable({ useCleanCache: true, warnOnReplace: false });
mockery.registerAllowable(MODULE_UNDER_TEST);
mockery.registerAllowable('../common/debugSession');
mockery.registerAllowable('../common/handles');
mockery.registerAllowables([
MODULE_UNDER_TEST,
'./utilities']);
mockery.registerMock('./webKitConnection', { });
mockery.registerMock('./utilities', { });
// Allow the common/ stuff - almost none of it is actually used but I can't get rid of the requires entirely
mockery.registerAllowables([
'../common/debugSession',
'../common/handles',
'../common/v8Protocol',
'./v8Protocol',
'events']);
mockery.registerMock('./webKitConnection', { WebKitConnection: MockWebKitConnection });
mockery.registerMock('child_process', { });
mockery.registerMock('url', { });
mockery.registerMock('path', { });
mockery.registerMock('os', { });
mockery.registerMock('net', { });
mockery.registerMock('fs', { });
});
teardown(() => {
testUtils.removeUnhandledRejectionListener();
mockery.deregisterAll();
mockery.disable();
});
suite('launch()', () => {
suite('attach()', () => {
test('fail', done => done('failed!!!!'));
test('if successful, an initialized event is fired', done => {
const WebKitDebugAdapter: typeof _WebKitDebugAdapter = require(MODULE_UNDER_TEST).WebKitDebugAdapter;
const wkda = new WebKitDebugAdapter();
let initializedFired = false;
wkda.registerEventHandler((event: DebugProtocol.Event) => {
if (event.type === 'initialize2') {
initializedFired = true;
} else {
assert.fail('An unexpected event was fired');
}
});
wkda.attach({ address: 'localhost', 'port': 9222 }).then(() => {
if (initializedFired) {
done();
} else {
assert.fail('Attach completed without firing the initialized event');
}
});
});
});
});
});
class MockWebKitConnection {
public on(eventName: string, handler: (msg: any) => void): void {
}
public attach(port: number): Promise<void> {
return Promise.resolve<void>();
}
}

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

@ -123,3 +123,34 @@ export function retryAsync(fn: () => Promise<any>, attempts: number, timeoutBetw
});
}
/**
* Holds a singleton to manage access to console.log.
* Logging is only allowed when running in server mode, because otherwise it goes through the same channel that Code uses to
* communicate with the adapter, which can cause communication issues.
* ALLOW_LOGGING should be set to false when packaging and releasing to ensure it's always disabled.
*/
export class Logger {
private static ALLOW_LOGGING = true;
private static _logger: Logger;
private _isServer: boolean;
public static log(msg: string): void {
if (this._logger) this._logger._log(msg);
}
public static init(isServer: boolean): void {
this._logger = new Logger(isServer);
// Logs tend to come in bursts, so this is useful for providing separation between groups of events that were logged at the same time
setInterval(() => Logger.log('-'), 1000);
}
constructor(isServer: boolean) {
this._isServer = isServer;
}
private _log(msg: string): void {
if (this._isServer && Logger.ALLOW_LOGGING) console.log(msg);
}
}

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

@ -6,7 +6,7 @@ import * as WebSocket from 'ws';
import * as http from 'http';
import {EventEmitter} from 'events';
import * as Utilities from './utilities';
import {Logger} from './webKitDebugSession';
import {Logger} from './utilities';
interface IMessageWithId {
id: number;

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

@ -2,18 +2,22 @@
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import {Event} from '../common/v8protocol';
import {Event} from '../common/v8Protocol';
import {StoppedEvent, InitializedEvent, TerminatedEvent} from '../common/debugSession';
import {Handles} from '../common/handles';
import {WebKitConnection} from './webKitConnection';
import * as Utilities from './utilities';
import {Logger} from './webKitDebugSession';
import {Logger} from './utilities';
import {spawn, ChildProcess} from 'child_process';
import * as NodeUrl from 'url';
import * as Path from 'path';
import * as Os from 'os';
class B {
private _a = new A();
}
interface IPendingBreakpoint {
resolve: (response: SetBreakpointsResponseBody) => void;
reject: (error?: any) => void;
@ -231,7 +235,7 @@ export class WebKitDebugAdapter implements IDebugAdapter {
return Promise.reject('The "port" field is required in the attach config.');
}
this._attach(args.port);
return this._attach(args.port);
}
public setBreakpoints(args: DebugProtocol.SetBreakpointsArguments): Promise<SetBreakpointsResponseBody> {

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

@ -5,11 +5,16 @@
import {Response} from '../common/v8Protocol';
import {DebugSession, ErrorDestination} from '../common/debugSession';
import {WebKitDebugAdapter} from './webKitDebugAdapter';
import {Logger} from './utilities';
import {AdapterProxy} from '../adapter/adapterProxy';
import {LineNumberTransformer} from '../adapter/lineNumberTransformer';
import {SourceMapTransformer} from '../adapter/sourceMaps/sourceMapTransformer';
class A {
}
export class WebKitDebugSession extends DebugSession {
private _adapterProxy: AdapterProxy;
@ -91,35 +96,3 @@ export class WebKitDebugSession extends DebugSession {
}
}
}
/**
* Holds a singleton to manage access to console.log.
* Logging is only allowed when running in server mode, because otherwise it goes through the same channel that Code uses to
* communicate with the adapter, which can cause communication issues.
* ALLOW_LOGGING should be set to false when packaging and releasing to ensure it's always disabled.
*/
export class Logger {
private static ALLOW_LOGGING = true;
private static _logger: Logger;
private _isServer: boolean;
public static log(msg: string): void {
if (this._logger) this._logger._log(msg);
}
public static init(isServer: boolean): void {
this._logger = new Logger(isServer);
// Logs tend to come in bursts, so this is useful for providing separation between groups of events that were logged at the same time
setInterval(() => Logger.log('-'), 1000);
}
constructor(isServer: boolean) {
this._isServer = isServer;
}
private _log(msg: string): void {
if (this._isServer && Logger.ALLOW_LOGGING) console.log(msg);
}
}