Create the SimpleStackFrameDeminfier which uses significantly less memory than the StackTraceDeminifier during runtime.
This commit is contained in:
Родитель
411d1a54ab
Коммит
64538ebc58
|
@ -12,17 +12,15 @@ namespace SourcemapToolkit.CallstackDeminifier
|
|||
/// 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)
|
||||
public List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader, SourceMap sourceMap)
|
||||
{
|
||||
if (sourceCodeStreamReader == null || sourceMapStreamReader == null)
|
||||
if (sourceCodeStreamReader == null || sourceMap == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<FunctionMapEntry> result = ParseSourceCode(sourceMapStreamReader);
|
||||
List<FunctionMapEntry> result = ParseSourceCode(sourceCodeStreamReader);
|
||||
|
||||
SourceMapParser sourceMapParser = new SourceMapParser();
|
||||
SourceMap sourceMap = sourceMapParser.ParseSourceMap(sourceMapStreamReader);
|
||||
foreach (FunctionMapEntry functionMapEntry in result)
|
||||
{
|
||||
functionMapEntry.DeminfifiedMethodName = GetDeminifiedMethodNameFromSourceMap(functionMapEntry, sourceMap);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SourcemapToolkit.SourcemapParser;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
|
@ -10,12 +12,12 @@ namespace SourcemapToolkit.CallstackDeminifier
|
|||
private readonly IFunctionMapGenerator _functionMapGenerator;
|
||||
private readonly KeyValueCache<string,List<FunctionMapEntry>> _functionMapCache;
|
||||
|
||||
public FunctionMapStore(ISourceCodeProvider sourceCodeProvider, ISourceMapProvider sourceMapProvider)
|
||||
public FunctionMapStore(ISourceCodeProvider sourceCodeProvider, Func<string, SourceMap> sourceMapGetter)
|
||||
{
|
||||
_functionMapGenerator = new FunctionMapGenerator();
|
||||
_functionMapCache = new KeyValueCache<string, List<FunctionMapEntry>>(sourceCodeUrl => _functionMapGenerator.GenerateFunctionMap(
|
||||
sourceCodeProvider.GetSourceCode(sourceCodeUrl),
|
||||
sourceMapProvider.GetSourceMapContentsForCallstackUrl(sourceCodeUrl)));
|
||||
sourceMapGetter(sourceCodeUrl)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SourcemapToolkit.SourcemapParser;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
|
@ -9,6 +10,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, StreamReader sourceMapStreamReader);
|
||||
List<FunctionMapEntry> GenerateFunctionMap(StreamReader sourceCodeStreamReader, SourceMap sourceMap);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
/// <summary>
|
||||
/// This class only deminfies the method name in a stack frame. It does not depend on having a source map available during runtime.
|
||||
/// </summary>
|
||||
internal class SimpleStackFrameDeminifier : IStackFrameDeminifier
|
||||
{
|
||||
protected readonly IFunctionMapConsumer _functionMapConsumer;
|
||||
protected readonly IFunctionMapStore _functionMapStore;
|
||||
|
||||
public SimpleStackFrameDeminifier(IFunctionMapStore functionMapStore, IFunctionMapConsumer functionMapConsumer)
|
||||
{
|
||||
_functionMapStore = functionMapStore;
|
||||
_functionMapConsumer = functionMapConsumer;
|
||||
}
|
||||
|
||||
public virtual StackFrame DeminifyStackFrame(StackFrame stackFrame)
|
||||
{
|
||||
if (stackFrame == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stackFrame));
|
||||
}
|
||||
|
||||
FunctionMapEntry wrappingFunction = null;
|
||||
|
||||
// This code deminifies the stack frame by finding the wrapping function in
|
||||
// the generated code and then using the source map to find the name and
|
||||
// and original source location.
|
||||
List<FunctionMapEntry> functionMap = _functionMapStore.GetFunctionMapForSourceCode(stackFrame.FilePath);
|
||||
if (functionMap != null)
|
||||
{
|
||||
wrappingFunction =
|
||||
_functionMapConsumer.GetWrappingFunctionForSourceLocation(stackFrame.SourcePosition, functionMap);
|
||||
}
|
||||
|
||||
return new StackFrame {MethodName = wrappingFunction?.DeminfifiedMethodName};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,10 +65,12 @@
|
|||
<Compile Include="IStackFrameDeminifier.cs" />
|
||||
<Compile Include="IStackTraceParser.cs" />
|
||||
<Compile Include="KeyValueCache.cs" />
|
||||
<Compile Include="SimpleStackFrameDeminifier.cs" />
|
||||
<Compile Include="SourceMapStore.cs" />
|
||||
<Compile Include="StackFrame.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StackFrameDeminifier.cs" />
|
||||
<Compile Include="StackTraceDeminfierFactory.cs" />
|
||||
<Compile Include="StackTraceDeminifier.cs" />
|
||||
<Compile Include="StackTraceParser.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,70 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SourcemapToolkit.SourcemapParser;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Class responsible for deminifying a single stack frame in a minified stack trace.
|
||||
/// </summary>
|
||||
internal class StackFrameDeminifier : IStackFrameDeminifier
|
||||
internal class StackFrameDeminifier : SimpleStackFrameDeminifier
|
||||
{
|
||||
private readonly IFunctionMapConsumer _functionMapConsumer;
|
||||
private readonly IFunctionMapStore _functionMapStore;
|
||||
private readonly ISourceMapStore _sourceMapStore;
|
||||
|
||||
public StackFrameDeminifier(ISourceMapStore sourceMapStore, IFunctionMapStore functionMapStore, IFunctionMapConsumer functionMapConsumer)
|
||||
public StackFrameDeminifier(ISourceMapStore sourceMapStore, IFunctionMapStore functionMapStore, IFunctionMapConsumer functionMapConsumer) : base (functionMapStore, functionMapConsumer)
|
||||
{
|
||||
_functionMapStore = functionMapStore;
|
||||
_sourceMapStore = sourceMapStore;
|
||||
_functionMapConsumer = functionMapConsumer;
|
||||
}
|
||||
|
||||
/// <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 StackFrame DeminifyStackFrame(StackFrame stackFrame)
|
||||
public override StackFrame DeminifyStackFrame(StackFrame stackFrame)
|
||||
{
|
||||
if (stackFrame == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stackFrame));
|
||||
}
|
||||
if (stackFrame == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stackFrame));
|
||||
}
|
||||
|
||||
FunctionMapEntry wrappingFunction = null;
|
||||
SourceMap sourceMap = _sourceMapStore.GetSourceMapForUrl(stackFrame.FilePath);
|
||||
SourceMap sourceMap = _sourceMapStore.GetSourceMapForUrl(stackFrame.FilePath);
|
||||
SourcePosition generatedSourcePosition = stackFrame.SourcePosition;
|
||||
|
||||
// This code deminifies the stack frame by finding the wrapping function in
|
||||
// the generated code and then using the source map to find the name and
|
||||
// and original source location.
|
||||
List<FunctionMapEntry> functionMap = _functionMapStore.GetFunctionMapForSourceCode(stackFrame.FilePath);
|
||||
if (functionMap != null)
|
||||
{
|
||||
wrappingFunction =
|
||||
_functionMapConsumer.GetWrappingFunctionForSourceLocation(stackFrame.SourcePosition, functionMap);
|
||||
}
|
||||
StackFrame result = base.DeminifyStackFrame(stackFrame);
|
||||
|
||||
return ExtractFrameInformationFromSourceMap(wrappingFunction, sourceMap, stackFrame.SourcePosition);
|
||||
}
|
||||
MappingEntry generatedSourcePositionMappingEntry = sourceMap?.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition);
|
||||
result.FilePath = generatedSourcePositionMappingEntry?.OriginalFileName;
|
||||
result.SourcePosition = generatedSourcePositionMappingEntry?.OriginalSourcePosition;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information necessary for a deminified stack frame from the relevant source map.
|
||||
/// </summary>
|
||||
/// <param name="wrappingFunction">The function that wraps the current stack frame location</param>
|
||||
/// <param name="sourceMap">The relevant source map for this generated code</param>
|
||||
/// <param name="generatedSourcePosition">The location that should be translated to original source code location in the deminified stack frame.</param>
|
||||
/// <returns>Returns a StackFrame object with best guess values for each property. Any of the properties may be null if no match was found.</returns>
|
||||
internal static StackFrame ExtractFrameInformationFromSourceMap(FunctionMapEntry wrappingFunction, SourceMap sourceMap, SourcePosition generatedSourcePosition)
|
||||
{
|
||||
StackFrame result = new StackFrame();
|
||||
|
||||
result.MethodName = wrappingFunction.DeminfifiedMethodName;
|
||||
MappingEntry generatedSourcePositionMappingEntry = sourceMap?.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition);
|
||||
result.FilePath = generatedSourcePositionMappingEntry?.OriginalFileName;
|
||||
result.SourcePosition = generatedSourcePositionMappingEntry?.OriginalSourcePosition;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using SourcemapToolkit.SourcemapParser;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
public class StackTraceDeminfierFactory
|
||||
{
|
||||
private void ValidateArguments(ISourceMapProvider sourceMapProvider, ISourceCodeProvider generatedCodeProvider)
|
||||
{
|
||||
if (sourceMapProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sourceMapProvider));
|
||||
}
|
||||
|
||||
if (generatedCodeProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(generatedCodeProvider));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a StackTraceDeminifier with full capabilities. StackTrace deminifiers created with this method will keep source maps cached, and thus use significantly more memory during runtime than the MethodNameStackTraceDeminifier.
|
||||
/// </summary>
|
||||
/// <param name="sourceMapProvider">Consumers of the API should implement this interface, which provides the source map for a given JavaScript file. Throws ArgumentNullException if the parameter is set to null.</param>
|
||||
/// <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 GetStackTraceDeminfier(ISourceMapProvider sourceMapProvider, ISourceCodeProvider generatedCodeProvider)
|
||||
{
|
||||
ValidateArguments(sourceMapProvider, generatedCodeProvider);
|
||||
|
||||
ISourceMapStore sourceMapStore = new SourceMapStore(sourceMapProvider);
|
||||
IStackFrameDeminifier stackFrameDeminifier = new StackFrameDeminifier(sourceMapStore,
|
||||
new FunctionMapStore(generatedCodeProvider, sourceMapStore.GetSourceMapForUrl), new FunctionMapConsumer());
|
||||
|
||||
IStackTraceParser stackTraceParser = new StackTraceParser();
|
||||
|
||||
return new StackTraceDeminifier(stackFrameDeminifier, stackTraceParser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a StackTraceDeminifier that only deminifies the method names. StackTrace deminifiers created with this method will use significantly less memory during runtime than the
|
||||
/// </summary>
|
||||
/// <param name="sourceMapProvider">Consumers of the API should implement this interface, which provides the source map for a given JavaScript file. Throws ArgumentNullException if the parameter is set to null.</param>
|
||||
/// <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 GetMethodNameOnlyStackTraceDeminfier(ISourceMapProvider sourceMapProvider, ISourceCodeProvider generatedCodeProvider)
|
||||
{
|
||||
ValidateArguments(sourceMapProvider, generatedCodeProvider);
|
||||
|
||||
SourceMapParser sourceMapParser = new SourceMapParser();
|
||||
IStackFrameDeminifier stackFrameDeminifier = new SimpleStackFrameDeminifier(new FunctionMapStore(generatedCodeProvider, (url) => sourceMapParser.ParseSourceMap(sourceMapProvider.GetSourceMapContentsForCallstackUrl(url))), new FunctionMapConsumer());
|
||||
|
||||
IStackTraceParser stackTraceParser = new StackTraceParser();
|
||||
|
||||
return new StackTraceDeminifier(stackFrameDeminifier, stackTraceParser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SourcemapToolkit.CallstackDeminifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Public API for parsing and deminifying browser stack traces.
|
||||
/// </summary>
|
||||
public class StackTraceDeminifier
|
||||
/// <summary>
|
||||
/// This class is responsible for parsing a callstack string into
|
||||
/// a list of StackFrame objects and providing the deminified version
|
||||
/// of the stack frame.
|
||||
/// </summary>
|
||||
public class StackTraceDeminifier
|
||||
{
|
||||
private readonly IStackFrameDeminifier _stackFrameDeminifier;
|
||||
private readonly IStackTraceParser _stackTraceParser;
|
||||
|
||||
/// <summary>
|
||||
/// This class is responsible for parsing a callstack string into
|
||||
/// a list of StackFrame objects and providing the deminified version
|
||||
/// of the stack frame.
|
||||
/// </summary>
|
||||
/// <param name="sourceMapProvider">Consumers of the API should implement this interface, which provides the source map for a given JavaScript file. Throws ArgumentNullException if the parameter is set to null.</param>
|
||||
/// <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, sourceMapProvider), new FunctionMapConsumer()), new StackTraceParser())
|
||||
{
|
||||
if (sourceMapProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sourceMapProvider));
|
||||
}
|
||||
|
||||
if (generatedCodeProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(generatedCodeProvider));
|
||||
}
|
||||
}
|
||||
|
||||
internal StackTraceDeminifier(IStackFrameDeminifier stackFrameDeminifier, IStackTraceParser stackTraceParser)
|
||||
{
|
||||
_stackFrameDeminifier = stackFrameDeminifier;
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
<Compile Include="StackTraceDeminifierUnitTests.cs" />
|
||||
<Compile Include="StackTraceParserUnitTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StackFrameDeminifierUnitTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\SourceMapToolkit.CallstackDeminifier\SourcemapToolkit.CallstackDeminifier.csproj">
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
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)
|
||||
{
|
||||
if (sourceMapStore == null)
|
||||
{
|
||||
sourceMapStore = MockRepository.GenerateStrictMock<ISourceMapStore>();
|
||||
}
|
||||
|
||||
if (functionMapStore == null)
|
||||
{
|
||||
functionMapStore = MockRepository.GenerateStrictMock<IFunctionMapStore>();
|
||||
}
|
||||
|
||||
if (functionMapConsumer == null)
|
||||
{
|
||||
functionMapConsumer = MockRepository.GenerateStrictMock<IFunctionMapConsumer>();
|
||||
}
|
||||
|
||||
return new StackFrameDeminifier(sourceMapStore, functionMapStore, functionMapConsumer);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void DeminifyStackFrame_NullInputStackFrame_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
IStackFrameDeminifier stackFrameDeminifier = GetStackFrameDeminifierWithMockDependencies();
|
||||
StackFrame stackFrame = null;
|
||||
|
||||
// Act
|
||||
StackFrame deminifiedStackFrame = stackFrameDeminifier.DeminifyStackFrame(stackFrame);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ExtractFrameInformationFromSourceMap_HasMatchingGeneratedPositionMapping_ReturnsStackFrameWithSourcePositionAndFileName()
|
||||
{
|
||||
// Arrange
|
||||
FunctionMapEntry functionMapEntry = null;
|
||||
SourcePosition generatedSourcePosition = new SourcePosition
|
||||
{
|
||||
ZeroBasedColumnNumber = 25,
|
||||
ZeroBasedLineNumber = 85
|
||||
};
|
||||
|
||||
SourceMap sourceMap = MockRepository.GenerateStub<SourceMap>();
|
||||
sourceMap.Stub(x => x.GetMappingEntryForGeneratedSourcePosition(generatedSourcePosition)).Return(new MappingEntry
|
||||
{
|
||||
OriginalSourcePosition = new SourcePosition { ZeroBasedColumnNumber = 10, ZeroBasedLineNumber = 20 }
|
||||
});
|
||||
|
||||
// Act
|
||||
StackFrame deminifiedStackFrame = StackFrameDeminifier.ExtractFrameInformationFromSourceMap(functionMapEntry, sourceMap, generatedSourcePosition);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(10, deminifiedStackFrame.SourcePosition.ZeroBasedColumnNumber);
|
||||
Assert.AreEqual(20, deminifiedStackFrame.SourcePosition.ZeroBasedLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,8 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
|
|||
ISourceCodeProvider sourceCodeProvider = MockRepository.GenerateStrictMock<ISourceCodeProvider>();
|
||||
sourceCodeProvider.Stub(x => x.GetSourceCode("http://localhost:11323/crashcauser.js")).Return(UnitTestUtils.StreamReaderFromString(GeneratedCodeString));
|
||||
|
||||
return new StackTraceDeminifier(sourceMapProvider, sourceCodeProvider);
|
||||
StackTraceDeminfierFactory stackTraceDeminfierFactory = new StackTraceDeminfierFactory();
|
||||
return stackTraceDeminfierFactory.GetStackTraceDeminfier(sourceMapProvider, sourceCodeProvider);
|
||||
}
|
||||
|
||||
private void ValidateDeminifyStackTraceResults(DeminifyStackTraceResult results)
|
||||
|
|
|
@ -18,8 +18,9 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
|
|||
ISourceCodeProvider sourceCodeProvider = MockRepository.GenerateStrictMock<ISourceCodeProvider>();
|
||||
sourceCodeProvider.Stub(x => x.GetSourceCode("http://localhost:11323/crashcauser.min.js")).Return(UnitTestUtils.StreamReaderFromString(GeneratedCodeString));
|
||||
|
||||
return new StackTraceDeminifier(sourceMapProvider, sourceCodeProvider);
|
||||
}
|
||||
StackTraceDeminfierFactory stackTraceDeminfierFactory = new StackTraceDeminfierFactory();
|
||||
return stackTraceDeminfierFactory.GetStackTraceDeminfier(sourceMapProvider, sourceCodeProvider);
|
||||
}
|
||||
|
||||
private static void ValidateDeminifyStackTraceResults(DeminifyStackTraceResult results)
|
||||
{
|
||||
|
|
|
@ -8,30 +8,6 @@ namespace SourcemapToolkit.CallstackDeminifier.UnitTests
|
|||
[TestClass]
|
||||
public class StackTraceDeminifierUnitTests
|
||||
{
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void StackTraceDeminifier_NullSourceMapProvider_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
ISourceCodeProvider sourceCodeProvider = MockRepository.GenerateStrictMock<ISourceCodeProvider>();
|
||||
ISourceMapProvider sourceMapProvider = null;
|
||||
|
||||
// Act
|
||||
StackTraceDeminifier stackTraceDeminifier = new StackTraceDeminifier(sourceMapProvider, sourceCodeProvider);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void StackTraceDeminifier_NullSourceCodeProvider_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
ISourceCodeProvider sourceCodeProvider = null;
|
||||
ISourceMapProvider sourceMapProvider = MockRepository.GenerateStrictMock<ISourceMapProvider>();
|
||||
|
||||
// Act
|
||||
StackTraceDeminifier stackTraceDeminifier = new StackTraceDeminifier(sourceMapProvider, sourceCodeProvider);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeminifyStackTrace_UnableToParseStackTraceString_ReturnsEmptyList()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче