Log messages to DiagnosticListener in addition to page instrumentation
Fixes #3281
This commit is contained in:
parent
cef4a66479
commit
d17db92e19
|
|
@ -84,6 +84,12 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IPageExecutionContext PageExecutionContext { get; set; }
|
public IPageExecutionContext PageExecutionContext { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a <see cref="DiagnosticSource.DiagnosticSource"/> instance used to instrument the page execution.
|
||||||
|
/// </summary>
|
||||||
|
[RazorInject]
|
||||||
|
public DiagnosticSource DiagnosticSource { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="TextWriter"/> that the page is writing output to.
|
/// Gets the <see cref="TextWriter"/> that the page is writing output to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -1063,12 +1069,41 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
||||||
public void BeginContext(int position, int length, bool isLiteral)
|
public void BeginContext(int position, int length, bool isLiteral)
|
||||||
{
|
{
|
||||||
|
const string BeginContextEvent = "Microsoft.AspNet.Mvc.Razor.BeginInstrumentationContext";
|
||||||
|
|
||||||
PageExecutionContext?.BeginContext(position, length, isLiteral);
|
PageExecutionContext?.BeginContext(position, length, isLiteral);
|
||||||
|
if (DiagnosticSource?.IsEnabled(BeginContextEvent) == true)
|
||||||
|
{
|
||||||
|
DiagnosticSource.Write(
|
||||||
|
BeginContextEvent,
|
||||||
|
new
|
||||||
|
{
|
||||||
|
httpContext = Context,
|
||||||
|
path = Path,
|
||||||
|
isPartial = IsPartial,
|
||||||
|
position = position,
|
||||||
|
length = length,
|
||||||
|
isLiteral = isLiteral,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndContext()
|
public void EndContext()
|
||||||
{
|
{
|
||||||
|
const string EndContextEvent = "Microsoft.AspNet.Mvc.Razor.EndInstrumentationContext";
|
||||||
|
|
||||||
PageExecutionContext?.EndContext();
|
PageExecutionContext?.EndContext();
|
||||||
|
if (DiagnosticSource?.IsEnabled(EndContextEvent) == true)
|
||||||
|
{
|
||||||
|
DiagnosticSource.Write(
|
||||||
|
EndContextEvent,
|
||||||
|
new
|
||||||
|
{
|
||||||
|
httpContext = Context,
|
||||||
|
path = Path,
|
||||||
|
isPartial = IsPartial,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Http.Internal;
|
||||||
using Microsoft.AspNet.Mvc.Abstractions;
|
using Microsoft.AspNet.Mvc.Abstractions;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Razor.Internal;
|
using Microsoft.AspNet.Mvc.Razor.Internal;
|
||||||
|
|
@ -15,6 +17,7 @@ using Microsoft.AspNet.Mvc.ViewEngines;
|
||||||
using Microsoft.AspNet.Mvc.ViewFeatures;
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
|
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.WebEncoders.Testing;
|
using Microsoft.Extensions.WebEncoders.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -33,24 +36,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
var helper = Mock.Of<IHtmlHelper<object>>();
|
||||||
var htmlEncoder = new HtmlTestEncoder();
|
var htmlEncoder = new HtmlTestEncoder();
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var diagnosticSource = new DiagnosticListener("Microsoft.AspNet");
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
|
var serviceProvider = new ServiceCollection()
|
||||||
.Returns(myService);
|
.AddInstance(myService)
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
|
.AddInstance(helper)
|
||||||
.Returns(helper);
|
.AddInstance<HtmlEncoder>(htmlEncoder)
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(HtmlEncoder)))
|
.AddInstance<DiagnosticSource>(diagnosticSource)
|
||||||
.Returns(htmlEncoder);
|
.BuildServiceProvider();
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new DefaultHttpContext
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
{
|
||||||
.Returns(serviceProvider.Object);
|
RequestServices = serviceProvider
|
||||||
|
};
|
||||||
|
|
||||||
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewContext = new ViewContext(actionContext,
|
var viewContext = new ViewContext(
|
||||||
Mock.Of<IView>(),
|
actionContext,
|
||||||
new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
Mock.Of<IView>(),
|
||||||
Mock.Of<ITempDataDictionary>(),
|
new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||||
TextWriter.Null,
|
Mock.Of<ITempDataDictionary>(),
|
||||||
new HtmlHelperOptions());
|
TextWriter.Null,
|
||||||
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
activator.Activate(instance, viewContext);
|
activator.Activate(instance, viewContext);
|
||||||
|
|
@ -59,6 +64,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
Assert.Same(helper, instance.Html);
|
Assert.Same(helper, instance.Html);
|
||||||
Assert.Same(myService, instance.MyService);
|
Assert.Same(myService, instance.MyService);
|
||||||
Assert.Same(viewContext, myService.ViewContext);
|
Assert.Same(viewContext, myService.ViewContext);
|
||||||
|
Assert.Same(diagnosticSource, instance.DiagnosticSource);
|
||||||
Assert.Null(instance.MyService2);
|
Assert.Null(instance.MyService2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,25 +78,23 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
var helper = Mock.Of<IHtmlHelper<object>>();
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var serviceProvider = new Mock<IServiceProvider>();
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new DefaultHttpContext
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
{
|
||||||
.Returns(serviceProvider.Object);
|
RequestServices = new ServiceCollection().BuildServiceProvider()
|
||||||
|
};
|
||||||
|
|
||||||
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewContext = new ViewContext(actionContext,
|
var viewContext = new ViewContext(
|
||||||
Mock.Of<IView>(),
|
actionContext,
|
||||||
new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
Mock.Of<IView>(),
|
||||||
Mock.Of<ITempDataDictionary>(),
|
new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||||
TextWriter.Null,
|
Mock.Of<ITempDataDictionary>(),
|
||||||
new HtmlHelperOptions());
|
TextWriter.Null,
|
||||||
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
// Act and Assert
|
// Act and Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => activator.Activate(instance, viewContext));
|
var ex = Assert.Throws<InvalidOperationException>(() => activator.Activate(instance, viewContext));
|
||||||
var message = string.Format(CultureInfo.InvariantCulture,
|
var message = $"View of type '{instance.GetType()}' cannot be activated by '{typeof(RazorPageActivator)}'.";
|
||||||
"View of type '{0}' cannot be activated by '{1}'.",
|
|
||||||
instance.GetType().FullName,
|
|
||||||
typeof(RazorPageActivator).FullName);
|
|
||||||
|
|
||||||
Assert.Equal(message, ex.Message);
|
Assert.Equal(message, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,28 +108,29 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
var helper = Mock.Of<IHtmlHelper<object>>();
|
||||||
var htmlEncoder = new HtmlTestEncoder();
|
var htmlEncoder = new HtmlTestEncoder();
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var serviceProvider = new ServiceCollection()
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
|
.AddInstance(myService)
|
||||||
.Returns(myService);
|
.AddInstance(helper)
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
|
.AddInstance<HtmlEncoder>(htmlEncoder)
|
||||||
.Returns(helper);
|
.AddInstance<DiagnosticSource>(new DiagnosticListener("Microsoft.Aspnet.Mvc"))
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(HtmlEncoder)))
|
.BuildServiceProvider();
|
||||||
.Returns(htmlEncoder);
|
var httpContext = new DefaultHttpContext
|
||||||
var httpContext = new Mock<HttpContext>();
|
{
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
RequestServices = serviceProvider
|
||||||
.Returns(serviceProvider.Object);
|
};
|
||||||
|
|
||||||
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewData = new ViewDataDictionary<object>(new EmptyModelMetadataProvider())
|
var viewData = new ViewDataDictionary<object>(new EmptyModelMetadataProvider())
|
||||||
{
|
{
|
||||||
Model = new MyModel()
|
Model = new MyModel()
|
||||||
};
|
};
|
||||||
var viewContext = new ViewContext(actionContext,
|
var viewContext = new ViewContext(
|
||||||
Mock.Of<IView>(),
|
actionContext,
|
||||||
viewData,
|
Mock.Of<IView>(),
|
||||||
Mock.Of<ITempDataDictionary>(),
|
viewData,
|
||||||
TextWriter.Null,
|
Mock.Of<ITempDataDictionary>(),
|
||||||
new HtmlHelperOptions());
|
TextWriter.Null,
|
||||||
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
activator.Activate(instance, viewContext);
|
activator.Activate(instance, viewContext);
|
||||||
|
|
@ -143,28 +148,29 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
var helper = Mock.Of<IHtmlHelper<object>>();
|
||||||
var htmlEncoder = new HtmlTestEncoder();
|
var htmlEncoder = new HtmlTestEncoder();
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var serviceProvider = new ServiceCollection()
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
|
.AddInstance(myService)
|
||||||
.Returns(myService);
|
.AddInstance(helper)
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
|
.AddInstance<HtmlEncoder>(htmlEncoder)
|
||||||
.Returns(helper);
|
.AddInstance<DiagnosticSource>(new DiagnosticListener("Microsoft.Aspnet.Mvc"))
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(HtmlEncoder)))
|
.BuildServiceProvider();
|
||||||
.Returns(htmlEncoder);
|
var httpContext = new DefaultHttpContext
|
||||||
var httpContext = new Mock<HttpContext>();
|
{
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
RequestServices = serviceProvider
|
||||||
.Returns(serviceProvider.Object);
|
};
|
||||||
|
|
||||||
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewData = new ViewDataDictionary<MyModel>(new EmptyModelMetadataProvider())
|
var viewData = new ViewDataDictionary<MyModel>(new EmptyModelMetadataProvider())
|
||||||
{
|
{
|
||||||
Model = new MyModel()
|
Model = new MyModel()
|
||||||
};
|
};
|
||||||
var viewContext = new ViewContext(actionContext,
|
var viewContext = new ViewContext(
|
||||||
Mock.Of<IView>(),
|
actionContext,
|
||||||
viewData,
|
Mock.Of<IView>(),
|
||||||
Mock.Of<ITempDataDictionary>(),
|
viewData,
|
||||||
TextWriter.Null,
|
Mock.Of<ITempDataDictionary>(),
|
||||||
new HtmlHelperOptions());
|
TextWriter.Null,
|
||||||
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
activator.Activate(instance, viewContext);
|
activator.Activate(instance, viewContext);
|
||||||
|
|
@ -182,25 +188,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
var helper = Mock.Of<IHtmlHelper<object>>();
|
||||||
var htmlEncoder = new HtmlTestEncoder();
|
var htmlEncoder = new HtmlTestEncoder();
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var serviceProvider = new ServiceCollection()
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
|
.AddInstance(myService)
|
||||||
.Returns(myService);
|
.AddInstance(helper)
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
|
.AddInstance<HtmlEncoder>(htmlEncoder)
|
||||||
.Returns(helper);
|
.AddInstance<DiagnosticSource>(new DiagnosticListener("Microsoft.AspNet.Mvc"))
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(HtmlEncoder)))
|
.BuildServiceProvider();
|
||||||
.Returns(htmlEncoder);
|
var httpContext = new DefaultHttpContext
|
||||||
var httpContext = new Mock<HttpContext>();
|
{
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
RequestServices = serviceProvider
|
||||||
.Returns(serviceProvider.Object);
|
};
|
||||||
|
|
||||||
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewData = new ViewDataDictionary<object>(new EmptyModelMetadataProvider());
|
var viewData = new ViewDataDictionary<object>(new EmptyModelMetadataProvider());
|
||||||
var viewContext = new ViewContext(actionContext,
|
var viewContext = new ViewContext(
|
||||||
Mock.Of<IView>(),
|
actionContext,
|
||||||
viewData,
|
Mock.Of<IView>(),
|
||||||
Mock.Of<ITempDataDictionary>(),
|
viewData,
|
||||||
TextWriter.Null,
|
Mock.Of<ITempDataDictionary>(),
|
||||||
new HtmlHelperOptions());
|
TextWriter.Null,
|
||||||
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
activator.Activate(instance, viewContext);
|
activator.Activate(instance, viewContext);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -745,6 +746,231 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
context.Verify();
|
context.Verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(false)]
|
||||||
|
[InlineData(true)]
|
||||||
|
public async Task WriteAttribute_CallsBeginAndEndContext_OnPageExecutionListenerContext(bool isPartial)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "path-to-page";
|
||||||
|
var page = CreatePage(p =>
|
||||||
|
{
|
||||||
|
p.HtmlEncoder = new HtmlTestEncoder();
|
||||||
|
p.BeginWriteAttribute("href", "prefix", 0, "suffix", 34, 2);
|
||||||
|
p.WriteAttributeValue("prefix", 0, "attr1-value", 8, 14, true);
|
||||||
|
p.WriteAttributeValue("prefix2", 22, "attr2", 29, 5, false);
|
||||||
|
p.EndWriteAttribute();
|
||||||
|
});
|
||||||
|
page.Path = path;
|
||||||
|
page.IsPartial = isPartial;
|
||||||
|
var adapter = new TestDiagnosticListener();
|
||||||
|
var diagnosticListener = new DiagnosticListener("Microsoft.AspNet.Mvc.Razor");
|
||||||
|
diagnosticListener.SubscribeWithAdapter(adapter);
|
||||||
|
page.DiagnosticSource = diagnosticListener;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await page.ExecuteAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Func<object, TestDiagnosticListener.BeginPageInstrumentationData> assertStartEvent = data =>
|
||||||
|
{
|
||||||
|
var beginEvent = Assert.IsType<TestDiagnosticListener.BeginPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(beginEvent.HttpContext);
|
||||||
|
Assert.Equal(path, beginEvent.Path);
|
||||||
|
Assert.Equal(isPartial, beginEvent.IsPartial);
|
||||||
|
|
||||||
|
return beginEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Action<object> assertEndEvent = data =>
|
||||||
|
{
|
||||||
|
var endEvent = Assert.IsType<TestDiagnosticListener.EndPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(endEvent.HttpContext);
|
||||||
|
Assert.Equal(path, endEvent.Path);
|
||||||
|
Assert.Equal(isPartial, endEvent.IsPartial);
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.Collection(adapter.PageInstrumentationData,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(0, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(0, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(8, beginEvent.Position);
|
||||||
|
Assert.Equal(14, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(22, beginEvent.Position);
|
||||||
|
Assert.Equal(7, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(29, beginEvent.Position);
|
||||||
|
Assert.Equal(5, beginEvent.Length);
|
||||||
|
Assert.False(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(34, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(false)]
|
||||||
|
[InlineData(true)]
|
||||||
|
public async Task WriteAttribute_WithBoolValue_CallsBeginAndEndContext_OnPageExecutionListenerContext(bool isPartial)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "some-path";
|
||||||
|
var page = CreatePage(p =>
|
||||||
|
{
|
||||||
|
p.HtmlEncoder = new HtmlTestEncoder();
|
||||||
|
p.BeginWriteAttribute("href", "prefix", 0, "suffix", 10, 1);
|
||||||
|
p.WriteAttributeValue("", 6, "true", 6, 4, false);
|
||||||
|
p.EndWriteAttribute();
|
||||||
|
});
|
||||||
|
page.Path = path;
|
||||||
|
page.IsPartial = isPartial;
|
||||||
|
var adapter = new TestDiagnosticListener();
|
||||||
|
var diagnosticListener = new DiagnosticListener("Microsoft.AspNet.Mvc.Razor");
|
||||||
|
diagnosticListener.SubscribeWithAdapter(adapter);
|
||||||
|
page.DiagnosticSource = diagnosticListener;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await page.ExecuteAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Func<object, TestDiagnosticListener.BeginPageInstrumentationData> assertStartEvent = data =>
|
||||||
|
{
|
||||||
|
var beginEvent = Assert.IsType<TestDiagnosticListener.BeginPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(beginEvent.HttpContext);
|
||||||
|
Assert.Equal(path, beginEvent.Path);
|
||||||
|
Assert.Equal(isPartial, beginEvent.IsPartial);
|
||||||
|
|
||||||
|
return beginEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Action<object> assertEndEvent = data =>
|
||||||
|
{
|
||||||
|
var endEvent = Assert.IsType<TestDiagnosticListener.EndPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(endEvent.HttpContext);
|
||||||
|
Assert.Equal(path, endEvent.Path);
|
||||||
|
Assert.Equal(isPartial, endEvent.IsPartial);
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.Collection(adapter.PageInstrumentationData,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(0, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(6, beginEvent.Position);
|
||||||
|
Assert.Equal(4, beginEvent.Length);
|
||||||
|
Assert.False(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(10, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(false)]
|
||||||
|
[InlineData(true)]
|
||||||
|
public async Task WriteAttribute_CallsBeginAndEndContext_OnPrefixAndSuffixValues(bool isPartial)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "some-path";
|
||||||
|
var page = CreatePage(p =>
|
||||||
|
{
|
||||||
|
p.BeginWriteAttribute("href", "prefix", 0, "tail", 7, 0);
|
||||||
|
p.EndWriteAttribute();
|
||||||
|
});
|
||||||
|
page.Path = path;
|
||||||
|
page.IsPartial = isPartial;
|
||||||
|
var adapter = new TestDiagnosticListener();
|
||||||
|
var diagnosticListener = new DiagnosticListener("Microsoft.AspNet.Mvc.Razor");
|
||||||
|
diagnosticListener.SubscribeWithAdapter(adapter);
|
||||||
|
page.DiagnosticSource = diagnosticListener;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await page.ExecuteAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Func<object, TestDiagnosticListener.BeginPageInstrumentationData> assertStartEvent = data =>
|
||||||
|
{
|
||||||
|
var beginEvent = Assert.IsType<TestDiagnosticListener.BeginPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(beginEvent.HttpContext);
|
||||||
|
Assert.Equal(path, beginEvent.Path);
|
||||||
|
Assert.Equal(isPartial, beginEvent.IsPartial);
|
||||||
|
|
||||||
|
return beginEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Action<object> assertEndEvent = data =>
|
||||||
|
{
|
||||||
|
var endEvent = Assert.IsType<TestDiagnosticListener.EndPageInstrumentationData>(data);
|
||||||
|
Assert.NotNull(endEvent.HttpContext);
|
||||||
|
Assert.Equal(path, endEvent.Path);
|
||||||
|
Assert.Equal(isPartial, endEvent.IsPartial);
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.Collection(adapter.PageInstrumentationData,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(0, beginEvent.Position);
|
||||||
|
Assert.Equal(6, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent,
|
||||||
|
data =>
|
||||||
|
{
|
||||||
|
var beginEvent = assertStartEvent(data);
|
||||||
|
Assert.Equal(7, beginEvent.Position);
|
||||||
|
Assert.Equal(4, beginEvent.Length);
|
||||||
|
Assert.True(beginEvent.IsLiteral);
|
||||||
|
},
|
||||||
|
assertEndEvent);
|
||||||
|
}
|
||||||
|
|
||||||
public static TheoryData AddHtmlAttributeValues_ValueData
|
public static TheoryData AddHtmlAttributeValues_ValueData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,14 @@
|
||||||
"version": "6.0.0-*",
|
"version": "6.0.0-*",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
|
"Microsoft.AspNet.Mvc.TestDiagnosticListener.Sources": {
|
||||||
|
"version": "6.0.0-*",
|
||||||
|
"type": "build"
|
||||||
|
},
|
||||||
"Microsoft.AspNet.Testing": "1.0.0-*",
|
"Microsoft.AspNet.Testing": "1.0.0-*",
|
||||||
"Microsoft.Dnx.Runtime": "1.0.0-*",
|
"Microsoft.Dnx.Runtime": "1.0.0-*",
|
||||||
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
|
||||||
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
string viewName,
|
string viewName,
|
||||||
IProxyView view)
|
IProxyView view)
|
||||||
{
|
{
|
||||||
ViewFound = new OnViewFoundEventData()
|
ViewFound = new OnViewFoundEventData()
|
||||||
{
|
{
|
||||||
ActionContext = actionContext,
|
ActionContext = actionContext,
|
||||||
IsPartial = isPartial,
|
IsPartial = isPartial,
|
||||||
|
|
@ -324,5 +324,68 @@ namespace Microsoft.AspNet.Mvc
|
||||||
View = view
|
View = view
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BeginPageInstrumentationData
|
||||||
|
{
|
||||||
|
public IProxyHttpContext HttpContext { get; set; }
|
||||||
|
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
public bool IsPartial { get; set; }
|
||||||
|
|
||||||
|
public int Position { get; set; }
|
||||||
|
|
||||||
|
public int Length { get; set; }
|
||||||
|
|
||||||
|
public bool IsLiteral { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EndPageInstrumentationData
|
||||||
|
{
|
||||||
|
public IProxyHttpContext HttpContext { get; set; }
|
||||||
|
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
public bool IsPartial { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<object> PageInstrumentationData { get; set; } = new List<object>();
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.Razor.BeginInstrumentationContext")]
|
||||||
|
public virtual void OnBeginPageInstrumentationContext(
|
||||||
|
IProxyHttpContext httpContext,
|
||||||
|
string path,
|
||||||
|
bool isPartial,
|
||||||
|
int position,
|
||||||
|
int length,
|
||||||
|
bool isLiteral)
|
||||||
|
{
|
||||||
|
PageInstrumentationData.Add(new BeginPageInstrumentationData
|
||||||
|
{
|
||||||
|
HttpContext = httpContext,
|
||||||
|
Path = path,
|
||||||
|
IsPartial = isPartial,
|
||||||
|
Position = position,
|
||||||
|
Length = length,
|
||||||
|
IsLiteral = isLiteral,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.Razor.EndInstrumentationContext")]
|
||||||
|
public virtual void OnEndPageInstrumentationContext(
|
||||||
|
IProxyHttpContext httpContext,
|
||||||
|
string path,
|
||||||
|
bool isPartial,
|
||||||
|
int position,
|
||||||
|
int length,
|
||||||
|
bool isLiteral)
|
||||||
|
{
|
||||||
|
PageInstrumentationData.Add(new EndPageInstrumentationData
|
||||||
|
{
|
||||||
|
HttpContext = httpContext,
|
||||||
|
Path = path,
|
||||||
|
IsPartial = isPartial,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue