In an effort to reduce the need to keep source maps in memory for consumers of the sourcemapdeminifier that only care about deminified method names, we'll compute the deminified method names during the function map generation process.

This commit is contained in:
Christian Gonzalez 2016-11-15 15:47:51 -08:00
Родитель 91ca5a2c12
Коммит 411d1a54ab
8 изменённых файлов: 260 добавлений и 239 удалений

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

@ -30,7 +30,9 @@ namespace SourcemapToolkit.CallstackDeminifier
/// To get the complete name of the function associated with this mapping entry
/// append the names of each bindings with a "."
/// </summary>
public List<BindingInformation> Bindings { get; set; }
public List<BindingInformation> Bindings { get; set; }
public string DeminfifiedMethodName { get; set; }
/// <summary>
/// Denotes the location of the beginning of this function

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

@ -1,16 +1,40 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Ajax.Utilities;
using SourcemapToolkit.SourcemapParser;
namespace SourcemapToolkit.CallstackDeminifier
{
internal class FunctionMapGenerator : IFunctionMapGenerator
{
/// <summary>
/// Returns a FunctionMap describing the locations of every funciton in the source code.
/// The functions are to be sorted descending by start position.
/// </summary>
public List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader)
/// <summary>
/// Returns a FunctionMap describing the locations of every funciton in the source code.
/// The functions are to be sorted descending by start position.
/// </summary>
public List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader, StreamReader sourceMapStreamReader)
{
if (sourceCodeStreamReader == null || sourceMapStreamReader == null)
{
return null;
}
List<FunctionMapEntry> result = ParseSourceCode(sourceMapStreamReader);
SourceMapParser sourceMapParser = new SourceMapParser();
SourceMap sourceMap = sourceMapParser.ParseSourceMap(sourceMapStreamReader);
foreach (FunctionMapEntry functionMapEntry in result)
{
functionMapEntry.DeminfifiedMethodName = GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
}
return result;
}
/// <summary>
/// Iterates over all the code in the JavaScript file to get a list of all the functions declared in that file.
/// </summary>
internal List<FunctionMapEntry> ParseSourceCode(StreamReader sourceCodeStreamReader)
{
if (sourceCodeStreamReader == null)
{
@ -32,7 +56,43 @@ namespace SourcemapToolkit.CallstackDeminifier
// Sort in descending order by start position
functionFinderVisitor.FunctionMap.Sort((x, y) => y.StartSourcePosition.CompareTo(x.StartSourcePosition));
return functionFinderVisitor.FunctionMap;
return functionFinderVisitor.FunctionMap;
}
internal static string GetDeminifiedMethodNameFromSourceMap(FunctionMapEntry wrappingFunction, SourceMap sourceMap)
{
string methodName = null;
if (wrappingFunction?.Bindings != null && wrappingFunction.Bindings.Count > 0)
{
if (wrappingFunction.Bindings.Count == 2)
{
MappingEntry objectProtoypeMappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings[0].SourcePosition);
methodName = objectProtoypeMappingEntry?.OriginalName;
}
MappingEntry mappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings.Last().SourcePosition);
if (mappingEntry != null)
{
if (mappingEntry.OriginalName != null)
{
if (methodName != null)
{
methodName = methodName + "." + mappingEntry.OriginalName;
}
else
{
methodName = mappingEntry.OriginalName;
}
}
}
}
return methodName;
}
}
}

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

@ -7,16 +7,15 @@ namespace SourcemapToolkit.CallstackDeminifier
/// </summary>
internal class FunctionMapStore : IFunctionMapStore
{
private readonly ISourceCodeProvider _sourceCodeProvider;
private readonly IFunctionMapGenerator _functionMapGenerator;
private readonly KeyValueCache<string,List<FunctionMapEntry>> _functionMapCache;
public FunctionMapStore(ISourceCodeProvider sourceCodeProvider)
public FunctionMapStore(ISourceCodeProvider sourceCodeProvider, ISourceMapProvider sourceMapProvider)
{
_sourceCodeProvider = sourceCodeProvider;
_functionMapGenerator = new FunctionMapGenerator();
_functionMapCache = new KeyValueCache<string, List<FunctionMapEntry>>(sourceCodeUrl => _functionMapGenerator.GenerateFunctionMap(
_sourceCodeProvider.GetSourceCode(sourceCodeUrl)));
sourceCodeProvider.GetSourceCode(sourceCodeUrl),
sourceMapProvider.GetSourceMapContentsForCallstackUrl(sourceCodeUrl)));
}
/// <summary>

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

