// 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; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Moq; using Xunit; using Mvc1_X = Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X; using MvcLatest = Microsoft.AspNetCore.Mvc.Razor.Extensions; namespace Microsoft.VisualStudio.Editor.Razor { public class DefaultProjectEngineFactoryServiceTest { public DefaultProjectEngineFactoryServiceTest() { Project project = null; Workspace = TestWorkspace.Create(workspace => { var info = ProjectInfo.Create(ProjectId.CreateNewId("Test"), VersionStamp.Default, "Test", "Test", LanguageNames.CSharp, filePath: "/TestPath/SomePath/Test.csproj"); project = workspace.CurrentSolution.AddProject(info).GetProject(info.Id); }); WorkspaceProject = project; HostProject_For_1_0 = new HostProject("/TestPath/SomePath/Test.csproj", FallbackRazorConfiguration.MVC_1_0); HostProject_For_1_1 = new HostProject("/TestPath/SomePath/Test.csproj", FallbackRazorConfiguration.MVC_1_1); HostProject_For_2_0 = new HostProject("/TestPath/SomePath/Test.csproj", FallbackRazorConfiguration.MVC_2_0); HostProject_For_2_1 = new HostProject( "/TestPath/SomePath/Test.csproj", new ProjectSystemRazorConfiguration(RazorLanguageVersion.Version_2_1, "MVC-2.1", Array.Empty())); HostProject_For_UnknownConfiguration = new HostProject( "/TestPath/SomePath/Test.csproj", new ProjectSystemRazorConfiguration(RazorLanguageVersion.Version_2_1, "Blazor-0.1", Array.Empty())); CustomFactories = new Lazy[] { new Lazy( () => new LegacyProjectEngineFactory_1_0(), typeof(LegacyProjectEngineFactory_1_0).GetCustomAttribute()), new Lazy( () => new LegacyProjectEngineFactory_1_1(), typeof(LegacyProjectEngineFactory_1_1).GetCustomAttribute()), new Lazy( () => new LegacyProjectEngineFactory_2_0(), typeof(LegacyProjectEngineFactory_2_0).GetCustomAttribute()), new Lazy( () => new LegacyProjectEngineFactory_2_1(), typeof(LegacyProjectEngineFactory_2_1).GetCustomAttribute()), }; FallbackFactory = new FallbackProjectEngineFactory(); } private Lazy[] CustomFactories { get; } private IFallbackProjectEngineFactory FallbackFactory { get; } private HostProject HostProject_For_1_0 { get; } private HostProject HostProject_For_1_1 { get; } private HostProject HostProject_For_2_0 { get; } private HostProject HostProject_For_2_1 { get; } private HostProject HostProject_For_UnknownConfiguration { get; } // We don't actually look at the project, we rely on the ProjectStateManager private Project WorkspaceProject { get; } private Workspace Workspace { get; } [Fact] public void Create_CreatesDesignTimeTemplateEngine_ForVersion2_1() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); projectManager.HostProjectAdded(HostProject_For_2_1); projectManager.WorkspaceProjectAdded(WorkspaceProject); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/SomePath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); } [Fact] public void Create_CreatesDesignTimeTemplateEngine_ForVersion2_0() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); projectManager.HostProjectAdded(HostProject_For_2_0); projectManager.WorkspaceProjectAdded(WorkspaceProject); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/SomePath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); } [Fact] public void Create_CreatesTemplateEngine_ForVersion1_1() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); projectManager.HostProjectAdded(HostProject_For_1_1); projectManager.WorkspaceProjectAdded(WorkspaceProject); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/SomePath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); } [Fact] public void Create_DoesNotSupportViewComponentTagHelpers_ForVersion1_0() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); projectManager.HostProjectAdded(HostProject_For_1_0); projectManager.WorkspaceProjectAdded(WorkspaceProject); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/SomePath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); } [Fact] public void Create_UnknownProject_UsesVersion2_0() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/DifferentPath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); Assert.Single(engine.Engine.Features.OfType()); } [Fact] public void Create_ForUnknownConfiguration_UsesFallbackFactory() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace); projectManager.HostProjectAdded(HostProject_For_UnknownConfiguration); projectManager.WorkspaceProjectAdded(WorkspaceProject); var factoryService = new DefaultProjectEngineFactoryService(projectManager, FallbackFactory, CustomFactories); // Act var engine = factoryService.Create("/TestPath/SomePath/", b => { b.Features.Add(new MyCoolNewFeature()); }); // Assert Assert.Single(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); Assert.Empty(engine.Engine.Features.OfType()); } private class MyCoolNewFeature : IRazorEngineFeature { public RazorEngine Engine { get; set; } } private class TestProjectSnapshotManager : DefaultProjectSnapshotManager { public TestProjectSnapshotManager(Workspace workspace) : base( Mock.Of(), Mock.Of(), Mock.Of(), Enumerable.Empty(), workspace) { } } } }