Have IStackFrameDeminifier.DeminifyStackFrame return a StackFrameDeminificationResult to report error cases when deminifying a StackFrame (#33)

* Keep track of any error cases encountered when attempting to deminify a StackFrame. Instead of returning a list of StackFrames in DeminifyStackTraceResult, we will return a StackFrameDeminificationResult, which contains the deminified StackFrame as well as an enum indicating if any error cases were hit. This result can be used to help provide information of any error cases in the SourceMapToolkit without having to debug.

* Updating documentation.

* Missed merges

* Add back StackFrameDeminifierUnitTests with test coverage to make sure StackFrameDeminificationResults are recorded correctly.

* Undo hint path for nuget packages from local box

* Fix up SourceMapToolkil csproj

* Documentation cleanup

* fix type in documentation

* Do not do Bitwise or on DeminificationError, since the Flags attribute was removed in a previous commit. Additionally update the NoFunctionMapProvided error to be NoSourceCodeProvided since FunctionMap is not

* If we fail to get the deminified stackframe method, we shouldn't attempt to get the source position or file path
This commit is contained in:
thomabr 2016-11-17 11:53:45 -08:00 коммит произвёл Christian Gonzalez
Родитель 0ff79ec40a
Коммит 067780e128
16 изменённых файлов: 364 добавлений и 37 удалений

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

@ -38,7 +38,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;
}
}

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

@ -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>

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

@ -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]);
}
}
}