@ -9,6 +9,6 @@ namespace SourcemapToolkit.CallstackDeminifier
/// Returns a FunctionMap describing the locations of every funciton in the source code.
/// The functions are to be sorted in decreasing order by start position.
/// </summary>
List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader);
List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader, StreamReader sourceMapStreamReader);
}
}

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

@ -59,37 +59,7 @@ namespace SourcemapToolkit.CallstackDeminifier
{
StackFrame result = new StackFrame();
if (wrappingFunction?.Bindings != null && wrappingFunction.Bindings.Count > 0)
{
string methodName = null;
if (wrappingFunction.Bindings.Count == 2)
{
MappingEntry objectProtoypeMappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings[0].SourcePosition);
methodName = objectProtoypeMappingEntry?.OriginalName;
}
MappingEntry mappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings.Last().SourcePosition);
if (mappingEntry != null)
{
if (mappingEntry.OriginalName != null)
{
if (methodName != null)
{
methodName = methodName + "." + mappingEntry.OriginalName;
}
else
{
methodName = mappingEntry.OriginalName;
}
}
result.MethodName = methodName;
}
}
result.MethodName = wrappingFunction.DeminfifiedMethodName;
MappingEntry generatedSourcePositionMappingEntry = sourceMap?.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition);
result.FilePath = generatedSourcePositionMappingEntry?.OriginalFileName;
result.SourcePosition = generatedSourcePositionMappingEntry?.OriginalSourcePosition;

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

