Merge remote-tracking branch 'refs/remotes/Microsoft/master' into niliao-sourcemap-toolkit

This commit is contained in:
Nile Liao 2016-11-18 16:03:18 +08:00
Родитель ab0b2bab4b dbd930d862
Коммит 36477f4c40
18 изменённых файлов: 454 добавлений и 52 удалений

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

@ -111,7 +111,7 @@ StackTraceDeminifier sourceMapCallstackDeminifier = StackTraceDeminfierFactory.G
DeminifyStackTraceResult deminifyStackTraceResult = sourceMapCallstackDeminifier.DeminifyStackTrace(callstack)
```
The result of `DeminifyStackTrace` is a `DeminifyStackTraceResult`, which is an object that contains a list of the parsed minified `StackFrame` objects in the `MinifiedStackFrame` property. The `DeminifiedStackFrame` property contains the best guess `StackFrame` object that maps to the `MinifiedStackFrame` element with the same index. Note that any of the properties on a `StackTrace` object may be null if no value could be extracted from the input callstack string or source map.
The result of `DeminifyStackTrace` is a `DeminifyStackTraceResult`, which is an object that contains a list of `StackFrameDeminificationResults` which contains the parsed minified `StackFrame` objects in the `MinifiedStackFrame` property and an enum indicating if any errors occured when attempting to deminify the `StackFrame`. The `DeminifiedStackFrame` property contains the best guess `StackFrame` object that maps to the `MinifiedStackFrame` element with the same index. Note that any of the properties on a `StackTrace` object may be null if no value could be extracted from the input callstack string or source map.
#### Memory Consumption
Parsed soure maps can take up a lot of memory for large JavaScript files. In order to allow for the `StackTraceDeminifier` to be used on servers with limited memory resources, the `StackTraceDeminfierFactory` exposes a `GetMethodNameOnlyStackTraceDeminfier` method that returns a `StackTraceDeminifier` that does not keep source maps in memory. Since the `StackTraceDeminifier` returned from this method only reads the source map once, the deminified stack frames will only contain the deminified method name and will not contain the original source location.

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

@ -6,6 +6,6 @@ namespace SourcemapToolkit.CallstackDeminifier
{
public List<StackFrame> MinifiedStackFrames;
public List<StackFrame> DeminifiedStackFrames;
public List<StackFrameDeminificationResult> DeminifiedStackFrameResults;
}
}

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

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Ajax.Utilities;
@ -61,36 +62,42 @@ namespace SourcemapToolkit.CallstackDeminifier
/// <summary>
/// Gets the original name corresponding to a function based on the information provided in the source map.
/// </summary>
/// <returns></returns>
internal static string GetDeminifiedMethodNameFromSourceMap(FunctionMapEntry wrappingFunction, SourceMap sourceMap)
{
if (wrappingFunction == null)
{
throw new ArgumentNullException(nameof(wrappingFunction));
}
if (sourceMap == null)
{
throw new ArgumentNullException(nameof(sourceMap));
}
string methodName = null;
if (wrappingFunction?.Bindings != null && wrappingFunction.Bindings.Count > 0)
if (wrappingFunction.Bindings != null && wrappingFunction.Bindings.Count > 0)
{
if (wrappingFunction.Bindings.Count == 2)
{
MappingEntry objectProtoypeMappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings[0].SourcePosition);
sourceMap.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings[0].SourcePosition);
methodName = objectProtoypeMappingEntry?.OriginalName;
}
MappingEntry mappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings.Last().SourcePosition);
sourceMap.GetMappingEntryForGeneratedSourcePosition(wrappingFunction.Bindings.Last().SourcePosition);
if (mappingEntry != null)
if (mappingEntry?.OriginalName != null)
{
if (mappingEntry.OriginalName != null)
if (methodName != null)
{
if (methodName != null)
{
methodName = methodName + "." + mappingEntry.OriginalName;
}
else
{
methodName = mappingEntry.OriginalName;
}
methodName = methodName + "." + mappingEntry.OriginalName;
}
else
{
methodName = mappingEntry.OriginalName;
}
}
}

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

@ -5,7 +5,7 @@
/// <summary>
/// This method will deminify a single stack from from a minified stack trace.
/// </summary>
/// <returns>Returns a stack trace that has been translated to the original source code. Returns null if it could not be deminified.</returns>
StackFrame DeminifyStackFrame(StackFrame stackFrame);
/// <returns>Returns a StackFrameDeminificationResult that contains a stack trace that has been translated to the original source code. The DeminificationError Property indicates if the StackFrame could not be deminified. DeminifiedStackFrame will not be null, but any properties of DeminifiedStackFrame could be null if the value could not be extracted. </returns>
StackFrameDeminificationResult DeminifyStackFrame(StackFrame stackFrame);
}
}

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

@ -19,8 +19,12 @@ namespace SourcemapToolkit.CallstackDeminifier
/// <summary>
/// This method will deminify the method name of a single stack from from a minified stack trace.
/// </summary>
public virtual StackFrame DeminifyStackFrame(StackFrame stackFrame)
public virtual StackFrameDeminificationResult DeminifyStackFrame(StackFrame stackFrame)
{
StackFrameDeminificationResult result = new StackFrameDeminificationResult
{
DeminificationError = DeminificationError.None
};
if (stackFrame == null)
{
throw new ArgumentNullException(nameof(stackFrame));
@ -36,9 +40,19 @@ namespace SourcemapToolkit.CallstackDeminifier
{
wrappingFunction =
_functionMapConsumer.GetWrappingFunctionForSourceLocation(stackFrame.SourcePosition, functionMap);
if (wrappingFunction == null)
{
result.DeminificationError = DeminificationError.NoWrapingFunctionFound;
}
}
else
{
result.DeminificationError = DeminificationError.NoSourceCodeProvided;
}
return new StackFrame {MethodName = wrappingFunction?.DeminfifiedMethodName};
result.DeminifiedStackFrame = new StackFrame {MethodName = wrappingFunction?.DeminfifiedMethodName};
return result;
}
}
}

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

@ -51,6 +51,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="StackFrameDeminificationResult.cs" />
<Compile Include="DeminifyStackTraceResult.cs" />
<Compile Include="FunctionFinderVisitor.cs" />
<Compile Include="FunctionMapConsumer.cs" />
@ -74,15 +75,15 @@
<Compile Include="StackTraceDeminifier.cs" />
<Compile Include="StackTraceParser.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SourcemapToolkit.SourcemapParser\SourcemapToolkit.SourcemapParser.csproj">
<Project>{69FD1EB5-32F2-4759-9187-9A8E25927BCA}</Project>
<Name>SourcemapToolkit.SourcemapParser</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

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

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SourcemapToolkit.CallstackDeminifier
{
/// <summary>
/// Enum indicating if there were any errors encountered when attempting to deminify the StakFrame.
/// </summary>
public enum DeminificationError
{
/// <summary>
/// No error was encountered durring deminification of the StackFrame.
/// </summary>
None,
/// <summary>
/// There was no source code provided by the ISourceCodeProvider.
/// </summary>
NoSourceCodeProvided,
/// <summary>
/// The function that wraps the minified stack frame could not be determined.
/// </summary>
NoWrapingFunctionFound,
/// <summary>
/// There was not a valid source map returned by ISourceMapProvider.GetSourceMapForUrl.
/// </summary>
NoSourceMap,
/// <summary>
/// A mapping entry was not found for the source position of the minified stack frame.
/// </summary>
NoMatchingMapingInSourceMap,
/// <summary>
/// There was an error when attempting to parse the source map returned by ISourceMapProvider.GetSourceMapForUrl.
/// </summary>
SourceMapFailedToParse
}
/// <summary>
/// Represents the result of attmpting to deminify a single entry in a JavaScript stack frame.
/// </summary>
public class StackFrameDeminificationResult
{
/// <summary>
/// The deminified StackFrame.
/// </summary>
public StackFrame DeminifiedStackFrame { get; set; }
/// <summary>
/// An enum indicating if any errors occured when deminifying the stack frame.
/// </summary>
public DeminificationError DeminificationError { get; set; }
}
}

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

@ -21,8 +21,8 @@ namespace SourcemapToolkit.CallstackDeminifier
/// <summary>
/// This method will deminify a single stack from from a minified stack trace.
/// </summary>
/// <returns>Returns a stack trace that has been translated to a best guess of the original source code. Any of the fields in the stack frame may be null</returns>
public override StackFrame DeminifyStackFrame(StackFrame stackFrame)
/// <returns>Returns a StackFrameDeminificationResult that contains a stack trace that has been translated to the original source code. The DeminificationError Property indicates if the StackFrame could not be deminified. DeminifiedStackFrame will not be null, but any properties of DeminifiedStackFrame could be null if the value could not be extracted. </returns>
public override StackFrameDeminificationResult DeminifyStackFrame(StackFrame stackFrame)
{
if (stackFrame == null)
{
@ -32,11 +32,31 @@ namespace SourcemapToolkit.CallstackDeminifier
SourceMap sourceMap = _sourceMapStore.GetSourceMapForUrl(stackFrame.FilePath);
SourcePosition generatedSourcePosition = stackFrame.SourcePosition;
StackFrame result = base.DeminifyStackFrame(stackFrame);
StackFrameDeminificationResult result = base.DeminifyStackFrame(stackFrame);
if (result.DeminificationError == DeminificationError.None)
{
MappingEntry generatedSourcePositionMappingEntry =
sourceMap?.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition);
MappingEntry generatedSourcePositionMappingEntry = sourceMap?.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition);
result.FilePath = generatedSourcePositionMappingEntry?.OriginalFileName;
result.SourcePosition = generatedSourcePositionMappingEntry?.OriginalSourcePosition;
if (generatedSourcePositionMappingEntry == null)
{
if (sourceMap == null)
{
result.DeminificationError = DeminificationError.NoSourceMap;
}
else if (sourceMap.ParsedMappings == null)
{
result.DeminificationError = DeminificationError.SourceMapFailedToParse;
}
else
{
result.DeminificationError = DeminificationError.NoMatchingMapingInSourceMap;
}
}
result.DeminifiedStackFrame.FilePath = generatedSourcePositionMappingEntry?.OriginalFileName;
result.DeminifiedStackFrame.SourcePosition = generatedSourcePositionMappingEntry?.OriginalSourcePosition;
}
return result;
}

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

@ -25,11 +25,11 @@ namespace SourcemapToolkit.CallstackDeminifier
{
DeminifyStackTraceResult result = new DeminifyStackTraceResult();
result.MinifiedStackFrames = _stackTraceParser.ParseStackTrace(stackTraceString);
result.DeminifiedStackFrames = new List<StackFrame>();
result.DeminifiedStackFrameResults = new List<StackFrameDeminificationResult>();
foreach (StackFrame minifiedStackFrame in result.MinifiedStackFrames)
{
result.DeminifiedStackFrames.Add(_stackFrameDeminifier.DeminifyStackFrame(minifiedStackFrame));
result.DeminifiedStackFrameResults.Add(_stackFrameDeminifier.DeminifyStackFrame(minifiedStackFrame));
}
return result;

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

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AjaxMin" version="5.14.5506.26202" targetFramework="net452" />
<package id="AjaxMin" version="5.14.5506.26202" targetFramework="net45" />
</packages>

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

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="D:\NugetCache\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('D:\NugetCache\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="D:\NugetCache\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('D:\NugetCache\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

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

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
</packages>

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

@ -385,6 +385,30 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
Assert.AreEqual(22, functionMap[1].EndSourcePosition.ZeroBasedColumnNumber);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void GetDeminifiedMethodNameFromSourceMap_NullFunctionMapEntry_ThrowsException()
{
// Arrange
FunctionMapEntry functionMapEntry = null;
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
// Act
FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void GetDeminifiedMethodNameFromSourceMap_NullSourceMap_ThrowsException()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry();
SourceMap sourceMap = null;
// Act
FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_NoBinding_ReturnNullMethodName()
{
@ -461,6 +485,50 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_MatchingMappingMultipleBindingsMissingPrototypeMapping_ReturnsMethodName()
{
// Arrange
FunctionMapEntry functionMapEntry = new FunctionMapEntry
{
Bindings =
new List<BindingInformation>
{
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 86, ZeroBasedColumnNumber = 52}
},
new BindingInformation
{
SourcePosition = new SourcePosition {ZeroBasedLineNumber = 88, ZeroBasedColumnNumber = 78}
}
}
};
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 86 && y.ZeroBasedColumnNumber == 52)))
.Return(null);
sourceMap.Stub(
x =>
x.GetMappingEntryForGeneratedSourcePosition(
Arg<SourcePosition>.Matches(y => y.ZeroBasedLineNumber == 88 && y.ZeroBasedColumnNumber == 78)))
.Return(new MappingEntry
{
OriginalName = "baz",
});
// Act
string result = FunctionMapGenerator.GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
// Assert
Assert.AreEqual("baz", result);
sourceMap.VerifyAllExpectations();
}
[TestMethod]
public void GetDeminifiedMethodNameFromSourceMap_MatchingMappingMultipleBindings_ReturnsMethodNameWithFullBinding()
{

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

@ -65,6 +65,7 @@
<Compile Include="FunctionMapConsumerUnitTests.cs" />
<Compile Include="FunctionMapGeneratorUnitTests.cs" />
<Compile Include="KeyValueCacheUnitTests.cs" />
<Compile Include="StackFrameDeminifierUnitTests.cs" />
<Compile Include="StackTraceDeminifierClosureEndToEndTests.cs" />
<Compile Include="StackTraceDeminifierEndToEndTests.cs" />
<Compile Include="StackTraceDeminifierUnitTests.cs" />

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

@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using SourcemapToolkit.SourcemapParser;
namespace SourcemapToolkit.CallstackDeminifier.UnitTests
{
[TestClass]
public class StackFrameDeminifierUnitTests
{
private IStackFrameDeminifier GetStackFrameDeminifierWithMockDependencies(ISourceMapStore sourceMapStore = null, IFunctionMapStore functionMapStore = null, IFunctionMapConsumer functionMapConsumer = null, bool useSimpleStackFrameDeminier = false)
{
if (sourceMapStore == null)
{
sourceMapStore = MockRepository.GenerateStub<ISourceMapStore>();
}
if (functionMapStore == null)
{
functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
}
if (functionMapConsumer == null)
{
functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
}
if (useSimpleStackFrameDeminier)
{
return new SimpleStackFrameDeminifier(functionMapStore, functionMapConsumer);
}
else
{
return new StackFrameDeminifier(sourceMapStore, functionMapStore, functionMapConsumer);
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void DeminifyStackFrame_NullInputStackFrame_ThrowsException()
{
// Arrange
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies();
StackFrame stackFrame = null;
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
}
[TestMethod]
public void DeminifyStackFrame_StackFrameNullProperties_DoesNotThrowException()
{
// Arrange
StackFrame stackFrame = new StackFrame();
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies();
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void SimpleStackFrameDeminierDeminifyStackFrame_FunctionMapReturnsNull_NoFunctionMapDeminificationError()
{
// Arrange
string filePath = "foo";
StackFrame stackFrame = new StackFrame {FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(null);
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(functionMapStore: functionMapStore, useSimpleStackFrameDeminier:true);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.NoSourceCodeProvided, stackFrameDeminification.DeminificationError);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void SimpleStackFrameDeminierDeminifyStackFrame_GetWRappingFunctionForSourceLocationReturnsNull_NoWrapingFunctionDeminificationError()
{
// Arrange
string filePath = "foo";
StackFrame stackFrame = new StackFrame { FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(new List<FunctionMapEntry>());
IFunctionMapConsumer functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
functionMapConsumer.Stub(c => c.GetWrappingFunctionForSourceLocation(Arg<SourcePosition>.Is.Anything, Arg<List<FunctionMapEntry>>.Is.Anything))
.Return(null);
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(functionMapStore: functionMapStore, functionMapConsumer: functionMapConsumer, useSimpleStackFrameDeminier: true);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.NoWrapingFunctionFound, stackFrameDeminification.DeminificationError);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void SimpleStackFrameDeminierDeminifyStackFrame_WrapingFunctionFound_NoDeminificationError()
{
// Arrange
string filePath = "foo";
FunctionMapEntry wrapingFunctionMapEntry = new FunctionMapEntry {DeminfifiedMethodName = "DeminifiedFoo"};
StackFrame stackFrame = new StackFrame { FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(new List<FunctionMapEntry>());
IFunctionMapConsumer functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
functionMapConsumer.Stub(c => c.GetWrappingFunctionForSourceLocation(Arg<SourcePosition>.Is.Anything, Arg<List<FunctionMapEntry>>.Is.Anything))
.Return(wrapingFunctionMapEntry);
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(functionMapStore: functionMapStore, functionMapConsumer: functionMapConsumer, useSimpleStackFrameDeminier: true);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.None, stackFrameDeminification.DeminificationError);
Assert.AreEqual(wrapingFunctionMapEntry.DeminfifiedMethodName, stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void StackFrameDeminierDeminifyStackFrame_SourceMapProviderReturnsNull_NoSourcemapProvidedError()
{
// Arrange
string filePath = "foo";
FunctionMapEntry wrapingFunctionMapEntry = new FunctionMapEntry { DeminfifiedMethodName = "DeminifiedFoo" };
StackFrame stackFrame = new StackFrame { FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(new List<FunctionMapEntry>());
IFunctionMapConsumer functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
functionMapConsumer.Stub(c => c.GetWrappingFunctionForSourceLocation(Arg<SourcePosition>.Is.Anything, Arg<List<FunctionMapEntry>>.Is.Anything))
.Return(wrapingFunctionMapEntry);
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(functionMapStore: functionMapStore, functionMapConsumer: functionMapConsumer);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.NoSourceMap, stackFrameDeminification.DeminificationError);
Assert.AreEqual(wrapingFunctionMapEntry.DeminfifiedMethodName, stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void StackFrameDeminierDeminifyStackFrame_SourceMapParsingNull_SourceMapFailedToParseError()
{
// Arrange
string filePath = "foo";
FunctionMapEntry wrapingFunctionMapEntry = new FunctionMapEntry { DeminfifiedMethodName = "DeminifiedFoo" };
StackFrame stackFrame = new StackFrame { FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(new List<FunctionMapEntry>());
IFunctionMapConsumer functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
functionMapConsumer.Stub(c => c.GetWrappingFunctionForSourceLocation(Arg<SourcePosition>.Is.Anything, Arg<List<FunctionMapEntry>>.Is.Anything))
.Return(wrapingFunctionMapEntry);
ISourceMapStore sourceMapStore = MockRepository.GenerateStub<ISourceMapStore>();
sourceMapStore.Stub(c => c.GetSourceMapForUrl(Arg<string>.Is.Anything)).Return(new SourceMap());
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(sourceMapStore: sourceMapStore,functionMapStore: functionMapStore, functionMapConsumer: functionMapConsumer);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.SourceMapFailedToParse, stackFrameDeminification.DeminificationError);
Assert.AreEqual(wrapingFunctionMapEntry.DeminfifiedMethodName, stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
[TestMethod]
public void StackFrameDeminierDeminifyStackFrame_SourceMapGeneratedMappingEntryNull_NoMatchingMapingInSourceMapError()
{
// Arrange
string filePath = "foo";
FunctionMapEntry wrapingFunctionMapEntry = new FunctionMapEntry { DeminfifiedMethodName = "DeminifiedFoo" };
StackFrame stackFrame = new StackFrame { FilePath = filePath };
IFunctionMapStore functionMapStore = MockRepository.GenerateStub<IFunctionMapStore>();
functionMapStore.Stub(c => c.GetFunctionMapForSourceCode(filePath))
.Return(new List<FunctionMapEntry>());
ISourceMapStore sourceMapStore = MockRepository.GenerateStub<ISourceMapStore>();
SourceMap sourceMap = new SourceMap() {ParsedMappings = new List<MappingEntry>()};
sourceMapStore.Stub(c => c.GetSourceMapForUrl(Arg<string>.Is.Anything)).Return(sourceMap);
IFunctionMapConsumer functionMapConsumer = MockRepository.GenerateStub<IFunctionMapConsumer>();
functionMapConsumer.Stub(c => c.GetWrappingFunctionForSourceLocation(Arg<SourcePosition>.Is.Anything, Arg<List<FunctionMapEntry>>.Is.Anything))
.Return(wrapingFunctionMapEntry);
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies(sourceMapStore: sourceMapStore, functionMapStore: functionMapStore, functionMapConsumer: functionMapConsumer);
// Act
StackFrameDeminificationResult stackFrameDeminification = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
// Assert
Assert.AreEqual(DeminificationError.NoMatchingMapingInSourceMap, stackFrameDeminification.DeminificationError);
Assert.AreEqual(wrapingFunctionMapEntry.DeminfifiedMethodName, stackFrameDeminification.DeminifiedStackFrame.MethodName);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.SourcePosition);
Assert.IsNull(stackFrameDeminification.DeminifiedStackFrame.FilePath);
}
}
}

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

@ -25,11 +25,12 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
private void ValidateDeminifyStackTraceResults(DeminifyStackTraceResult results)
{
Assert.AreEqual(4, results.DeminifiedStackFrames.Count);
Assert.AreEqual("mynamespace.objectWithMethods.propertyMethodLevel2", results.DeminifiedStackFrames[0].MethodName);
Assert.AreEqual("mynamespace.objectWithMethods.prototypeMethodLevel1", results.DeminifiedStackFrames[1].MethodName);
Assert.AreEqual("GlobalFunction", results.DeminifiedStackFrames[2].MethodName);
Assert.AreEqual("window", results.DeminifiedStackFrames[3].MethodName);
Assert.AreEqual(4, results.DeminifiedStackFrameResults.Count);
Assert.AreEqual(DeminificationError.None, results.DeminifiedStackFrameResults[0].DeminificationError);
Assert.AreEqual("mynamespace.objectWithMethods.propertyMethodLevel2", results.DeminifiedStackFrameResults[0].DeminifiedStackFrame.MethodName);
Assert.AreEqual("mynamespace.objectWithMethods.prototypeMethodLevel1", results.DeminifiedStackFrameResults[1].DeminifiedStackFrame.MethodName);
Assert.AreEqual("GlobalFunction", results.DeminifiedStackFrameResults[2].DeminifiedStackFrame.MethodName);
Assert.AreEqual("window", results.DeminifiedStackFrameResults[3].DeminifiedStackFrame.MethodName);
}
[TestMethod]

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

@ -23,12 +23,13 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
private static void ValidateDeminifyStackTraceResults(DeminifyStackTraceResult results)
{
Assert.AreEqual(5, results.DeminifiedStackFrames.Count);
Assert.AreEqual("level3", results.DeminifiedStackFrames[0].MethodName);
Assert.AreEqual("level2", results.DeminifiedStackFrames[1].MethodName);
Assert.AreEqual("level1", results.DeminifiedStackFrames[2].MethodName);
Assert.AreEqual("causeCrash", results.DeminifiedStackFrames[3].MethodName);
Assert.AreEqual("window", results.DeminifiedStackFrames[4].MethodName);
Assert.AreEqual(5, results.DeminifiedStackFrameResults.Count);
Assert.AreEqual(DeminificationError.None, results.DeminifiedStackFrameResults[0].DeminificationError);
Assert.AreEqual("level3", results.DeminifiedStackFrameResults[0].DeminifiedStackFrame.MethodName);
Assert.AreEqual("level2", results.DeminifiedStackFrameResults[1].DeminifiedStackFrame.MethodName);
Assert.AreEqual("level1", results.DeminifiedStackFrameResults[2].DeminifiedStackFrame.MethodName);
Assert.AreEqual("causeCrash", results.DeminifiedStackFrameResults[3].DeminifiedStackFrame.MethodName);
Assert.AreEqual("window", results.DeminifiedStackFrameResults[4].DeminifiedStackFrame.MethodName);
}
[TestMethod]

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

@ -23,7 +23,7 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
DeminifyStackTraceResult result = stackTraceDeminifier.DeminifyStackTrace(stackTraceString);
// Assert
Assert.AreEqual(0, result.DeminifiedStackFrames.Count);
Assert.AreEqual(0, result.DeminifiedStackFrameResults.Count);
}
[TestMethod]
@ -44,9 +44,9 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
DeminifyStackTraceResult result = stackTraceDeminifier.DeminifyStackTrace(stackTraceString);
// Assert
Assert.AreEqual(1, result.DeminifiedStackFrames.Count);
Assert.AreEqual(1, result.DeminifiedStackFrameResults.Count);
Assert.AreEqual(minifiedStackFrames[0], result.MinifiedStackFrames[0]);
Assert.IsNull(result.DeminifiedStackFrames[0]);
Assert.IsNull(result.DeminifiedStackFrameResults[0]);
}
[TestMethod]
@ -59,8 +59,8 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
stackTraceParser.Stub(x => x.ParseStackTrace(stackTraceString)).Return(minifiedStackFrames);
IStackFrameDeminifier stackFrameDeminifier = MockRepository.GenerateStrictMock<IStackFrameDeminifier>();
StackFrame deminifiedStackFrame = new StackFrame();
stackFrameDeminifier.Stub(x => x.DeminifyStackFrame(minifiedStackFrames[0])).Return(deminifiedStackFrame);
StackFrameDeminificationResult stackFrameDeminification = new StackFrameDeminificationResult();
stackFrameDeminifier.Stub(x => x.DeminifyStackFrame(minifiedStackFrames[0])).Return(stackFrameDeminification);
StackTraceDeminifier stackTraceDeminifier = new StackTraceDeminifier(stackFrameDeminifier, stackTraceParser);
@ -68,9 +68,9 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
DeminifyStackTraceResult result = stackTraceDeminifier.DeminifyStackTrace(stackTraceString);
// Assert
Assert.AreEqual(1, result.DeminifiedStackFrames.Count);
Assert.AreEqual(1, result.DeminifiedStackFrameResults.Count);
Assert.AreEqual(minifiedStackFrames[0], result.MinifiedStackFrames[0]);
Assert.AreEqual(deminifiedStackFrame, result.DeminifiedStackFrames[0]);
Assert.AreEqual(stackFrameDeminification, result.DeminifiedStackFrameResults[0]);
}
}
}