Merge branch 'roblou/pathMappingChanges' - fix Microsoft/vscode#49472
This commit is contained in:
Коммит
b1b1f4da58
|
@ -5,80 +5,82 @@
|
|||
import * as url from 'url';
|
||||
import * as path from 'path';
|
||||
import { Protocol as Crdp } from 'devtools-protocol';
|
||||
import { logger } from 'vscode-debugadapter';
|
||||
|
||||
import * as utils from '../utils';
|
||||
import { ITarget } from './chromeConnection';
|
||||
import { IPathMapping } from '../debugAdapterInterfaces';
|
||||
|
||||
export function targetUrlToClientPathByPathMappings(scriptUrl: string, pathMapping: any): string {
|
||||
export function targetUrlPathToClientPath(scriptUrlPath: string, pathMapping: IPathMapping): string {
|
||||
if (!pathMapping) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!scriptUrlPath || !scriptUrlPath.startsWith('/')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const mappingKeys = Object.keys(pathMapping)
|
||||
.sort((a, b) => b.length - a.length);
|
||||
for (let pattern of mappingKeys) {
|
||||
// empty pattern match nothing use / to match root
|
||||
if (!pattern) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const mappingRHS = pathMapping[pattern];
|
||||
if (pattern[0] !== '/') {
|
||||
logger.log(`PathMapping keys should be absolute: ${pattern}`);
|
||||
pattern = '/' + pattern;
|
||||
}
|
||||
|
||||
if (pathMappingPatternMatchesPath(pattern, scriptUrlPath)) {
|
||||
return toClientPath(pattern, mappingRHS, scriptUrlPath);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function pathMappingPatternMatchesPath(pattern: string, scriptPath: string): boolean {
|
||||
if (pattern === scriptPath) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pattern.endsWith('/')) {
|
||||
// Don't match /foo with /foobar/something
|
||||
pattern += '/';
|
||||
}
|
||||
|
||||
return scriptPath.startsWith(pattern);
|
||||
}
|
||||
|
||||
export function targetUrlToClientPath(scriptUrl: string, pathMapping: IPathMapping): string {
|
||||
const parsedUrl = url.parse(scriptUrl);
|
||||
if (!parsedUrl.protocol || parsedUrl.protocol.startsWith('file') || !parsedUrl.pathname) {
|
||||
// Skip file: URLs and paths, and invalid things
|
||||
return '';
|
||||
}
|
||||
|
||||
const urlWithoutQuery = parsedUrl.protocol + '//' + parsedUrl.host + parsedUrl.pathname;
|
||||
const mappingKeys = Object.keys(pathMapping)
|
||||
.sort((a, b) => b.length - a.length);
|
||||
for (let pattern of mappingKeys) {
|
||||
// empty pattern match nothing use / to match root
|
||||
if (pattern) {
|
||||
const localPath = pathMapping[pattern];
|
||||
const parsedPattern = url.parse(pattern);
|
||||
|
||||
if (parsedPattern.protocol) {
|
||||
// pattern is an url with protocol
|
||||
if (urlWithoutQuery.startsWith(pattern)) {
|
||||
const clientPath = toClientPath(localPath, parsedUrl.pathname, pattern);
|
||||
if (clientPath) {
|
||||
return clientPath;
|
||||
}
|
||||
}
|
||||
} else if (pattern[0] === '/') {
|
||||
// pattern is absolute
|
||||
if (parsedUrl.pathname.startsWith(pattern)) {
|
||||
const clientPath = toClientPath(localPath, parsedUrl.pathname, pattern);
|
||||
if (clientPath) {
|
||||
return clientPath;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// pattern is relative
|
||||
// avoid matching whole segment
|
||||
pattern = '/' + pattern;
|
||||
const indexOf = parsedUrl.pathname.indexOf(pattern);
|
||||
if (indexOf !== -1) {
|
||||
const clientPath = toClientPath(localPath, parsedUrl.pathname.substring(indexOf), pattern);
|
||||
if (clientPath) {
|
||||
return clientPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
return targetUrlPathToClientPath(parsedUrl.pathname, pathMapping);
|
||||
}
|
||||
|
||||
function toClientPath(localPath: string, source: string, pattern: string): string {
|
||||
if (source.length === pattern.length) {
|
||||
return localPath;
|
||||
} else {
|
||||
// Verify that matching whole segment of the pattern
|
||||
if (source[pattern.length - 1] === '/'
|
||||
|| source[pattern.length] === '/') {
|
||||
const r = decodeURIComponent(source.substring(pattern.length));
|
||||
return path.join(localPath, r);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
function toClientPath(pattern: string, mappingRHS: string, scriptPath: string): string {
|
||||
const rest = decodeURIComponent(scriptPath.substring(pattern.length));
|
||||
const mappedResult = rest ?
|
||||
path.join(mappingRHS, rest) :
|
||||
mappingRHS;
|
||||
|
||||
return mappedResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a url from target to an absolute local path.
|
||||
* Maps a url from target to an absolute local path, if it exists.
|
||||
* 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 targetUrlToClientPath(webRoot: string, aUrl: string): string {
|
||||
export function targetUrlToClientPath2(aUrl: string, pathMapping: IPathMapping): string {
|
||||
if (!aUrl) {
|
||||
return '';
|
||||
}
|
||||
|
@ -90,23 +92,17 @@ export function targetUrlToClientPath(webRoot: string, aUrl: string): string {
|
|||
return canonicalUrl;
|
||||
}
|
||||
|
||||
// If we don't have the client workingDirectory for some reason, don't try to map the url to a client path
|
||||
if (!webRoot) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Search the filesystem under the webRoot for the file that best matches the given url
|
||||
let pathName = decodeURIComponent(url.parse(canonicalUrl).pathname);
|
||||
let pathName = url.parse(canonicalUrl).pathname;
|
||||
if (!pathName || pathName === '/') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Dealing with the path portion of either a url or an absolute path to remote file.
|
||||
// Need to force path.sep separator
|
||||
pathName = pathName.replace(/\//g, path.sep);
|
||||
const pathParts = pathName.split(path.sep);
|
||||
const pathParts = pathName.split(/[\/\\]/);
|
||||
while (pathParts.length > 0) {
|
||||
const clientPath = path.join(webRoot, pathParts.join(path.sep));
|
||||
const joinedPath = '/' + pathParts.join('/');
|
||||
const clientPath = targetUrlPathToClientPath(joinedPath, pathMapping);
|
||||
if (utils.existsSync(clientPath)) {
|
||||
return utils.canonicalizeUrl(clientPath);
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
import { DebugProtocol } from 'vscode-debugprotocol';
|
||||
import { Protocol as Crdp } from 'devtools-protocol';
|
||||
import { ITelemetryPropertyCollector } from './telemetry';
|
||||
import { IStringDictionary } from './utils';
|
||||
|
||||
export type ISourceMapPathOverrides = { [pattern: string]: string };
|
||||
export type ISourceMapPathOverrides = IStringDictionary<string>;
|
||||
export type IPathMapping = IStringDictionary<string>;
|
||||
|
||||
export type BreakOnLoadStrategy = 'regex' | 'instrument' | 'off';
|
||||
|
||||
|
@ -19,10 +21,9 @@ export { ITelemetryPropertyCollector } from './telemetry';
|
|||
* Properties valid for both Launch and Attach
|
||||
*/
|
||||
export interface ICommonRequestArgs {
|
||||
webRoot?: string;
|
||||
remoteRoot?: string;
|
||||
localRoot?: string;
|
||||
pathMapping?: {[url: string]: string};
|
||||
pathMapping?: IPathMapping;
|
||||
outDir?: string;
|
||||
outFiles?: string[];
|
||||
sourceMaps?: boolean;
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as path from 'path';
|
|||
import * as sourceMapUtils from './sourceMapUtils';
|
||||
import * as utils from '../utils';
|
||||
import { logger } from 'vscode-debugadapter';
|
||||
import { ISourceMapPathOverrides } from '../debugAdapterInterfaces';
|
||||
import { IPathMapping } from '../debugAdapterInterfaces';
|
||||
|
||||
export type MappedPosition = MappedPosition;
|
||||
|
||||
|
@ -71,11 +71,10 @@ export class SourceMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* pathToGenerated - an absolute local path or a URL
|
||||
* json - sourcemap contents
|
||||
* webRoot - an absolute path
|
||||
* generatedPath: an absolute local path or a URL
|
||||
* json: sourcemap contents as string
|
||||
*/
|
||||
public constructor(generatedPath: string, json: string, webRoot?: string, sourceMapPathOverrides?: ISourceMapPathOverrides) {
|
||||
public constructor(generatedPath: string, json: string, pathMapping?: IPathMapping, sourceMapPathOverrides?: utils.IStringDictionary<string>) {
|
||||
this._generatedPath = generatedPath;
|
||||
|
||||
const sm = JSON.parse(json);
|
||||
|
@ -85,12 +84,12 @@ export class SourceMap {
|
|||
logger.log('Warning: if you are using gulp-sourcemaps < 2.0 directly or indirectly, you may need to set sourceRoot manually in your build config, if your files are not actually under a directory called /source');
|
||||
}
|
||||
logger.log(`SourceMap: sources: ${JSON.stringify(sm.sources)}`);
|
||||
if (webRoot) {
|
||||
logger.log(`SourceMap: webRoot: ${webRoot}`);
|
||||
if (pathMapping) {
|
||||
logger.log(`SourceMap: pathMapping: ${JSON.stringify(pathMapping)}`);
|
||||
}
|
||||
|
||||
// Absolute path
|
||||
const computedSourceRoot = sourceMapUtils.getComputedSourceRoot(sm.sourceRoot, this._generatedPath, webRoot);
|
||||
const computedSourceRoot = sourceMapUtils.getComputedSourceRoot(sm.sourceRoot, this._generatedPath, pathMapping);
|
||||
|
||||
// Overwrite the sourcemap's sourceRoot with the version that's resolved to an absolute path,
|
||||
// so the work above only has to be done once
|
||||
|
|
|
@ -11,11 +11,11 @@ import * as sourceMapUtils from './sourceMapUtils';
|
|||
import * as utils from '../utils';
|
||||
import { logger } from 'vscode-debugadapter';
|
||||
import { SourceMap } from './sourceMap';
|
||||
import { ISourceMapPathOverrides } from '../debugAdapterInterfaces';
|
||||
import { ISourceMapPathOverrides, IPathMapping } from '../debugAdapterInterfaces';
|
||||
|
||||
export class SourceMapFactory {
|
||||
constructor(
|
||||
private _webRoot?: string,
|
||||
private _pathMapping?: IPathMapping,
|
||||
private _sourceMapPathOverrides?: ISourceMapPathOverrides,
|
||||
private _enableSourceMapCaching?: boolean) {
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ export class SourceMapFactory {
|
|||
*/
|
||||
getMapForGeneratedPath(pathToGenerated: string, mapPath: string): Promise<SourceMap> {
|
||||
let msg = `SourceMaps.getMapForGeneratedPath: Finding SourceMap for ${pathToGenerated} by URI: ${mapPath}`;
|
||||
if (this._webRoot) {
|
||||
msg += ` and webRoot: ${this._webRoot}`;
|
||||
if (this._pathMapping) {
|
||||
msg += ` and webRoot/pathMapping: ${JSON.stringify(this._pathMapping)}`;
|
||||
}
|
||||
|
||||
logger.log(msg);
|
||||
|
@ -47,7 +47,7 @@ export class SourceMapFactory {
|
|||
if (contents) {
|
||||
try {
|
||||
// Throws for invalid JSON
|
||||
return new SourceMap(pathToGenerated, contents, this._webRoot, this._sourceMapPathOverrides);
|
||||
return new SourceMap(pathToGenerated, contents, this._pathMapping, this._sourceMapPathOverrides);
|
||||
} catch (e) {
|
||||
logger.error(`SourceMaps.getMapForGeneratedPath: exception while processing path: ${pathToGenerated}, sourcemap: ${mapPath}\n${e.stack}`);
|
||||
return null;
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
|
||||
import * as utils from '../utils';
|
||||
import { logger } from 'vscode-debugadapter';
|
||||
import { ISourceMapPathOverrides } from '../debugAdapterInterfaces';
|
||||
|
||||
import * as chromeUtils from '../chrome/chromeUtils';
|
||||
import * as utils from '../utils';
|
||||
import { ISourceMapPathOverrides, IPathMapping } from '../debugAdapterInterfaces';
|
||||
|
||||
/**
|
||||
* Resolves a relative path in terms of another file
|
||||
|
@ -17,9 +18,9 @@ export function resolveRelativeToFile(absPath: string, relPath: string): string
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine the absolute path to the sourceRoot.
|
||||
* Determine an absolute path for the sourceRoot.
|
||||
*/
|
||||
export function getComputedSourceRoot(sourceRoot: string, generatedPath: string, webRoot = ''): string {
|
||||
export function getComputedSourceRoot(sourceRoot: string, generatedPath: string, pathMapping: IPathMapping = {}): string {
|
||||
let absSourceRoot: string;
|
||||
if (sourceRoot) {
|
||||
if (sourceRoot.startsWith('file:///')) {
|
||||
|
@ -28,16 +29,16 @@ export function getComputedSourceRoot(sourceRoot: string, generatedPath: string,
|
|||
} else if (sourceRoot.startsWith('/')) {
|
||||
// sourceRoot is like "/src", would be like http://localhost/src, resolve to a local path under webRoot
|
||||
// note that C:/src (or /src as an absolute local path) is not a valid sourceroot
|
||||
absSourceRoot = path.join(webRoot, sourceRoot);
|
||||
} else {
|
||||
absSourceRoot = chromeUtils.targetUrlPathToClientPath(sourceRoot, pathMapping);
|
||||
} else if (path.isAbsolute(generatedPath)) {
|
||||
// sourceRoot is like "src" or "../src", relative to the script
|
||||
if (path.isAbsolute(generatedPath)) {
|
||||
absSourceRoot = resolveRelativeToFile(generatedPath, sourceRoot);
|
||||
} else {
|
||||
// generatedPath is a URL so runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
const genDirname = path.dirname(url.parse(generatedPath).pathname);
|
||||
absSourceRoot = path.join(webRoot, genDirname, sourceRoot);
|
||||
}
|
||||
absSourceRoot = resolveRelativeToFile(generatedPath, sourceRoot);
|
||||
} else {
|
||||
// generatedPath is a URL so runtime script is not on disk, resolve the sourceRoot location on disk.
|
||||
const generatedUrlPath = url.parse(generatedPath).pathname;
|
||||
const mappedPath = chromeUtils.targetUrlPathToClientPath(generatedUrlPath, pathMapping);
|
||||
const mappedDirname = path.dirname(mappedPath);
|
||||
absSourceRoot = path.join(mappedDirname, sourceRoot);
|
||||
}
|
||||
|
||||
logger.log(`SourceMap: resolved sourceRoot ${sourceRoot} -> ${absSourceRoot}`);
|
||||
|
@ -45,10 +46,11 @@ export function getComputedSourceRoot(sourceRoot: string, generatedPath: string,
|
|||
absSourceRoot = path.dirname(generatedPath);
|
||||
logger.log(`SourceMap: no sourceRoot specified, using script dirname: ${absSourceRoot}`);
|
||||
} else {
|
||||
// runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
const urlPath = url.parse(generatedPath).pathname;
|
||||
const scriptPathDirname = urlPath ? path.dirname(urlPath) : ''; // could be debugadapter://123, no other info.
|
||||
absSourceRoot = path.join(webRoot, scriptPathDirname);
|
||||
// No sourceRoot and runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
const urlPathname = url.parse(generatedPath).pathname || '/placeholder.js'; // could be debugadapter://123, no other info.
|
||||
const mappedPath = chromeUtils.targetUrlPathToClientPath(urlPathname, pathMapping);
|
||||
const scriptPathDirname = mappedPath ? path.dirname(mappedPath) : '';
|
||||
absSourceRoot = scriptPathDirname;
|
||||
logger.log(`SourceMap: no sourceRoot specified, using webRoot + script path dirname: ${absSourceRoot}`);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
import { SourceMap, MappedPosition, ISourcePathDetails } from './sourceMap';
|
||||
import { SourceMapFactory } from './sourceMapFactory';
|
||||
import { ISourceMapPathOverrides } from '../debugAdapterInterfaces';
|
||||
import { ISourceMapPathOverrides, IPathMapping } from '../debugAdapterInterfaces';
|
||||
|
||||
export class SourceMaps {
|
||||
// Maps absolute paths to generated/authored source files to their corresponding SourceMap object
|
||||
|
@ -13,8 +13,8 @@ export class SourceMaps {
|
|||
|
||||
private _sourceMapFactory: SourceMapFactory;
|
||||
|
||||
public constructor(webRoot?: string, sourceMapPathOverrides?: ISourceMapPathOverrides, enableSourceMapCaching?: boolean) {
|
||||
this._sourceMapFactory = new SourceMapFactory(webRoot, sourceMapPathOverrides, enableSourceMapCaching);
|
||||
public constructor(pathMapping?: IPathMapping, sourceMapPathOverrides?: ISourceMapPathOverrides, enableSourceMapCaching?: boolean) {
|
||||
this._sourceMapFactory = new SourceMapFactory(pathMapping, sourceMapPathOverrides, enableSourceMapCaching);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,7 +65,7 @@ export class BaseSourceMapTransformer {
|
|||
|
||||
protected init(args: ILaunchRequestArgs | IAttachRequestArgs): void {
|
||||
if (args.sourceMaps) {
|
||||
this._sourceMaps = new SourceMaps(args.webRoot, args.sourceMapPathOverrides, this._enableSourceMapCaching);
|
||||
this._sourceMaps = new SourceMaps(args.pathMapping, args.sourceMapPathOverrides, this._enableSourceMapCaching);
|
||||
this._requestSeqToSetBreakpointsArgs = new Map<number, ISavedSetBreakpointsArgs>();
|
||||
this._allRuntimeScriptPaths = new Set<string>();
|
||||
this._authoredPathsToMappedBPs = new Map<string, DebugProtocol.SourceBreakpoint[]>();
|
||||
|
|
|
@ -17,9 +17,9 @@ export class FallbackToClientPathTransformer extends UrlPathTransformer {
|
|||
super();
|
||||
}
|
||||
|
||||
protected async targetUrlToClientPath(webRoot: string, scriptUrl: string): Promise<string> {
|
||||
protected async targetUrlToClientPath(scriptUrl: string): Promise<string> {
|
||||
// First try the default UrlPathTransformer transformation
|
||||
return super.targetUrlToClientPath(webRoot, scriptUrl).then(filePath => {
|
||||
return super.targetUrlToClientPath(scriptUrl).then(filePath => {
|
||||
// If it returns a valid non empty file path then that should be a valid result, so we use that
|
||||
// If it's an eval script we won't be able to map it, so we also return that
|
||||
return (filePath || ChromeUtils.isEvalScript(scriptUrl))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
import { BasePathTransformer } from './basePathTransformer';
|
||||
|
||||
import { ISetBreakpointsArgs, ILaunchRequestArgs, IAttachRequestArgs, IStackTraceResponseBody } from '../debugAdapterInterfaces';
|
||||
import { ISetBreakpointsArgs, ILaunchRequestArgs, IAttachRequestArgs, IStackTraceResponseBody, IPathMapping } from '../debugAdapterInterfaces';
|
||||
import * as utils from '../utils';
|
||||
import { logger } from 'vscode-debugadapter';
|
||||
import { DebugProtocol } from 'vscode-debugprotocol';
|
||||
|
@ -16,20 +16,17 @@ import * as path from 'path';
|
|||
* Converts a local path from Code to a path on the target.
|
||||
*/
|
||||
export class UrlPathTransformer extends BasePathTransformer {
|
||||
private _webRoot: string;
|
||||
private _pathMapping: {[url: string]: string} = {};
|
||||
private _pathMapping: IPathMapping;
|
||||
private _clientPathToTargetUrl = new Map<string, string>();
|
||||
private _targetUrlToClientPath = new Map<string, string>();
|
||||
|
||||
public launch(args: ILaunchRequestArgs): Promise<void> {
|
||||
this._webRoot = args.webRoot;
|
||||
this._pathMapping = args.pathMapping || {};
|
||||
this._pathMapping = args.pathMapping;
|
||||
return super.launch(args);
|
||||
}
|
||||
|
||||
public attach(args: IAttachRequestArgs): Promise<void> {
|
||||
this._webRoot = args.webRoot;
|
||||
this._pathMapping = args.pathMapping || {};
|
||||
this._pathMapping = args.pathMapping;
|
||||
return super.attach(args);
|
||||
}
|
||||
|
||||
|
@ -64,19 +61,15 @@ export class UrlPathTransformer extends BasePathTransformer {
|
|||
}
|
||||
|
||||
public async scriptParsed(scriptUrl: string): Promise<string> {
|
||||
let clientPath = ChromeUtils.targetUrlToClientPathByPathMappings(scriptUrl, this._pathMapping);
|
||||
|
||||
if (!clientPath) {
|
||||
clientPath = await this.targetUrlToClientPath(this._webRoot, scriptUrl);
|
||||
}
|
||||
const clientPath = await this.targetUrlToClientPath(scriptUrl);
|
||||
|
||||
if (!clientPath) {
|
||||
// It's expected that eval scripts (eval://) won't be resolved
|
||||
if (!scriptUrl.startsWith(ChromeUtils.EVAL_NAME_PREFIX)) {
|
||||
logger.log(`Paths.scriptParsed: could not resolve ${scriptUrl} to a file under webRoot: ${this._webRoot}. It may be external or served directly from the server's memory (and that's OK).`);
|
||||
logger.log(`Paths.scriptParsed: could not resolve ${scriptUrl} to a file with pathMapping/webRoot: ${JSON.stringify(this._pathMapping)}. It may be external or served directly from the server's memory (and that's OK).`);
|
||||
}
|
||||
} else {
|
||||
logger.log(`Paths.scriptParsed: resolved ${scriptUrl} to ${clientPath}. webRoot: ${this._webRoot}`);
|
||||
logger.log(`Paths.scriptParsed: resolved ${scriptUrl} to ${clientPath}. pathMapping/webroot: ${JSON.stringify(this._pathMapping)}`);
|
||||
const canonicalizedClientPath = utils.canonicalizeUrl(clientPath);
|
||||
this._clientPathToTargetUrl.set(canonicalizedClientPath, scriptUrl);
|
||||
this._targetUrlToClientPath.set(scriptUrl, clientPath);
|
||||
|
@ -96,7 +89,7 @@ export class UrlPathTransformer extends BasePathTransformer {
|
|||
// Try to resolve the url to a path in the workspace. If it's not in the workspace,
|
||||
// just use the script.url as-is. It will be resolved or cleared by the SourceMapTransformer.
|
||||
const clientPath = this.getClientPathFromTargetPath(source.path) ||
|
||||
await this.targetUrlToClientPath(this._webRoot, source.path);
|
||||
await this.targetUrlToClientPath(source.path);
|
||||
|
||||
// Incoming stackFrames have sourceReference and path set. If the path was resolved to a file in the workspace,
|
||||
// clear the sourceReference since it's not needed.
|
||||
|
@ -120,7 +113,10 @@ export class UrlPathTransformer extends BasePathTransformer {
|
|||
return this._targetUrlToClientPath.get(targetPath);
|
||||
}
|
||||
|
||||
protected async targetUrlToClientPath(webRoot: string, scriptUrl: string): Promise<string> {
|
||||
return Promise.resolve(ChromeUtils.targetUrlToClientPath(this._webRoot, scriptUrl));
|
||||
/**
|
||||
* Overridable for VS to ask Client to resolve path
|
||||
*/
|
||||
protected async targetUrlToClientPath(scriptUrl: string): Promise<string> {
|
||||
return Promise.resolve(ChromeUtils.targetUrlToClientPath2(scriptUrl, this._pathMapping));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ import * as https from 'https';
|
|||
|
||||
import { IExecutionResultTelemetryProperties } from './telemetry';
|
||||
|
||||
export interface IStringDictionary<T> {
|
||||
[name: string]: T;
|
||||
}
|
||||
|
||||
export const enum Platform {
|
||||
Windows, OSX, Linux
|
||||
}
|
||||
|
|
|
@ -44,17 +44,18 @@ suite('ChromeUtils', () => {
|
|||
const TEST_TARGET_LOCAL_URL = 'file:///' + TEST_CLIENT_PATH;
|
||||
const TEST_TARGET_HTTP_URL = 'http://site.com/page/scripts/a.js';
|
||||
const TEST_WEB_ROOT = 'c:\\site';
|
||||
const PATH_MAPPING = { '/': TEST_WEB_ROOT };
|
||||
|
||||
test('an empty string is returned for a missing url', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('', ''), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2('', PATH_MAPPING), '');
|
||||
});
|
||||
|
||||
test('an empty string is returned when the webRoot is missing', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(null, TEST_TARGET_HTTP_URL), '');
|
||||
test('an empty string is returned when the pathMapping is missing', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2(TEST_TARGET_HTTP_URL, null), '');
|
||||
});
|
||||
|
||||
test('a url without a path returns an empty string', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_WEB_ROOT, 'http://site.com'), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2('http://site.com', PATH_MAPPING), '');
|
||||
});
|
||||
|
||||
test('it searches the disk for a path that exists, built from the url', () => {
|
||||
|
@ -62,7 +63,7 @@ suite('ChromeUtils', () => {
|
|||
if (aPath !== TEST_CLIENT_PATH) throw new Error('Not found');
|
||||
};
|
||||
mockery.registerMock('fs', { statSync });
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_WEB_ROOT, TEST_TARGET_HTTP_URL), TEST_CLIENT_PATH);
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2(TEST_TARGET_HTTP_URL, PATH_MAPPING), TEST_CLIENT_PATH);
|
||||
});
|
||||
|
||||
test(`returns an empty string when it can't resolve a url`, () => {
|
||||
|
@ -70,23 +71,23 @@ suite('ChromeUtils', () => {
|
|||
throw new Error('Not found');
|
||||
};
|
||||
mockery.registerMock('fs', { statSync });
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_WEB_ROOT, TEST_TARGET_HTTP_URL), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2(TEST_TARGET_HTTP_URL, PATH_MAPPING), '');
|
||||
});
|
||||
|
||||
test('file:/// urls are returned canonicalized', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('', TEST_TARGET_LOCAL_URL), TEST_CLIENT_PATH);
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2(TEST_TARGET_LOCAL_URL, PATH_MAPPING), TEST_CLIENT_PATH);
|
||||
});
|
||||
|
||||
test('uri encodings are fixed for file:/// paths', () => {
|
||||
const clientPath = 'c:\\project\\path with spaces\\script.js';
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_WEB_ROOT, 'file:///' + encodeURI(clientPath)), clientPath);
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2('file:///' + encodeURI(clientPath), PATH_MAPPING), clientPath);
|
||||
});
|
||||
|
||||
test('uri encodings are fixed in URLs', () => {
|
||||
const pathSegment = 'path with spaces\\script.js';
|
||||
const url = 'http:\\' + encodeURIComponent(pathSegment);
|
||||
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_WEB_ROOT, url), path.join(TEST_WEB_ROOT, pathSegment));
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath2(url, PATH_MAPPING), path.join(TEST_WEB_ROOT, pathSegment));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -97,28 +98,27 @@ suite('ChromeUtils', () => {
|
|||
|
||||
const ROOT_MAPPING = { '/': TEST_WEB_ROOT };
|
||||
const PAGE_MAPPING = { '/page/': TEST_WEB_ROOT };
|
||||
const PARTIAL_PAGE_MAPPING = { '/page': TEST_WEB_ROOT, 'page': TEST_WEB_ROOT};
|
||||
const PARTIAL_PAGE_MAPPING = { '/page': TEST_WEB_ROOT };
|
||||
const FILE_MAPPING = { '/page.js': TEST_CLIENT_PATH };
|
||||
const RELATIVE_FILE_MAPPING = { 'page.js': TEST_CLIENT_PATH};
|
||||
|
||||
test('an empty string is returned for a missing url', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings('', { }), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('', { }), '');
|
||||
});
|
||||
|
||||
test('an empty string is returned for file: URLs', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings('file:///Users/foo/bar.js', { }), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('file:///Users/foo/bar.js', { }), '');
|
||||
});
|
||||
|
||||
test('an empty string is returned for non-URLs', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings('foo.js', { }), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('foo.js', { }), '');
|
||||
});
|
||||
|
||||
test('a url without a path returns an empty string', () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings('http://site.com', { }), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath('http://site.com', { }), '');
|
||||
});
|
||||
|
||||
test(`returns an empty string when it can't resolve a url`, () => {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(TEST_TARGET_HTTP_URL, { '/foo': '/bar' }), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(TEST_TARGET_HTTP_URL, { '/foo': '/bar' }), '');
|
||||
});
|
||||
|
||||
test('decodes uri-encoded characters', () => {
|
||||
|
@ -127,7 +127,7 @@ suite('ChromeUtils', () => {
|
|||
const url = 'http://localhost/' + escapedSegment + '/script.js';
|
||||
|
||||
assert.equal(
|
||||
getChromeUtils().targetUrlToClientPathByPathMappings(url, ROOT_MAPPING),
|
||||
getChromeUtils().targetUrlToClientPath(url, ROOT_MAPPING),
|
||||
path.join(TEST_WEB_ROOT, segmentWithSpaces, 'script.js'));
|
||||
});
|
||||
|
||||
|
@ -137,50 +137,44 @@ suite('ChromeUtils', () => {
|
|||
const url = 'http://localhost/' + escapedSegment + '/script.js';
|
||||
|
||||
assert.equal(
|
||||
getChromeUtils().targetUrlToClientPathByPathMappings(url, { '/path%20with%20spaces/': TEST_WEB_ROOT }),
|
||||
getChromeUtils().targetUrlToClientPath(url, { '/path%20with%20spaces/': TEST_WEB_ROOT }),
|
||||
path.join(TEST_WEB_ROOT, 'script.js'));
|
||||
});
|
||||
|
||||
test('resolves webroot-style mapping', () => {
|
||||
assert.equal(
|
||||
getChromeUtils().targetUrlToClientPathByPathMappings(TEST_TARGET_HTTP_URL, PAGE_MAPPING),
|
||||
getChromeUtils().targetUrlToClientPath(TEST_TARGET_HTTP_URL, PAGE_MAPPING),
|
||||
TEST_CLIENT_PATH);
|
||||
});
|
||||
|
||||
test('resolves webroot-style mapping without trailing slash', () => {
|
||||
assert.equal(
|
||||
getChromeUtils().targetUrlToClientPathByPathMappings(TEST_TARGET_HTTP_URL, PARTIAL_PAGE_MAPPING),
|
||||
getChromeUtils().targetUrlToClientPath(TEST_TARGET_HTTP_URL, PARTIAL_PAGE_MAPPING),
|
||||
TEST_CLIENT_PATH);
|
||||
});
|
||||
|
||||
test('resolves pathMapping for a particular file', () => {
|
||||
assert.equal(
|
||||
getChromeUtils().targetUrlToClientPathByPathMappings('http://site.com/page.js', FILE_MAPPING),
|
||||
getChromeUtils().targetUrlToClientPath('http://site.com/page.js', FILE_MAPPING),
|
||||
TEST_CLIENT_PATH);
|
||||
});
|
||||
|
||||
test('return an empty string for url that has partially matching directory', () => {
|
||||
const url = 'http://site.com/page-alike/scripts/a.js';
|
||||
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, PARTIAL_PAGE_MAPPING), '');
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(url, PARTIAL_PAGE_MAPPING), '');
|
||||
});
|
||||
|
||||
test('return an empty string for file matching pathMapped directory', () => {
|
||||
const url = 'http://site.com/page.js';
|
||||
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, PARTIAL_PAGE_MAPPING), '');
|
||||
});
|
||||
|
||||
test('resolves pathMapping for a particular relative file', () => {
|
||||
const url = 'http://site.com/page.js';
|
||||
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, RELATIVE_FILE_MAPPING), TEST_CLIENT_PATH);
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(url, PARTIAL_PAGE_MAPPING), '');
|
||||
});
|
||||
|
||||
test('matches longer patterns first', () => {
|
||||
const url = 'http://localhost/foo/bar';
|
||||
|
||||
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, {
|
||||
assert.equal(getChromeUtils().targetUrlToClientPath(url, {
|
||||
'/': 'C:\\a',
|
||||
'foo': 'C:\\b'
|
||||
}), 'C:\\b\\bar');
|
||||
|
|
|
@ -18,6 +18,7 @@ import { ISourceMapPathOverrides } from '../../src/debugAdapterInterfaces';
|
|||
suite('SourceMap', () => {
|
||||
const GENERATED_PATH = testUtils.pathResolve('/project/src/app.js');
|
||||
const WEBROOT = testUtils.pathResolve('/project');
|
||||
const PATH_MAPPING = { '/': WEBROOT };
|
||||
const SOURCEROOT = '/src/';
|
||||
|
||||
const SOURCES = [
|
||||
|
@ -47,7 +48,7 @@ suite('SourceMap', () => {
|
|||
test('does not crash when sourceRoot is undefined', () => {
|
||||
// Rare and possibly invalid, but I saw it
|
||||
const sourceMapJSON = getMockSourceMapJSON(SOURCES, undefined);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert(sm);
|
||||
});
|
||||
});
|
||||
|
@ -56,14 +57,14 @@ suite('SourceMap', () => {
|
|||
test('relative sources are made absolute', () => {
|
||||
const sourceMapJSON = getMockSourceMapJSON(SOURCES, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert.deepEqual(sm.authoredSources, ABSOLUTE_SOURCES);
|
||||
});
|
||||
|
||||
test('sources with absolute paths are used as-is', () => {
|
||||
const sourceMapJSON = getMockSourceMapJSON(ABSOLUTE_SOURCES, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert.deepEqual(sm.authoredSources, ABSOLUTE_SOURCES);
|
||||
});
|
||||
|
||||
|
@ -71,14 +72,14 @@ suite('SourceMap', () => {
|
|||
const fileSources = ABSOLUTE_SOURCES.map(source => 'file:///' + source);
|
||||
const sourceMapJSON = getMockSourceMapJSON(fileSources, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert.deepEqual(sm.authoredSources, ABSOLUTE_SOURCES);
|
||||
});
|
||||
|
||||
test('sourceMapPathOverrides are respected', () => {
|
||||
const sourceMapJSON = getMockSourceMapJSON(SOURCES, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT, <ISourceMapPathOverrides>{ '/src/*': testUtils.pathResolve('/project/client/*') });
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING, <ISourceMapPathOverrides>{ '/src/*': testUtils.pathResolve('/project/client/*') });
|
||||
const expectedSources = SOURCES.map(sourcePath => path.join(testUtils.pathResolve('/project/client'), sourcePath));
|
||||
assert.deepEqual(sm.authoredSources, expectedSources);
|
||||
});
|
||||
|
@ -88,14 +89,14 @@ suite('SourceMap', () => {
|
|||
test('returns true for a source that it contains', () => {
|
||||
const sourceMapJSON = getMockSourceMapJSON(ABSOLUTE_SOURCES, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert(sm.doesOriginateFrom(ABSOLUTE_SOURCES[0]));
|
||||
});
|
||||
|
||||
test('returns false for a source that it does not contain', () => {
|
||||
const sourceMapJSON = getMockSourceMapJSON(ABSOLUTE_SOURCES, SOURCEROOT);
|
||||
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, WEBROOT);
|
||||
const sm = new SourceMap(GENERATED_PATH, sourceMapJSON, PATH_MAPPING);
|
||||
assert(!sm.doesOriginateFrom('c:\\fake\\file.js'));
|
||||
});
|
||||
});
|
||||
|
@ -104,7 +105,7 @@ suite('SourceMap', () => {
|
|||
let sm: SourceMap;
|
||||
|
||||
setup(() => {
|
||||
sm = new SourceMap(GENERATED_PATH, SOURCEMAP_MAPPINGS_JSON, WEBROOT);
|
||||
sm = new SourceMap(GENERATED_PATH, SOURCEMAP_MAPPINGS_JSON, PATH_MAPPING);
|
||||
});
|
||||
|
||||
function getExpectedResult(line: number, column: number, source = ABSOLUTE_SOURCES[0]): MozSourceMap.MappedPosition {
|
||||
|
@ -203,7 +204,7 @@ suite('SourceMap', () => {
|
|||
let sm: SourceMap;
|
||||
|
||||
setup(() => {
|
||||
sm = new SourceMap(GENERATED_PATH, SOURCEMAP_MAPPINGS_JSON, WEBROOT);
|
||||
sm = new SourceMap(GENERATED_PATH, SOURCEMAP_MAPPINGS_JSON, PATH_MAPPING);
|
||||
});
|
||||
|
||||
function getExpectedResult(line: number, column: number): MozSourceMap.Position {
|
||||
|
|
|
@ -30,52 +30,53 @@ suite('SourceMapUtils', () => {
|
|||
const GEN_URL = 'http://localhost:8080/code/script.js';
|
||||
const ABS_SOURCEROOT = testUtils.pathResolve('/project/src');
|
||||
const WEBROOT = testUtils.pathResolve('/project/webroot');
|
||||
const PATH_MAPPING = { '/': WEBROOT };
|
||||
|
||||
test('handles file:/// sourceRoot', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('file:///' + ABS_SOURCEROOT, GEN_PATH, WEBROOT),
|
||||
getComputedSourceRoot('file:///' + ABS_SOURCEROOT, GEN_PATH, PATH_MAPPING),
|
||||
ABS_SOURCEROOT);
|
||||
});
|
||||
|
||||
test('handles /src style sourceRoot', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('/src', GEN_PATH, WEBROOT),
|
||||
getComputedSourceRoot('/src', GEN_PATH, PATH_MAPPING),
|
||||
testUtils.pathResolve('/project/webroot/src'));
|
||||
});
|
||||
|
||||
test('handles ../../src style sourceRoot', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('../../src', GEN_PATH, WEBROOT),
|
||||
getComputedSourceRoot('../../src', GEN_PATH, PATH_MAPPING),
|
||||
ABS_SOURCEROOT);
|
||||
});
|
||||
|
||||
test('handles src style sourceRoot', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('src', GEN_PATH, WEBROOT),
|
||||
getComputedSourceRoot('src', GEN_PATH, PATH_MAPPING),
|
||||
testUtils.pathResolve('/project/webroot/code/src'));
|
||||
});
|
||||
|
||||
test('handles runtime script not on disk', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('../src', GEN_URL, WEBROOT),
|
||||
getComputedSourceRoot('../src', GEN_URL, PATH_MAPPING),
|
||||
testUtils.pathResolve('/project/webroot/src'));
|
||||
});
|
||||
|
||||
test('when no sourceRoot specified and runtime script is on disk, uses the runtime script dirname', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('', GEN_PATH, WEBROOT),
|
||||
getComputedSourceRoot('', GEN_PATH, PATH_MAPPING),
|
||||
testUtils.pathResolve('/project/webroot/code'));
|
||||
});
|
||||
|
||||
test('when no sourceRoot specified and runtime script is not on disk, uses the runtime script dirname', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('', GEN_URL, WEBROOT),
|
||||
getComputedSourceRoot('', GEN_URL, PATH_MAPPING),
|
||||
testUtils.pathResolve('/project/webroot/code'));
|
||||
});
|
||||
|
||||
test('no crash on debugadapter:// urls', () => {
|
||||
assert.equal(
|
||||
getComputedSourceRoot('', 'eval://123', WEBROOT),
|
||||
getComputedSourceRoot('', 'eval://123', PATH_MAPPING),
|
||||
testUtils.pathResolve(WEBROOT));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,8 +18,9 @@ suite('SourceMaps', () => {
|
|||
const AUTHORED_PATH = path.resolve(DIRNAME, 'testData/source1.ts');
|
||||
const ALL_SOURCES = [AUTHORED_PATH, path.resolve(DIRNAME, 'testData/source2.ts')];
|
||||
const WEBROOT = 'http://localhost';
|
||||
const PATH_MAPPING = { '/': WEBROOT };
|
||||
const SOURCEMAP_URL = 'app.js.map';
|
||||
const sourceMaps = new SourceMaps(WEBROOT);
|
||||
const sourceMaps = new SourceMaps(PATH_MAPPING);
|
||||
|
||||
setup((done) => {
|
||||
testUtils.setupUnhandledRejectionListener();
|
||||
|
|
|
@ -9,10 +9,6 @@ import * as testUtils from '../testUtils';
|
|||
import {UrlPathTransformer as _UrlPathTransformer } from '../../src/transformers/urlPathTransformer';
|
||||
import * as chromeUtils from '../../src/chrome/chromeUtils';
|
||||
|
||||
// As of 0.1.0, the included .d.ts is not in the right format to use the import syntax here
|
||||
// https://github.com/florinn/typemoq/issues/4
|
||||
// const typemoq: ITypeMoqStatic = require('typemoq');
|
||||
|
||||
import { Mock, MockBehavior, It, IMock, Times } from 'typemoq';
|
||||
|
||||
const MODULE_UNDER_TEST = '../../src/transformers/urlPathTransformer';
|
||||
|
@ -56,11 +52,7 @@ suite('UrlPathTransformer', () => {
|
|||
|
||||
test('resolves correctly when it can map the client script to the target script', async () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPathByPathMappings(It.isValue(TARGET_URL), It.isAny()))
|
||||
.returns(() => '').verifiable();
|
||||
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPath(It.isValue(undefined), It.isValue(TARGET_URL)))
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL), It.isValue(undefined)))
|
||||
.returns(() => CLIENT_PATH).verifiable();
|
||||
|
||||
await transformer.scriptParsed(TARGET_URL);
|
||||
|
@ -84,11 +76,7 @@ suite('UrlPathTransformer', () => {
|
|||
suite('scriptParsed', () => {
|
||||
test('returns the client path when the file can be mapped', async () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPathByPathMappings(It.isValue(TARGET_URL), It.isAny()))
|
||||
.returns(() => '').verifiable();
|
||||
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPath(It.isValue(undefined), It.isValue(TARGET_URL)))
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL), It.isValue(undefined)))
|
||||
.returns(() => CLIENT_PATH).verifiable();
|
||||
|
||||
assert.equal(await transformer.scriptParsed(TARGET_URL), CLIENT_PATH);
|
||||
|
@ -96,11 +84,7 @@ suite('UrlPathTransformer', () => {
|
|||
|
||||
test(`returns the given path when the file can't be mapped`, async () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPathByPathMappings(It.isValue(TARGET_URL), It.isAny()))
|
||||
.returns(() => '').verifiable();
|
||||
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPath(It.isValue(undefined), It.isValue(TARGET_URL)))
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL), It.isValue(undefined)))
|
||||
.returns(() => '').verifiable();
|
||||
|
||||
chromeUtilsMock
|
||||
|
@ -112,7 +96,7 @@ suite('UrlPathTransformer', () => {
|
|||
|
||||
test('ok with uncanonicalized paths', async () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPathByPathMappings(It.isValue(TARGET_URL + '?queryparam'), It.isAny()))
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL + '?queryparam'), It.isValue(undefined)))
|
||||
.returns(() => CLIENT_PATH).verifiable();
|
||||
|
||||
assert.equal(await transformer.scriptParsed(TARGET_URL + '?queryparam'), CLIENT_PATH);
|
||||
|
@ -130,9 +114,8 @@ suite('UrlPathTransformer', () => {
|
|||
|
||||
test('modifies the source path and clears sourceReference when the file can be mapped', async () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPath(It.isValue(undefined), It.isValue(TARGET_URL)))
|
||||
.returns(() => CLIENT_PATH)
|
||||
.verifiable(Times.atLeastOnce());
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL), It.isValue(undefined)))
|
||||
.returns(() => CLIENT_PATH).verifiable(Times.atLeastOnce());
|
||||
|
||||
const response = testUtils.getStackTraceResponseBody(TARGET_URL, RUNTIME_LOCATIONS, [1, 2, 3]);
|
||||
const expectedResponse = testUtils.getStackTraceResponseBody(CLIENT_PATH, RUNTIME_LOCATIONS);
|
||||
|
@ -143,9 +126,8 @@ suite('UrlPathTransformer', () => {
|
|||
|
||||
test(`doesn't modify the source path or clear the sourceReference when the file can't be mapped`, () => {
|
||||
chromeUtilsMock
|
||||
.setup(x => x.targetUrlToClientPath(It.isValue(undefined), It.isValue(TARGET_URL)))
|
||||
.returns(() => '')
|
||||
.verifiable(Times.atLeastOnce());
|
||||
.setup(x => x.targetUrlToClientPath2(It.isValue(TARGET_URL), It.isValue(undefined)))
|
||||
.returns(() => '').verifiable(Times.atLeastOnce());
|
||||
|
||||
const response = testUtils.getStackTraceResponseBody(TARGET_URL, RUNTIME_LOCATIONS, [1, 2, 3]);
|
||||
const expectedResponse = testUtils.getStackTraceResponseBody(TARGET_URL, RUNTIME_LOCATIONS, [1, 2, 3]);
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
"no-var-requires": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
false,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
|
|
Загрузка…
Ссылка в новой задаче