@ -20,7 +20,7 @@ namespace SourcemapToolkit.CallstackDeminifier
/// <param name="generatedCodeProvider">Consumers of the API should implement this interface, which provides the contents of a JavaScript file. Throws ArgumentNullException if the parameter is set to null.</param>
public StackTraceDeminifier(ISourceMapProvider sourceMapProvider, ISourceCodeProvider generatedCodeProvider)
: this(new StackFrameDeminifier(new SourceMapStore(sourceMapProvider),
new FunctionMapStore(generatedCodeProvider), new FunctionMapConsumer()), new StackTraceParser())
new FunctionMapStore(generatedCodeProvider, sourceMapProvider), new FunctionMapConsumer()), new StackTraceParser())
{
if (sourceMapProvider == null)
{

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

@ -1,49 +1,67 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SourcemapToolkit.SourcemapParser.UnitTests;
using Rhino.Mocks;
using SourcemapToolkit.SourcemapParser;
namespace SourcemapToolkit.CallstackDeminifier.UnitTests
{
[TestClass]
public class FunctionMapGeneratorUnitTests
{
[TestMethod]
public void GenerateFunctionMap_NullInput_ReturnsNull()
[TestMethod]
public void GenerateFunctionMap_NullSourceMap_ReturnsNull()
{
// Arrange
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode), null);
// Assert
Assert.IsNull(functionMap);
}
[TestMethod]
public void ParseSourceCode_NullInput_ReturnsNull()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(null);
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(null);
// Assert
Assert.IsNull(functionMap);
}
[TestMethod]
public void GenerateFunctionMap_NoFunctionsInSource_EmptyFunctionList()
public void ParseSourceCode_NoFunctionsInSource_EmptyFunctionList()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "bar();";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(0, functionMap.Count);
}
[TestMethod]
public void GenerateFunctionMap_SingleLineFunctionInSource_CorrectZeroBasedColumnNumbers()
public void ParseSourceCode_SingleLineFunctionInSource_CorrectZeroBasedColumnNumbers()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "function foo(){bar();}";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(1, functionMap.Count);
@ -57,15 +75,15 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_MultiLineFunctionInSource_CorrectColumnAndZeroBasedLineNumbers()
public void ParseSourceCode_MultiLineFunctionInSource_CorrectColumnAndZeroBasedLineNumbers()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "function foo()" + Environment.NewLine + "{" + Environment.NewLine + "bar();" +
Environment.NewLine + "}";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(1, functionMap.Count);
@ -79,14 +97,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_TwoSingleLineFunctions_TwoFunctionMapEntries()
public void ParseSourceCode_TwoSingleLineFunctions_TwoFunctionMapEntries()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "function foo(){bar();}function bar(){baz();}";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -109,14 +127,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_TwoNestedSingleLineFunctions_TwoFunctionMapEntries()
public void ParseSourceCode_TwoNestedSingleLineFunctions_TwoFunctionMapEntries()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "function foo(){function bar(){baz();}}";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -139,14 +157,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_FunctionAssignedToVariable_FunctionMapEntryGenerated()
public void ParseSourceCode_FunctionAssignedToVariable_FunctionMapEntryGenerated()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){bar();}";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(1, functionMap.Count);
@ -161,14 +179,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_StaticMethod_FunctionMapEntryGenerated()
public void ParseSourceCode_StaticMethod_FunctionMapEntryGenerated()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){};foo.bar = function() { baz(); }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -191,14 +209,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_InstanceMethod_FunctionMapEntryGenerated()
public void ParseSourceCode_InstanceMethod_FunctionMapEntryGenerated()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){} foo.prototype.bar = function () { baz(); }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -221,14 +239,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_InstanceMethodInObjectInitializer_FunctionMapEntryGenerated()
public void ParseSourceCode_InstanceMethodInObjectInitializer_FunctionMapEntryGenerated()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){} foo.prototype = { bar: function () { baz(); } }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -254,14 +272,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_FunctionAssignedToVariableAndHasName_FunctionMapEntryGeneratedForVariableName()
public void ParseSourceCode_FunctionAssignedToVariableAndHasName_FunctionMapEntryGeneratedForVariableName()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function myCoolFunctionName(){ bar(); }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(1, functionMap.Count);
@ -276,14 +294,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_StaticMethodAndFunctionHasName_FunctionMapEntryGeneratedForPropertyName()
public void ParseSourceCode_StaticMethodAndFunctionHasName_FunctionMapEntryGeneratedForPropertyName()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){};foo.bar = function myCoolFunctionName() { baz(); }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -306,14 +324,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_InstanceMethodAndFunctionHasName_FunctionMapEntryGeneratedForObjectPrototype()
public void ParseSourceCode_InstanceMethodAndFunctionHasName_FunctionMapEntryGeneratedForObjectPrototype()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){} foo.prototype.bar = function myCoolFunctionName() { baz(); } }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -336,14 +354,14 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
}
[TestMethod]
public void GenerateFunctionMap_InstanceMethodWithObjectInitializerAndFunctionHasName_FunctionMapEntryGeneratedForObjectPrototype()
public void ParseSourceCode_InstanceMethodWithObjectInitializerAndFunctionHasName_FunctionMapEntryGeneratedForObjectPrototype()
{
// Arrange
IFunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
FunctionMapGenerator functionMapGenerator = new FunctionMapGenerator();
string sourceCode = "var foo = function(){} foo.prototype = { bar: function myCoolFunctionName() { baz(); } }";
// Act
List<FunctionMapEntry> functionMap = functionMapGenerator.GenerateFunctionMap(UnitTestUtils.StreamReaderFromString(sourceCode));
List<FunctionMapEntry> functionMap = functionMapGenerator.ParseSourceCode(UnitTestUtils.StreamReaderFromString(sourceCode));
// Assert
Assert.AreEqual(2, functionMap.Count);
@ -367,5 +385,128 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
Assert.AreEqual(20, functionMap[1].StartSourcePosition.ZeroBasedColumnNumber);
Assert.AreEqual(22, functionMap[1].EndSourcePosition.ZeroBasedColumnNumber);
}
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_NoBinding_ReturnNullMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry();
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
// Act
string result = FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
// Assert
Assert.IsNull(result);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_HasSingleBindingNoMatchingMapping_ReturnNullMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 20, ZeroBasedColumnNumber = 15}
}
}
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(x => x.GetMappingEntryForGeneratedSourcePosition(Arg<SourcePosition>.Is.Anything)).Return(null);
// Act
string result = FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
// Assert
Assert.IsNull(result);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_HasSingleBindingMatchingMapping_ReturnsMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 5, ZeroBasedColumnNumber = 8}
}
}
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 5 && y.ZeroBasedColumnNumber == 8)))
.Return(new MappingEntry
{
OriginalName = "foo",
});
// Act
string result = FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
// Assert
Assert.AreEqual("foo", result);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_MatchingMappingMultipleBindings_ReturnsMethodNameWithFullBinding()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 5, ZeroBasedColumnNumber = 5}
},
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 20, ZeroBasedColumnNumber = 10}
}
}
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 5 && y.ZeroBasedColumnNumber == 5)))
.Return(new MappingEntry
{
OriginalName = "bar"
});
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 20 && y.ZeroBasedColumnNumber == 10)))
.Return(new MappingEntry
{
OriginalName = "baz",
});
// Act
string result = FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
// Assert
Assert.AreEqual("bar.baz", result);
sourceMap.VerifyAllExpectations();
}
}
}

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

@ -41,157 +41,6 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
StackFrame deminifiedStackFrame = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_NullInputs_DoesNotThrowException()
{
// Arrange
FunctionMapEntry functionMapEntry = null;
SourceMap sourceMap = null;
SourcePosition generatedSourcePosition = null;
// Act
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
// Assert
Assert.IsNull(deminifiedStackFrame.MethodName);
Assert.IsNull(deminifiedStackFrame.SourcePosition);
Assert.IsNull(deminifiedStackFrame.FilePath);
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_NoBinding_ReturnNullMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry();
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
SourcePosition generatedSourcePosition = new SourcePosition();
// Act
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
// Assert
Assert.IsNull(deminifiedStackFrame.MethodName);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_HasSingleBindingNoMatchingMapping_ReturnNullMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 20, ZeroBasedColumnNumber = 15}
}
}
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(x => x.GetMappingEntryForGeneratedSourcePosition(Arg<SourcePosition>.Is.Anything)).Return(null);
SourcePosition generatedSourcePosition = new SourcePosition();
// Act
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
// Assert
Assert.IsNull(deminifiedStackFrame.MethodName);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_HasSingleBindingMatchingMapping_ReturnsStackFrameWithMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 5, ZeroBasedColumnNumber = 8}
}
}
};
SourcePosition generatedSourcePosition = new SourcePosition
{
ZeroBasedColumnNumber = 25,
ZeroBasedLineNumber = 85
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 5 && y.ZeroBasedColumnNumber == 8)))
.Return(new MappingEntry
{
OriginalName = "foo",
});
// Act
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
// Assert
Assert.AreEqual("foo", deminifiedStackFrame.MethodName);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_MatchingMappingMultipleBindings_ReturnsStackFrameWithFullBinding()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 5, ZeroBasedColumnNumber = 5}
},
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 20, ZeroBasedColumnNumber = 10}
}
}
};
SourcePosition generatedSourcePosition = new SourcePosition {ZeroBasedColumnNumber = 39, ZeroBasedLineNumber = 31};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 5 && y.ZeroBasedColumnNumber == 5)))
.Return(new MappingEntry
{
OriginalName = "bar"
});
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 20 && y.ZeroBasedColumnNumber == 10)))
.Return(new MappingEntry
{
OriginalName = "baz",
});
// Act
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
// Assert
Assert.AreEqual("bar.baz", deminifiedStackFrame.MethodName);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void ExtractFrameInformationFromSourceMap_HasMatchingGeneratedPositionMapping_ReturnsStackFrameWithSourcePositionAndFileName()
{