diff --git a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets index 3af2791f18..d35c6c26b8 100644 --- a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets +++ b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets @@ -7,6 +7,7 @@ <_RazorDebugSymbolsIntermediatePath Condition="'$(DebugSymbols)'=='true' and '$(DebugType)'!='' and '$(DebugType)'!='none' and '$(DebugType)'!='embedded'" Include="$(IntermediateOutputPath)$(RazorTargetName).pdb" /> + <_RazorDebugSymbolsOutputPath Include="@(_RazorDebugSymbolsIntermediatePath->'$(OutDir)%(Filename)%(Extension)')" /> $"File: '{FilePath}' was found, but should not exist."; } + + private class NuspecException : MSBuildXunitException + { + public NuspecException(MSBuildResult result, string filePath, string content, string expected) + : base(result) + { + FilePath = filePath; + Content = content; + Expected = expected; + } + + public string Content { get; } + + public string Expected { get; } + + public string FilePath { get; } + + protected override string Heading + { + get + { + return + $"nuspec: '{FilePath}' did not contain the expected content." + Environment.NewLine + + Environment.NewLine + + $"expected: {Expected}" + Environment.NewLine + + Environment.NewLine + + $"actual: {Content}"; + } + } + } + + private class NupkgFileMissingException : MSBuildXunitException + { + public NupkgFileMissingException(MSBuildResult result, string nupkgPath, string filePath) + : base(result) + { + NupkgPath = nupkgPath; + FilePath = filePath; + } + + public string FilePath { get; } + + public string NupkgPath { get; } + + protected override string Heading => $"File: '{FilePath}' was not found was not found in {NupkgPath}."; + } } } diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/BuildIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/BuildIntegrationTest.cs index 92f9691a02..86d32aff9f 100644 --- a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/BuildIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/BuildIntegrationTest.cs @@ -29,7 +29,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.BuildPassed(result); Assert.FileExists(result, OutputPath, "SimpleMvc.dll"); + Assert.FileExists(result, OutputPath, "SimpleMvc.pdb"); Assert.FileExists(result, OutputPath, "SimpleMvc.PrecompiledViews.dll"); + Assert.FileExists(result, OutputPath, "SimpleMvc.PrecompiledViews.pdb"); if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Darwin) { @@ -114,5 +116,18 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.pdb"); Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.PrecompiledViews.pdb"); } + + [Fact] + [InitializeTestProject("AppWithP2PReference", "ClassLibrary")] + public async Task Build_WithP2P_CopiesRazorAssembly() + { + var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true"); + + Assert.BuildPassed(result); + Assert.FileExists(result, OutputPath, "AppWithP2PReference.dll"); + Assert.FileExists(result, OutputPath, "AppWithP2PReference.PrecompiledViews.dll"); + Assert.FileExists(result, OutputPath, "ClassLibrary.dll"); + Assert.FileExists(result, OutputPath, "ClassLibrary.PrecompiledViews.dll"); + } } } diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/InitializeTestProjectAttribute.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/InitializeTestProjectAttribute.cs index 18b93aa99c..5660c4aefa 100644 --- a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/InitializeTestProjectAttribute.cs +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/InitializeTestProjectAttribute.cs @@ -10,10 +10,12 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests public class InitializeTestProjectAttribute : BeforeAfterTestAttribute { private readonly string _projectName; + private readonly string[] _additionalProjects; - public InitializeTestProjectAttribute(string projectName) + public InitializeTestProjectAttribute(string projectName, params string[] additionalProjects) { _projectName = projectName; + _additionalProjects = additionalProjects; } public override void Before(MethodInfo methodUnderTest) @@ -23,7 +25,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests throw new InvalidOperationException($"This should be used on a class derived from {typeof(MSBuildIntegrationTestBase)}"); } - MSBuildIntegrationTestBase.Project = ProjectDirectory.Create(_projectName); + MSBuildIntegrationTestBase.Project = ProjectDirectory.Create(_projectName, _additionalProjects); } public override void After(MethodInfo methodUnderTest) diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/PackIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/PackIntegrationTest.cs new file mode 100644 index 0000000000..c980437f71 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/PackIntegrationTest.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests +{ + public class PackIntegrationTest : MSBuildIntegrationTestBase + { + [Fact] + [InitializeTestProject("ClassLibrary")] + public async Task Pack_Wortks_IncludesRazorAssembly() + { + var result = await DotnetMSBuild("Pack", "/p:RazorCompileOnBuild=true"); + + Assert.BuildPassed(result); + + Assert.FileExists(result, OutputPath, "ClassLibrary.dll"); + Assert.FileExists(result, OutputPath, "ClassLibrary.PrecompiledViews.dll"); + + Assert.NuspecContains( + result, + Path.Combine("obj", Configuration, "ClassLibrary.1.0.0.nuspec"), + $""); + + Assert.NupkgContains( + result, + Path.Combine("bin", Configuration, "ClassLibrary.1.0.0.nupkg"), + Path.Combine("lib", "netcoreapp2.0", "ClassLibrary.PrecompiledViews.dll")); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ProjectDirectory.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ProjectDirectory.cs index 02f7efbf07..8b117f9dff 100644 --- a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ProjectDirectory.cs +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ProjectDirectory.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests public bool PreserveWorkingDirectory { get; set; } #endif - public static ProjectDirectory Create(string projectName) + public static ProjectDirectory Create(string projectName, string[] additionalProjects) { var destinationPath = Path.Combine(Path.GetTempPath(), "Razor", Path.GetRandomFileName()); Directory.CreateDirectory(destinationPath); @@ -38,21 +38,26 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests throw new InvalidOperationException("Could not find solution root."); } - var projectRoot = Path.Combine(solutionRoot, "test", "testapps", projectName); - if (!Directory.Exists(projectRoot)) - { - throw new InvalidOperationException($"Could not find project at '{projectRoot}'"); - } - var binariesRoot = Path.GetDirectoryName(typeof(ProjectDirectory).Assembly.Location); - CopyDirectory(new DirectoryInfo(projectRoot), new DirectoryInfo(destinationPath)); + foreach (var project in new string[] { projectName, }.Concat(additionalProjects)) + { + var projectRoot = Path.Combine(solutionRoot, "test", "testapps", project); + if (!Directory.Exists(projectRoot)) + { + throw new InvalidOperationException($"Could not find project at '{projectRoot}'"); + } - CreateDirectoryProps(projectRoot, binariesRoot, destinationPath); - CreateDirectoryTargets(destinationPath); + var projectDestination = Path.Combine(destinationPath, project); + Directory.CreateDirectory(projectDestination); + CopyDirectory(new DirectoryInfo(projectRoot), new DirectoryInfo(projectDestination)); + CreateDirectoryProps(projectRoot, binariesRoot, destinationPath); + CreateDirectoryTargets(destinationPath); + } + CopyGlobalJson(solutionRoot, destinationPath); - return new ProjectDirectory(destinationPath); + return new ProjectDirectory(destinationPath, Path.Combine(destinationPath, projectName)); } catch { @@ -127,22 +132,25 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests } } - private ProjectDirectory(string directoryPath) + private ProjectDirectory(string solutionPath, string directoryPath) { + SolutionPath = solutionPath; DirectoryPath = directoryPath; } public string DirectoryPath { get; } + public string SolutionPath { get; } + public void Dispose() { if (PreserveWorkingDirectory) { - Console.WriteLine($"Skipping deletion of working directory {DirectoryPath}"); + Console.WriteLine($"Skipping deletion of working directory {SolutionPath}"); } else { - CleanupDirectory(DirectoryPath); + CleanupDirectory(SolutionPath); } } diff --git a/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj b/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj new file mode 100644 index 0000000000..5238c1ca01 --- /dev/null +++ b/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj @@ -0,0 +1,23 @@ + + + netcoreapp2.0 + + + + + + + + + + + + + + + + + + + + diff --git a/test/testapps/AppWithP2PReference/Models/ErrorViewModel.cs b/test/testapps/AppWithP2PReference/Models/ErrorViewModel.cs new file mode 100644 index 0000000000..ecc6e00ab2 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace AppWithP2PReference.Models +{ + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} \ No newline at end of file diff --git a/test/testapps/AppWithP2PReference/Program.cs b/test/testapps/AppWithP2PReference/Program.cs new file mode 100644 index 0000000000..dc3ac4e250 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Program.cs @@ -0,0 +1,13 @@ + +namespace AppWithP2PReference +{ + public class Program + { + public static void Main(string[] args) + { + // Just make sure we have a reference to the MvcShim + var t = typeof(Microsoft.AspNetCore.Mvc.IActionResult); + System.Console.WriteLine(t.FullName); + } + } +} diff --git a/test/testapps/AppWithP2PReference/Views/Home/About.cshtml b/test/testapps/AppWithP2PReference/Views/Home/About.cshtml new file mode 100644 index 0000000000..3674e37a86 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

diff --git a/test/testapps/AppWithP2PReference/Views/Home/Contact.cshtml b/test/testapps/AppWithP2PReference/Views/Home/Contact.cshtml new file mode 100644 index 0000000000..a11a1867cf --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/Home/Contact.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/test/testapps/AppWithP2PReference/Views/Home/Index.cshtml b/test/testapps/AppWithP2PReference/Views/Home/Index.cshtml new file mode 100644 index 0000000000..00afab6a0c --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/Home/Index.cshtml @@ -0,0 +1,108 @@ +@{ + ViewData["Title"] = "Home Page"; +} + + + + diff --git a/test/testapps/AppWithP2PReference/Views/Shared/Error.cshtml b/test/testapps/AppWithP2PReference/Views/Shared/Error.cshtml new file mode 100644 index 0000000000..ec2ea6bd03 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/Shared/Error.cshtml @@ -0,0 +1,22 @@ +@model ErrorViewModel +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +@if (Model.ShowRequestId) +{ +

+ Request ID: @Model.RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

diff --git a/test/testapps/AppWithP2PReference/Views/Shared/_ValidationScriptsPartial.cshtml b/test/testapps/AppWithP2PReference/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..a699aafa97 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/test/testapps/AppWithP2PReference/Views/_ViewImports.cshtml b/test/testapps/AppWithP2PReference/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..601a427791 --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using AppWithP2PReference +@using AppWithP2PReference.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/test/testapps/AppWithP2PReference/Views/_ViewStart.cshtml b/test/testapps/AppWithP2PReference/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/test/testapps/AppWithP2PReference/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/test/testapps/ClassLibrary/Class1.cs b/test/testapps/ClassLibrary/Class1.cs new file mode 100644 index 0000000000..62a93d35fc --- /dev/null +++ b/test/testapps/ClassLibrary/Class1.cs @@ -0,0 +1,7 @@ +namespace ClassLibrary +{ + public class Class1 + { + // Just here so this assembly has some compilation inputs. + } +} \ No newline at end of file diff --git a/test/testapps/ClassLibrary/ClassLibrary.csproj b/test/testapps/ClassLibrary/ClassLibrary.csproj new file mode 100644 index 0000000000..db0fa4a101 --- /dev/null +++ b/test/testapps/ClassLibrary/ClassLibrary.csproj @@ -0,0 +1,23 @@ + + + netcoreapp2.0 + + + + + + + + + + + + + + + + + + + + diff --git a/test/testapps/ClassLibrary/Views/Shared/_Layout.cshtml b/test/testapps/ClassLibrary/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..1a9473e464 --- /dev/null +++ b/test/testapps/ClassLibrary/Views/Shared/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimpleMvc + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimpleMvc

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/test/testapps/ClassLibrary/Views/_ViewImports.cshtml b/test/testapps/ClassLibrary/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..1dbbe8a4c2 --- /dev/null +++ b/test/testapps/ClassLibrary/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using ClassLibrary +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/test/testapps/SimpleMvc/SimpleMvc.csproj b/test/testapps/SimpleMvc/SimpleMvc.csproj index c25c6bb89c..f2a93d60cb 100644 --- a/test/testapps/SimpleMvc/SimpleMvc.csproj +++ b/test/testapps/SimpleMvc/SimpleMvc.csproj @@ -4,9 +4,9 @@ - - - + + + diff --git a/test/testapps/SimplePages/SimplePages.csproj b/test/testapps/SimplePages/SimplePages.csproj index c25c6bb89c..f2a93d60cb 100644 --- a/test/testapps/SimplePages/SimplePages.csproj +++ b/test/testapps/SimplePages/SimplePages.csproj @@ -4,9 +4,9 @@ - - - + + +