public void GetOrAdd_UpdatesCache_IfFileExpirationTriggerExpires() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "test content"); using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider)) { var expected1 = new ChunkTree(); var expected2 = new ChunkTree(); // Act 1 var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => expected1); // Assert 1 Assert.Same(expected1, result1); // Act 2 fileProvider.GetChangeToken(path).HasChanged = true; var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected2); // Assert 2 Assert.Same(expected2, result2); } }
public void Compile_ReturnsCompilationFailureWithPathsFromLinePragmas() { // Arrange var viewPath = "some-relative-path"; var fileContent = "test file content"; var content = $@" #line 1 ""{viewPath}"" this should fail"; var applicationEnvironment = PlatformServices.Default.Application; var libraryExporter = CompilationServices.Default.LibraryExporter; var mvcRazorHost = Mock.Of<IMvcRazorHost>(); var fileProvider = new TestFileProvider(); var fileInfo = fileProvider.AddFile(viewPath, fileContent); var compilationService = new RoslynCompilationService( applicationEnvironment, libraryExporter, mvcRazorHost, GetOptions(), GetFileProviderAccessor(fileProvider), NullLoggerFactory.Instance); var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path"); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType<CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(relativeFileInfo.RelativePath, compilationFailure.SourceFilePath); Assert.Equal(fileContent, compilationFailure.SourceFileContent); }
public void GetOrAdd_ReturnsFileNotFoundIfFileWasDeleted() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty<RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected, result1.CompilationResult); // Act 2 // Delete the file from the file system and set it's expiration trigger. fileProvider.DeleteFile(ViewPath); fileProvider.GetTrigger(ViewPath).IsExpired = true; var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.Same(CompilerCacheResult.FileNotFound, result2); Assert.Null(result2.CompilationResult); }
public void Compile_ReturnsCompilationFailureWithPathsFromLinePragmas() { // Arrange var viewPath = "some-relative-path"; var fileContent = "test file content"; var content = $@" #line 1 ""{viewPath}"" this should fail"; var fileProvider = new TestFileProvider(); var fileInfo = fileProvider.AddFile(viewPath, fileContent); var compilationService = new DefaultRoslynCompilationService( GetDependencyContext(), GetOptions(), GetFileProviderAccessor(fileProvider), NullLoggerFactory.Instance); var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path"); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType<CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(relativeFileInfo.RelativePath, compilationFailure.SourceFilePath); Assert.Equal(fileContent, compilationFailure.SourceFileContent); }
public void GetOrAdd_ReturnsFileNotFoundResult_IfFileIsNotFoundInFileSystem() { // Arrange var fileProvider = new TestFileProvider(); var cache = new CompilerCache(fileProvider); // Act var result = cache.GetOrAdd("/some/path", ThrowsIfCalled); // Assert Assert.False(result.Success); }
public void GetInheritedChunks_ReadsChunksFromGlobalFilesInPath() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"Views\accounts\_GlobalImport.cshtml", "@using AccountModels"); fileProvider.AddFile(@"Views\Shared\_GlobalImport.cshtml", "@inject SharedHelper Shared"); fileProvider.AddFile(@"Views\home\_GlobalImport.cshtml", "@using MyNamespace"); fileProvider.AddFile(@"Views\_GlobalImport.cshtml", @"@inject MyHelper<TModel> Helper @inherits MyBaseType @{ Layout = ""test.cshtml""; } "); var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var cache = new DefaultCodeTreeCache(fileProvider); var host = new MvcRazorHost(cache); var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); // Act var codeTrees = utility.GetInheritedCodeTrees(@"Views\home\Index.cshtml"); // Assert Assert.Equal(2, codeTrees.Count); var viewStartChunks = codeTrees[0].Chunks; Assert.Equal(3, viewStartChunks.Count); Assert.IsType<LiteralChunk>(viewStartChunks[0]); var usingChunk = Assert.IsType<UsingChunk>(viewStartChunks[1]); Assert.Equal("MyNamespace", usingChunk.Namespace); Assert.IsType<LiteralChunk>(viewStartChunks[2]); viewStartChunks = codeTrees[1].Chunks; Assert.Equal(5, viewStartChunks.Count); Assert.IsType<LiteralChunk>(viewStartChunks[0]); var injectChunk = Assert.IsType<InjectChunk>(viewStartChunks[1]); Assert.Equal("MyHelper<TModel>", injectChunk.TypeName); Assert.Equal("Helper", injectChunk.MemberName); var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(viewStartChunks[2]); Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName); Assert.IsType<StatementChunk>(viewStartChunks[3]); Assert.IsType<LiteralChunk>(viewStartChunks[4]); }
public void GetOrAdd_ReturnsFileNotFoundResult_IfFileIsNotFoundInFileSystem() { // Arrange var fileProvider = new TestFileProvider(); var cache = new CompilerCache(Enumerable.Empty<RazorFileInfoCollection>(), TestLoadContext, fileProvider); // Act var result = cache.GetOrAdd("/some/path", ThrowsIfCalled); // Assert Assert.Same(CompilerCacheResult.FileNotFound, result); Assert.Null(result.CompilationResult); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var expected = new CompilationResult(typeof(TestView)); // Act var result = cache.GetOrAdd(ViewPath, _ => expected); // Assert Assert.True(result.Success); Assert.IsType<TestView>(result.PageFactory()); Assert.Same(ViewPath, result.PageFactory().Path); }
public void FileProvider_ReturnsInstanceIfExactlyOneFileProviderIsSpecified() { // Arrange var fileProvider = new TestFileProvider(); var options = new RazorViewEngineOptions(); options.FileProviders.Add(fileProvider); var optionsAccessor = new Mock<IOptions<RazorViewEngineOptions>>(); optionsAccessor.SetupGet(o => o.Value).Returns(options); var fileProviderAccessor = new DefaultRazorViewEngineFileProviderAccessor(optionsAccessor.Object); // Act var actual = fileProviderAccessor.FileProvider; // Assert Assert.Same(fileProvider, actual); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act var result = cache.GetOrAdd(ViewPath, _ => expected); // Assert Assert.NotSame(CompilerCacheResult.FileNotFound, result); var actual = Assert.IsType<UncachedCompilationResult>(result.CompilationResult); Assert.NotNull(actual); Assert.Same(expected, actual); Assert.Equal("hello world", actual.CompiledContent); Assert.Same(type, actual.CompiledType); }
public void GetInheritedChunks_ReturnsEmptySequenceIfNoGlobalsArePresent() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"_GlobalImport.cs", string.Empty); fileProvider.AddFile(@"Views\_Layout.cshtml", string.Empty); fileProvider.AddFile(@"Views\home\_not-globalimport.cshtml", string.Empty); var cache = new DefaultCodeTreeCache(fileProvider); var host = new MvcRazorHost(cache); var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); // Act var codeTrees = utility.GetInheritedCodeTrees(@"Views\home\Index.cshtml"); // Assert Assert.Empty(codeTrees); }
public void OnProvidersExecuting_ThrowsIfRouteTemplateHasOverridePattern() { // Arrange var fileProvider = new TestFileProvider(); var file = fileProvider.AddFile("/Index.cshtml", "@page \"/custom-route\""); fileProvider.AddDirectoryContent("/", new[] { file }); var project = new TestRazorProject(fileProvider); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); var context = new PageRouteModelProviderContext(); // Act & Assert var ex = Assert.Throws <InvalidOperationException>(() => provider.OnProvidersExecuting(context)); Assert.Equal("The route for the page at '/Index.cshtml' cannot start with / or ~/. Pages do not support overriding the file path of the page.", ex.Message); }
public void DoubleWildcardShouldMatchZeroOrMorePathSegments() { // Given TestFileProvider fileProvider = new TestFileProvider(); fileProvider.AddDirectory("/"); fileProvider.AddDirectory("/root"); fileProvider.AddDirectory("/root/a"); fileProvider.AddDirectory("/root/a/b"); fileProvider.AddDirectory("/root/d"); fileProvider.AddFile("/root/a/x.txt"); fileProvider.AddFile("/root/a/b/x.txt"); fileProvider.AddFile("/root/d/x.txt"); IDirectory directory = fileProvider.GetDirectory("/"); // When IEnumerable <IFile> matches = Globber.GetFiles(directory, new[] { "root/{a,}/**/x.txt" }); // Then matches.Select(x => x.Path.FullPath).ShouldBe( new[] { "/root/a/x.txt", "/root/a/b/x.txt", "/root/d/x.txt" }, true); }
public void Compile_ReturnsCompilationFailureWithPathsFromLinePragmas() { // Arrange var viewPath = "some-relative-path"; var fileContent = "test file content"; var content = $@" #line 1 ""{viewPath}"" this should fail"; var applicationEnvironment = GetApplicationEnvironment(); var libraryExporter = GetLibraryExporter(); var compilerOptionsProvider = new Mock <ICompilerOptionsProvider>(); compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationName, applicationEnvironment.RuntimeFramework, applicationEnvironment.Configuration)) .Returns(new CompilerOptions()); var mvcRazorHost = Mock.Of <IMvcRazorHost>(); var fileProvider = new TestFileProvider(); var fileInfo = fileProvider.AddFile(viewPath, fileContent); var compilationService = new RoslynCompilationService(applicationEnvironment, libraryExporter, compilerOptionsProvider.Object, mvcRazorHost, GetOptions(fileProvider)); var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path"); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType <CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(relativeFileInfo.RelativePath, compilationFailure.SourceFilePath); Assert.Equal(fileContent, compilationFailure.SourceFileContent); }
public void LookupFileInfo_ReturnsTrue_IfFileExists() { // Arrange var options = new StaticFileOptions(); var fileProvider = new TestFileProvider(); fileProvider.AddFile("/foo.txt", new TestFileInfo { LastModified = new DateTimeOffset(2014, 1, 2, 3, 4, 5, TimeSpan.Zero) }); options.FileProvider = fileProvider; var pathString = new PathString("/test"); var httpContext = new DefaultHttpContext(); httpContext.Request.Path = new PathString("/test/foo.txt"); var context = new StaticFileContext(httpContext, options, pathString, NullLogger.Instance); // Act context.ValidatePath(); var result = context.LookupFileInfo(); // Assert Assert.True(result); }
private static TestRazorViewCompiler GetViewCompiler( TestFileProvider fileProvider = null, Action <RoslynCompilationContext> compilationCallback = null, RazorReferenceManager referenceManager = null, IList <CompiledViewDescriptor> precompiledViews = null) { fileProvider = fileProvider ?? new TestFileProvider(); var accessor = Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider); compilationCallback = compilationCallback ?? (_ => { }); var options = Options.Create(new RazorViewEngineOptions()); if (referenceManager == null) { var applicationPartManager = new ApplicationPartManager(); var assembly = typeof(RazorViewCompilerTest).Assembly; applicationPartManager.ApplicationParts.Add(new AssemblyPart(assembly)); applicationPartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider()); referenceManager = new DefaultRazorReferenceManager(applicationPartManager, options); } precompiledViews = precompiledViews ?? Array.Empty <CompiledViewDescriptor>(); var hostingEnvironment = Mock.Of <IHostingEnvironment>(e => e.ContentRootPath == "BasePath"); var fileSystem = new FileProviderRazorProjectFileSystem(accessor, hostingEnvironment); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, builder => { RazorExtensions.Register(builder); }); var viewCompiler = new TestRazorViewCompiler( fileProvider, projectEngine, new CSharpCompiler(referenceManager, hostingEnvironment), compilationCallback, precompiledViews); return(viewCompiler); }
public async Task IncludesDocumentsFromDependencies() { // Given Bootstrapper bootstrapper = Bootstrapper.Factory.CreateWeb(Array.Empty <string>()); bootstrapper.AddSetting(WebKeys.DataFiles, "x/**/*.json"); bootstrapper.BuildPipeline("Test", builder => builder .WithInputReadFiles("a/**/*.json") .AsDependencyOf(nameof(Data))); TestFileProvider fileProvider = new TestFileProvider { { "/input/a/b/c.json", "{ \"Foo\": \"Bar\" }" }, { "/input/x/y/z.json", "{ \"Foo\": \"Buz\" }" } }; // When BootstrapperTestResult result = await bootstrapper.RunTestAsync(fileProvider); // Then result.ExitCode.ShouldBe((int)ExitCode.Normal); result.Outputs[nameof(Data)][Phase.Process].Select(x => x["Foo"]).ShouldBe(new[] { "Bar", "Buz" }, true); }
public void EnumerateFiles_ReturnsCshtmlFiles() { // Arrange var fileProvider = new TestFileProvider(); var file1 = fileProvider.AddFile("File1.cshtml", "content"); var file2 = fileProvider.AddFile("File2.js", "content"); var file3 = fileProvider.AddFile("File3.cshtml", "content"); fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2, file3 }); var accessor = Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider); var razorProject = new FileProviderRazorProject(accessor); // Act var razorFiles = razorProject.EnumerateItems("/"); // Assert Assert.Collection(razorFiles.OrderBy(f => f.FilePath), file => Assert.Equal("/File1.cshtml", file.FilePath), file => Assert.Equal("/File3.cshtml", file.FilePath)); }
public void GetOrAdd_NormalizesPathSepartorForPaths(string relativePath) { // Arrange var viewPath = "/Areas/Finances/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "some content"); var cache = new CompilerCache(fileProvider); var expected = new CompilationResult(typeof(TestView)); // Act - 1 var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected); // Assert - 1 Assert.IsType<TestView>(result1.PageFactory()); // Act - 2 var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled); // Assert - 2 Assert.IsType<TestView>(result2.PageFactory()); Assert.Same(result1.PageFactory, result2.PageFactory); }
public async Task DoesNotApplyDirectoryMetadataIfSettingIsFalse() { // Given Bootstrapper bootstrapper = Bootstrapper.Factory .CreateWeb(Array.Empty <string>()) .AddSetting(WebKeys.ApplyDirectoryMetadata, false); TestFileProvider fileProvider = new TestFileProvider { { "/input/a/b/c.json", "{ \"Foo\": \"Bar\" }" }, { "/input/a/_directory.json", "{ \"Fizz\": \"Buzz\" }" } }; // When BootstrapperTestResult result = await bootstrapper.RunTestAsync(fileProvider); // Then result.ExitCode.ShouldBe((int)ExitCode.Normal); IDocument document = result.Outputs[nameof(Data)][Phase.Process].ShouldHaveSingleItem(); document["Foo"].ShouldBe("Bar"); document.ContainsKey("Fizz").ShouldBeFalse(); }
public async Task ProcessesJsonSidecarFileWithDifferentExtension() { // Given Bootstrapper bootstrapper = Bootstrapper.Factory.CreateWeb(Array.Empty <string>()); bootstrapper.AddSetting(WebKeys.DataFiles, "**/*.foo"); TestFileProvider fileProvider = new TestFileProvider { { "/input/a/b/c.foo", "Foobar" }, { "/input/a/b/_c.json", "{ \"Fizz\": \"Buzz\" }" } }; // When BootstrapperTestResult result = await bootstrapper.RunTestAsync(fileProvider); // Then result.ExitCode.ShouldBe((int)ExitCode.Normal); IDocument document = result.Outputs[nameof(Data)][Phase.Process].ShouldHaveSingleItem(); document["Fizz"].ShouldBe("Buzz"); (await document.GetContentStringAsync()).ShouldBe("Foobar"); }
public async Task CompileAsync_PrecompiledViewWithChecksum_CanRecompile() { // Arrange var path = "/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); var fileInfo = fileProvider.AddFile(path, "some content"); var expected2 = new CompiledViewDescriptor(); var precompiledView = new CompiledViewDescriptor { RelativePath = path, Item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", path, new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), path), }), }; var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView }); viewCompiler.AllowRecompilingViewsOnFileChange = true; // Act - 1 var result = await viewCompiler.CompileAsync(path); // Assert - 1 Assert.Same(precompiledView.Item, result.Item); Assert.NotEmpty(result.ExpirationTokens); // Act - 2 fileInfo.Content = "some other content"; fileProvider.GetChangeToken(path).HasChanged = true; viewCompiler.Compile = _ => expected2; result = await viewCompiler.CompileAsync(path); // Assert - 2 Assert.Same(expected2, result); }
public async Task GetAsync_Sample() { var requestUri = new Uri("users/test", UriKind.Relative); var json = TestFileProvider.ReadText("user.json"); clientContext.MockHttpMessageHandler.SetResponse(requestUri, json); var user = await client.GetAsync("test"); Assert.IsNotNull(user); var expected = new UserResult { Id = 7, Username = "******", FullName = "", Email = "", AvatarUrl = "https://secure.gravatar.com/avatar/bb11777b425ba7229a182f446783203d" }; ObjectTreeAssert.AreEqual(expected, user); }
public void GetOrAdd_UpdatesCacheWithValue_IfFileWasAdded() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); var chunkTreeCache = new DefaultChunkTreeCache(fileProvider); var expected = new ChunkTree(); // Act 1 var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); }); // Assert 1 Assert.Null(result1); // Act 2 fileProvider.AddFile(path, "test content"); fileProvider.GetChangeToken(path).HasChanged = true; var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected); // Assert 2 Assert.Same(expected, result2); }
public void GetOrAdd_ExpiresEntriesAfterOneMinute() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "some content"); var clock = new Mock <ISystemClock>(); var utcNow = DateTimeOffset.UtcNow; clock.SetupGet(c => c.UtcNow) .Returns(() => utcNow); var options = new MemoryCacheOptions { Clock = clock.Object }; var chunkTreeCache = new DefaultChunkTreeCache(fileProvider, options); var chunkTree1 = new ChunkTree(); var chunkTree2 = new ChunkTree(); // Act 1 var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => chunkTree1); // Assert 1 Assert.Same(chunkTree1, result1); // Act 2 utcNow = utcNow.AddSeconds(59); var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); }); // Assert 2 Assert.Same(chunkTree1, result2); // Act 3 utcNow = utcNow.AddSeconds(65); var result3 = chunkTreeCache.GetOrAdd(path, fileInfo => chunkTree2); // Assert 3 Assert.Same(chunkTree2, result3); }
private TestCompiledPageRouteModelProvider CreateProvider( RazorPagesOptions options = null, IList <CompiledViewDescriptor> descriptors = null, TestFileProvider fileProvider = null) { options = options ?? new RazorPagesOptions(); fileProvider = fileProvider ?? new TestFileProvider(); var project = new FileProviderRazorProject( Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider), Mock.Of <IHostingEnvironment>(e => e.ContentRootPath == "BasePath")); var templateEngine = new RazorTemplateEngine(RazorEngine.Create(), project); var provider = new TestCompiledPageRouteModelProvider( new ApplicationPartManager(), Options.Create(options), templateEngine, NullLogger <CompiledPageRouteModelProvider> .Instance); provider.Descriptors.AddRange(descriptors ?? Array.Empty <CompiledViewDescriptor>()); return(provider); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act var result = cache.GetOrAdd(ViewPath, _ => expected); // Assert Assert.NotSame(CompilerCacheResult.FileNotFound, result); var actual = Assert.IsType <UncachedCompilationResult>(result.CompilationResult); Assert.NotNull(actual); Assert.Same(expected, actual); Assert.Equal("hello world", actual.CompiledContent); Assert.Same(type, actual.CompiledType); }
public async Task CompileAsync_ReturnsPrecompiledViews() { // Arrange var path = "/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "some content"); var precompiledView = new CompiledViewDescriptor { RelativePath = path, }; var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView }); // Act var result = await viewCompiler.CompileAsync(path); // Assert Assert.Same(precompiledView, result); // This view doesn't have checksums so it can't be recompiled. Assert.Null(precompiledView.ExpirationTokens); }
public void Compile_ReturnsCompilationFailureWithPathsFromLinePragmas() { // Arrange var viewPath = "some-relative-path"; var fileContent = "test file content"; var content = $@" #line 1 ""{viewPath}"" this should fail"; var applicationEnvironment = GetApplicationEnvironment(); var accessor = GetLoadContextAccessor(); var libraryExporter = GetLibraryExporter(); var compilerOptionsProvider = new Mock<ICompilerOptionsProvider>(); compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationName, applicationEnvironment.RuntimeFramework, applicationEnvironment.Configuration)) .Returns(new CompilerOptions()); var mvcRazorHost = Mock.Of<IMvcRazorHost>(); var fileProvider = new TestFileProvider(); var fileInfo = fileProvider.AddFile(viewPath, fileContent); var compilationService = new RoslynCompilationService(applicationEnvironment, accessor, libraryExporter, compilerOptionsProvider.Object, mvcRazorHost, GetOptions(fileProvider)); var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path"); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType<CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(relativeFileInfo.RelativePath, compilationFailure.SourceFilePath); Assert.Equal(fileContent, compilationFailure.SourceFileContent); }
public void IncludesFile() { // Given TestFileProvider fileProvider = new TestFileProvider(); fileProvider.AddDirectory("/"); fileProvider.AddDirectory("/A"); fileProvider.AddDirectory("/A/B"); fileProvider.AddFile("/A/B/c.txt", "foo"); TestFileSystem fileSystem = new TestFileSystem { FileProvider = fileProvider }; fileSystem.InputPaths.Clear(); fileSystem.InputPaths.Add("/A"); TestExecutionContext context = new TestExecutionContext { FileSystem = fileSystem }; TestDocument document = new TestDocument(); KeyValuePair <string, string>[] args = new KeyValuePair <string, string>[] { new KeyValuePair <string, string>(null, "B/c.txt") }; Include shortcode = new Include(); // When IShortcodeResult result = shortcode.Execute(args, string.Empty, document, context); // Then using (TextReader reader = new StreamReader(result.Stream)) { reader.ReadToEnd().ShouldBe("foo"); } }
public void OnProvidersExecuting_DiscoversFilesUnderBasePath() { // Arrange var fileProvider = new TestFileProvider(); var dir1 = fileProvider.AddDirectoryContent("/Pages", new[] { fileProvider.AddFile("/Pages/Index.cshtml", "@page"), fileProvider.AddFile("/Pages/_Layout.cshtml", "@page") }); var dir2 = fileProvider.AddDirectoryContent("/NotPages", new[] { fileProvider.AddFile("/NotPages/Index.cshtml", "@page"), fileProvider.AddFile("/NotPages/_Layout.cshtml", "@page") }); var rootFile = fileProvider.AddFile("/Index.cshtml", "@page"); fileProvider.AddDirectoryContent("/", new IFileInfo[] { rootFile, dir1, dir2 }); var project = new TestRazorProject(fileProvider); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/Pages"; var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); var context = new PageRouteModelProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert Assert.Collection(context.RouteModels, model => { Assert.Equal("/Pages/Index.cshtml", model.RelativePath); }); }
public void ConvertingBadSassFails() { // Given const string input = @" $font-stack: Helvetica, sans-serif $primary-color: #333 body { font: 100% $font-stack; color: $primary-color; }"; TestFileProvider fileProvider = new TestFileProvider(); fileProvider.AddDirectory("/"); fileProvider.AddDirectory("/input"); fileProvider.AddDirectory("/input/assets"); fileProvider.AddFile("/input/assets/test.scss", input); TestFileSystem fileSystem = new TestFileSystem { FileProvider = fileProvider }; IExecutionContext context = new TestExecutionContext { FileSystem = fileSystem }; IDocument document = new TestDocument(input, new MetadataItems { { Keys.RelativeFilePath, new FilePath("assets/test.scss") } }); Sass sass = new Sass(); // When, Then Assert.Catch <AggregateException>(() => { sass.Execute(new[] { document }, context).ToList(); // Make sure to materialize the result list }); }
public void OnProvidersExecuting_ReturnsPagesWithPageDirective() { // Arrange var fileProvider = new TestFileProvider(); var file1 = fileProvider.AddFile("/Pages/Home.cshtml", "@page"); var file2 = fileProvider.AddFile("/Pages/Test.cshtml", "Hello world"); var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { file1, file2 }); fileProvider.AddDirectoryContent("/", new[] { dir1 }); var project = new TestRazorProject(fileProvider); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); var context = new PageRouteModelProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert Assert.Collection(context.RouteModels, model => { Assert.Equal("/Pages/Home.cshtml", model.RelativePath); Assert.Equal("/Pages/Home", model.ViewEnginePath); Assert.Collection(model.Selectors, selector => Assert.Equal("Pages/Home", selector.AttributeRouteModel.Template)); Assert.Collection(model.RouteValues.OrderBy(k => k.Key), kvp => { Assert.Equal("page", kvp.Key); Assert.Equal("/Pages/Home", kvp.Value); }); }); }
private static TestRazorViewCompiler GetViewCompiler( TestFileProvider fileProvider = null, Action <RoslynCompilationContext> compilationCallback = null, RazorReferenceManager referenceManager = null, IList <CompiledViewDescriptor> precompiledViews = null, CSharpCompiler csharpCompiler = null) { fileProvider = fileProvider ?? new TestFileProvider(); var accessor = Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider); compilationCallback = compilationCallback ?? (_ => { }); var options = Options.Create(new RazorViewEngineOptions()); if (referenceManager == null) { referenceManager = CreateReferenceManager(options); } precompiledViews = precompiledViews ?? Array.Empty <CompiledViewDescriptor>(); var hostingEnvironment = Mock.Of <IHostingEnvironment>(e => e.ContentRootPath == "BasePath"); var fileSystem = new FileProviderRazorProjectFileSystem(accessor, hostingEnvironment); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, builder => { RazorExtensions.Register(builder); }); csharpCompiler = csharpCompiler ?? new CSharpCompiler(referenceManager, hostingEnvironment); var viewCompiler = new TestRazorViewCompiler( fileProvider, projectEngine, csharpCompiler, compilationCallback, precompiledViews); return(viewCompiler); }
public void AddFileVersionToPath_UpdatesEntryWhenCacheExpires_ForNonExistingFile() { // Arrange var fileProvider = new TestFileProvider(); var fileVersionProvider = new FileVersionProvider( fileProvider, new MemoryCache(new MemoryCacheOptions()), GetRequestPathBase()); // Act 1 - File does not exist var result = fileVersionProvider.AddFileVersionToPath("file.txt"); // Assert 1 Assert.Equal("file.txt", result); // Act 2 - File gets added fileProvider.AddFile("file.txt", "Hello World!"); fileProvider.GetChangeToken("file.txt").HasChanged = true; result = fileVersionProvider.AddFileVersionToPath("file.txt"); // Assert 2 Assert.Equal("file.txt?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", result); }
public async Task CompileAsync_AddsChangeTokensForViewStartsIfFileExists_WhenWatchingForFileChanges() { // Arrange var path = "/file/exists/FilePath.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "Content"); var viewCompiler = GetViewCompiler(fileProvider); viewCompiler.AllowRecompilingViewsOnFileChange = true; // Act var result = await viewCompiler.CompileAsync(path); // Assert Assert.NotNull(result.ViewAttribute); Assert.Collection( result.ExpirationTokens, token => Assert.Same(fileProvider.GetChangeToken(path), token), token => Assert.Same(fileProvider.GetChangeToken("/_ViewImports.cshtml"), token), token => Assert.Same(fileProvider.GetChangeToken("/file/_ViewImports.cshtml"), token), token => Assert.Same(fileProvider.GetChangeToken("/file/exists/_ViewImports.cshtml"), token)); }
public void LookupFileInfo_ReturnsTrue_IfFileExists() { // Arrange var options = new StaticFileOptions(); var fileProvider = new TestFileProvider(); fileProvider.AddFile("/foo.txt", new TestFileInfo { LastModified = new DateTimeOffset(2014, 1, 2, 3, 4, 5, TimeSpan.Zero) }); var pathString = new PathString("/test"); var httpContext = new DefaultHttpContext(); httpContext.Request.Path = new PathString("/test/foo.txt"); var context = new StaticFileContext(httpContext, options, pathString, NullLogger.Instance, fileProvider, new FileExtensionContentTypeProvider()); // Act context.ValidatePath(); var result = context.LookupFileInfo(); // Assert Assert.True(result); }
private IFileProvider GetFileProvider() { TestFileProvider fileProvider = new TestFileProvider(); fileProvider.AddDirectory("/a"); fileProvider.AddDirectory("/a/b"); fileProvider.AddDirectory("/a/b/c"); fileProvider.AddDirectory("/a/b/c/1"); fileProvider.AddDirectory("/a/b/d"); fileProvider.AddDirectory("/a/x"); fileProvider.AddDirectory("/a/y"); fileProvider.AddDirectory("/a/y/z"); fileProvider.AddFile("/a/b/c/foo.txt"); fileProvider.AddFile("/a/b/c/baz.txt"); fileProvider.AddFile("/a/b/c/1/2.txt"); fileProvider.AddFile("/a/b/d/baz.txt"); fileProvider.AddFile("/a/x/bar.txt"); fileProvider.AddFile("/a/x/foo.xml"); fileProvider.AddFile("/a/x/foo.doc"); return(fileProvider); }
public void GetItem_ReturnsFileFromDisk() { var fileProvider = new TestFileProvider("BasePath"); var file1 = fileProvider.AddFile("File1.cshtml", "content"); var file2 = fileProvider.AddFile("File2.js", "content"); var file3 = fileProvider.AddFile("File3.cshtml", "content"); fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2, file3 }); var accessor = Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider); var razorProject = new FileProviderRazorProject(accessor, Mock.Of <IHostingEnvironment>(e => e.ContentRootPath == "BasePath")); // Act var item = razorProject.GetItem("/File3.cshtml"); // Assert Assert.True(item.Exists); Assert.Equal("/File3.cshtml", item.FilePath); Assert.Equal(string.Empty, item.BasePath); Assert.Equal(Path.Combine("BasePath", "File3.cshtml"), item.PhysicalPath); Assert.Equal("File3.cshtml", item.RelativePhysicalPath); }
public void RecursiveWildcardTests(string directoryPath, string[] patterns, string[] resultPaths) { // Given TestFileProvider fileProvider = new TestFileProvider(); fileProvider.AddDirectory("/a"); fileProvider.AddDirectory("/a/b"); fileProvider.AddDirectory("/a/b/c"); fileProvider.AddDirectory("/a/b/c/d"); fileProvider.AddDirectory("/a/b/c/d/e"); fileProvider.AddDirectory("/a/b/c/d/e/1"); fileProvider.AddDirectory("/a/b/c/d/e/1/2"); fileProvider.AddFile("/a/b/c/d/e/1/2/3.txt"); IDirectory directory = fileProvider.GetDirectory(directoryPath); // When IEnumerable <IFile> matches = Globber.GetFiles(directory, patterns); IEnumerable <IFile> matchesReversedSlash = Globber.GetFiles(directory, patterns.Select(x => x.Replace("/", "\\"))); // Then CollectionAssert.AreEquivalent(resultPaths, matches.Select(x => x.Path.FullPath)); CollectionAssert.AreEquivalent(resultPaths, matchesReversedSlash.Select(x => x.Path.FullPath)); }
public void GetOrAdd_NormalizesPathSepartorForPaths(string relativePath) { // Arrange var viewPath = "/Areas/Finances/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = new CompilationResult(type); // Act - 1 var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected); // Assert - 1 Assert.Same(type, result1.CompilationResult.CompiledType); // Act - 2 var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled); // Assert - 2 Assert.Same(type, result2.CompilationResult.CompiledType); }
public void SameConfigWhenReloadOnChangeIsFalse() { var testFileProvider = new TestFileProvider( new TestFile("Secret1", "SecretValue1"), new TestFile("Secret2", "SecretValue2")); var config = new ConfigurationBuilder() .AddKeyPerFile(o => { o.FileProvider = testFileProvider; o.ReloadOnChange = false; }).Build(); Assert.Equal("SecretValue1", config["Secret1"]); Assert.Equal("SecretValue2", config["Secret2"]); testFileProvider.ChangeFiles( new TestFile("Secret1", "NewSecretValue1"), new TestFile("Secret3", "NewSecretValue3")); Assert.Equal("SecretValue1", config["Secret1"]); Assert.Equal("SecretValue2", config["Secret2"]); }
public void AddFileVersionToPath_UpdatesEntryWhenCacheExpires_ForExistingFile_WithRequestPathBase() { // Arrange var fileProvider = new TestFileProvider(); var requestPath = GetRequestPathBase("/wwwroot/"); var fileVersionProvider = GetFileVersionProvider(fileProvider); fileProvider.AddFile("file.txt", "Hello World!"); // Act 1 - File exists var result = fileVersionProvider.AddFileVersionToPath(requestPath, "/wwwroot/file.txt"); // Assert 1 Assert.Equal("/wwwroot/file.txt?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", result); // Act 2 fileProvider.DeleteFile("file.txt"); fileProvider.GetChangeToken("file.txt").HasChanged = true; result = fileVersionProvider.AddFileVersionToPath(requestPath, "/wwwroot/file.txt"); // Assert 2 Assert.Equal("/wwwroot/file.txt", result); }
public void AddFileVersionToPath_DoesNotLockFileAfterReading() { // Arrange var stream = new TestableMemoryStream(Encoding.UTF8.GetBytes("Hello World!")); var mockFile = new Mock <IFileInfo>(); mockFile.SetupGet(f => f.Exists).Returns(true); mockFile .Setup(m => m.CreateReadStream()) .Returns(stream); var fileProvider = new TestFileProvider(); fileProvider.AddFile("/hello/world", mockFile.Object); var requestPath = GetRequestPathBase(); var fileVersionProvider = GetFileVersionProvider(fileProvider); // Act var result = fileVersionProvider.AddFileVersionToPath(requestPath, "/hello/world"); // Assert Assert.True(stream.Disposed); }
public void GetOrAdd_ExpiresEntriesAfterOneMinute() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "some content"); var clock = new Mock<ISystemClock>(); var utcNow = DateTimeOffset.UtcNow; clock.SetupGet(c => c.UtcNow) .Returns(() => utcNow); var options = new MemoryCacheOptions { Clock = clock.Object }; using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider, options)) { var chunkTree1 = new ChunkTree(); var chunkTree2 = new ChunkTree(); // Act 1 var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => chunkTree1); // Assert 1 Assert.Same(chunkTree1, result1); // Act 2 utcNow = utcNow.AddSeconds(59); var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); }); // Assert 2 Assert.Same(chunkTree1, result2); // Act 3 utcNow = utcNow.AddSeconds(65); var result3 = chunkTreeCache.GetOrAdd(path, fileInfo => chunkTree2); // Assert 3 Assert.Same(chunkTree2, result3); } }
public void GetOrAdd_NormalizesPathSepartorForPaths(string relativePath) { // Arrange var viewPath = "/Areas/Finances/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act - 1 var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected); // Assert - 1 var compilationResult = Assert.IsType<UncachedCompilationResult>(result1.CompilationResult); Assert.Same(expected, compilationResult); Assert.Same(type, compilationResult.CompiledType); // Act - 2 var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled); // Assert - 2 Assert.Same(type, result2.CompilationResult.CompiledType); }
public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForViewImports(string globalImportPath) { // Arrange var fileProvider = new TestFileProvider(); var cache = new CompilerCache(fileProvider, _precompiledViews); // Act fileProvider.Watch(globalImportPath); fileProvider.GetChangeToken(globalImportPath).HasChanged = true; var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled); // Assert Assert.NotSame(CompilerCacheResult.FileNotFound, result); Assert.Same(typeof(PreCompile), result.CompilationResult.CompiledType); }
public void GetOrAdd_ReturnsRuntimeCompiledAndPrecompiledViews() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider, _precompiledViews); var expected = CompilationResult.Successful(typeof(TestView)); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.Same(expected, result1.CompilationResult); // Act 2 var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.Same(typeof(TestView), result2.CompilationResult.CompiledType); // Act 3 var result3 = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled); // Assert 3 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.Same(typeof(PreCompile), result3.CompilationResult.CompiledType); }
public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages() { // Arrange var viewPath = "Views/Home/Index"; var generatedCodeFileName = "Generated Code"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "view-content"); var options = new Mock<IOptions<RazorViewEngineOptions>>(); options.SetupGet(o => o.Options) .Returns(new RazorViewEngineOptions { FileProvider = fileProvider }); var compilationService = new RoslynCompilationService( GetApplicationEnvironment(), GetLoadContextAccessor(), GetLibraryExporter(), Mock.Of<ICompilerOptionsProvider>(), Mock.Of<IMvcRazorHost>(), options.Object); var assemblyName = "random-assembly-name"; var diagnostics = new[] { Diagnostic.Create( GetDiagnosticDescriptor("message-1"), Location.Create( viewPath, new TextSpan(10, 5), new LinePositionSpan(new LinePosition(10, 1), new LinePosition(10, 2)))), Diagnostic.Create( GetDiagnosticDescriptor("message-2"), Location.Create( assemblyName, new TextSpan(1, 6), new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))), Diagnostic.Create( GetDiagnosticDescriptor("message-3"), Location.Create( viewPath, new TextSpan(40, 50), new LinePositionSpan(new LinePosition(30, 5), new LinePosition(40, 12)))), }; // Act var compilationResult = compilationService.GetCompilationFailedResult( viewPath, "compilation-content", assemblyName, diagnostics); // Assert Assert.Collection(compilationResult.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Equal("view-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-1", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(11, message.StartLine); Assert.Equal(2, message.StartColumn); Assert.Equal(11, message.EndLine); Assert.Equal(3, message.EndColumn); }, message => { Assert.Equal("message-3", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(31, message.StartLine); Assert.Equal(6, message.StartColumn); Assert.Equal(41, message.EndLine); Assert.Equal(13, message.EndColumn); }); }, failure => { Assert.Equal(generatedCodeFileName, failure.SourceFilePath); Assert.Equal("compilation-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-2", message.Message); Assert.Equal(assemblyName, message.SourceFilePath); Assert.Equal(2, message.StartLine); Assert.Equal(3, message.StartColumn); Assert.Equal(4, message.EndLine); Assert.Equal(5, message.EndColumn); }); }); }
public void GetInheritedChunks_ReadsChunksFromGlobalFilesInPath() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"/Views/accounts/_ViewImports.cshtml", "@using AccountModels"); fileProvider.AddFile(@"/Views/Shared/_ViewImports.cshtml", "@inject SharedHelper Shared"); fileProvider.AddFile(@"/Views/home/_ViewImports.cshtml", "@using MyNamespace"); fileProvider.AddFile(@"/Views/_ViewImports.cshtml", @"@inject MyHelper<TModel> Helper @inherits MyBaseType @{ Layout = ""test.cshtml""; } "); var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var cache = new DefaultChunkTreeCache(fileProvider); using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false))) { var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); // Act var chunkTreeResults = utility.GetInheritedChunkTreeResults( PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml")); // Assert Assert.Collection(chunkTreeResults, chunkTreeResult => { var viewImportsPath = @"/Views/_ViewImports.cshtml"; Assert.Collection(chunkTreeResult.ChunkTree.Children, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { var injectChunk = Assert.IsType<InjectChunk>(chunk); Assert.Equal("MyHelper<TModel>", injectChunk.TypeName); Assert.Equal("Helper", injectChunk.MemberName); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk); Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { Assert.IsType<StatementChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }); Assert.Equal(viewImportsPath, chunkTreeResult.FilePath); }, chunkTreeResult => { var viewImportsPath = "/Views/home/_ViewImports.cshtml"; Assert.Collection(chunkTreeResult.ChunkTree.Children, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { var usingChunk = Assert.IsType<UsingChunk>(chunk); Assert.Equal("MyNamespace", usingChunk.Namespace); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }, chunk => { Assert.IsType<LiteralChunk>(chunk); Assert.Equal(viewImportsPath, chunk.Start.FilePath); }); Assert.Equal(viewImportsPath, chunkTreeResult.FilePath); }); } }
public void MergeInheritedChunks_MergesDefaultInheritedChunks() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"Views\_ViewImports.cshtml", "@inject DifferentHelper<TModel> Html"); var cache = new DefaultChunkTreeCache(fileProvider); var host = new MvcRazorHost(cache); var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var inheritedChunkTrees = new ChunkTree[] { new ChunkTree { Chunks = new Chunk[] { new UsingChunk { Namespace = "InheritedNamespace" }, new LiteralChunk { Text = "some text" } } }, new ChunkTree { Chunks = new Chunk[] { new UsingChunk { Namespace = "AppNamespace.Model" }, } } }; var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); var chunkTree = new ChunkTree(); // Act utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic"); // Assert Assert.Equal(3, chunkTree.Chunks.Count); Assert.Same(inheritedChunkTrees[0].Chunks[0], chunkTree.Chunks[0]); Assert.Same(inheritedChunkTrees[1].Chunks[0], chunkTree.Chunks[1]); Assert.Same(defaultChunks[0], chunkTree.Chunks[2]); }
public void GetOrAdd_UpdatesCacheWithValue_IfFileWasAdded() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); var codeTreeCache = new DefaultCodeTreeCache(fileProvider); var expected = new CodeTree(); // Act 1 var result1 = codeTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); }); // Assert 1 Assert.Null(result1); // Act 2 fileProvider.AddFile(path, "test content"); fileProvider.GetTrigger(path).IsExpired = true; var result2 = codeTreeCache.GetOrAdd(path, fileInfo => expected); // Assert 2 Assert.Same(expected, result2); }
public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages() { // Arrange var viewPath = "Views/Home/Index"; var generatedCodeFileName = "Generated Code"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "view-content"); var options = new RazorViewEngineOptions(); options.FileProviders.Add(fileProvider); var compilationService = new DefaultRoslynCompilationService( GetDependencyContext(), options, GetFileProviderAccessor(fileProvider), NullLoggerFactory.Instance); var assemblyName = "random-assembly-name"; var diagnostics = new[] { Diagnostic.Create( GetDiagnosticDescriptor("message-1"), Location.Create( viewPath, new TextSpan(10, 5), new LinePositionSpan(new LinePosition(10, 1), new LinePosition(10, 2)))), Diagnostic.Create( GetDiagnosticDescriptor("message-2"), Location.Create( assemblyName, new TextSpan(1, 6), new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))), Diagnostic.Create( GetDiagnosticDescriptor("message-3"), Location.Create( viewPath, new TextSpan(40, 50), new LinePositionSpan(new LinePosition(30, 5), new LinePosition(40, 12)))), }; // Act var compilationResult = compilationService.GetCompilationFailedResult( viewPath, "compilation-content", assemblyName, diagnostics); // Assert Assert.Collection(compilationResult.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Equal("view-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-1", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(11, message.StartLine); Assert.Equal(2, message.StartColumn); Assert.Equal(11, message.EndLine); Assert.Equal(3, message.EndColumn); }, message => { Assert.Equal("message-3", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(31, message.StartLine); Assert.Equal(6, message.StartColumn); Assert.Equal(41, message.EndLine); Assert.Equal(13, message.EndColumn); }); }, failure => { Assert.Equal(generatedCodeFileName, failure.SourceFilePath); Assert.Equal("compilation-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-2", message.Message); Assert.Equal(assemblyName, message.SourceFilePath); Assert.Equal(2, message.StartLine); Assert.Equal(3, message.StartColumn); Assert.Equal(4, message.EndLine); Assert.Equal(5, message.EndColumn); }); }); }
public void Compile_DoesNotThrow_IfFileCannotBeRead() { // Arrange var path = "some-relative-path"; var content = $@" #line 1 ""{path}"" this should fail"; var mockFileInfo = new Mock<IFileInfo>(); mockFileInfo.Setup(f => f.CreateReadStream()) .Throws(new Exception()); var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, mockFileInfo.Object); var compilationService = new DefaultRoslynCompilationService( GetDependencyContext(), GetOptions(), GetFileProviderAccessor(), NullLoggerFactory.Instance); var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, path); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType<CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(path, compilationFailure.SourceFilePath); Assert.Null(compilationFailure.SourceFileContent); }
public void MergeInheritedChunks_MergesDefaultInheritedChunks() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"/Views/_ViewImports.cshtml", "@inject DifferentHelper<TModel> Html"); var cache = new DefaultChunkTreeCache(fileProvider); using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false))) { var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var inheritedChunkTrees = new ChunkTree[] { new ChunkTree { Children = new Chunk[] { new UsingChunk { Namespace = "InheritedNamespace" }, new LiteralChunk { Text = "some text" } } }, new ChunkTree { Children = new Chunk[] { new UsingChunk { Namespace = "AppNamespace.Model" }, } } }; var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); var chunkTree = new ChunkTree(); // Act utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic"); // Assert Assert.Collection(chunkTree.Children, chunk => Assert.Same(defaultChunks[1], chunk), chunk => Assert.Same(inheritedChunkTrees[0].Children[0], chunk), chunk => Assert.Same(defaultChunks[0], chunk)); } }
public void GetInheritedChunks_ReturnsEmptySequenceIfNoGlobalsArePresent() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(@"/_ViewImports.cs", string.Empty); fileProvider.AddFile(@"/Views/_Layout.cshtml", string.Empty); fileProvider.AddFile(@"/Views/home/_not-viewimports.cshtml", string.Empty); var cache = new DefaultChunkTreeCache(fileProvider); using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false))) { var defaultChunks = new Chunk[] { new InjectChunk("MyTestHtmlHelper", "Html"), new UsingChunk { Namespace = "AppNamespace.Model" }, }; var utility = new ChunkInheritanceUtility(host, cache, defaultChunks); // Act var chunkTrees = utility.GetInheritedChunkTreeResults(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml")); // Assert Assert.Empty(chunkTrees); } }
public void GetOrAdd_UpdatesCacheWithNullValue_IfFileWasDeleted() { // Arrange var path = @"Views\Home\_ViewStart.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, "test content"); using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider)) { var expected1 = new ChunkTree(); // Act 1 var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => expected1); // Assert 1 Assert.Same(expected1, result1); // Act 2 fileProvider.DeleteFile(path); fileProvider.GetChangeToken(path).HasChanged = true; var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); }); // Assert 2 Assert.Null(result2); } }
public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages() { // Arrange var viewPath = @"views/index.razor"; var viewImportsPath = @"views/global.import.cshtml"; var host = Mock.Of<IMvcRazorHost>(); var fileProvider = new TestFileProvider(); var file = fileProvider.AddFile(viewPath, "View Content"); fileProvider.AddFile(viewImportsPath, "Global Import Content"); var relativeFileInfo = new RelativeFileInfo(file, viewPath); var razorService = new RazorCompilationService( Mock.Of<ICompilationService>(), Mock.Of<IMvcRazorHost>(), GetOptions(fileProvider)); var errors = new[] { new RazorError("message-1", new SourceLocation(1, 2, 17)), new RazorError("message-2", new SourceLocation(viewPath, 1, 4, 6), 7), new RazorError { Message = "message-3" }, new RazorError("message-4", new SourceLocation(viewImportsPath, 1, 3, 8), 4), }; // Act var result = razorService.GetCompilationFailedResult(relativeFileInfo, errors); // Assert Assert.NotNull(result.CompilationFailures); Assert.Collection(result.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Equal("View Content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal(errors[0].Message, message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(3, message.StartLine); Assert.Equal(17, message.StartColumn); Assert.Equal(3, message.EndLine); Assert.Equal(18, message.EndColumn); }, message => { Assert.Equal(errors[1].Message, message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(5, message.StartLine); Assert.Equal(6, message.StartColumn); Assert.Equal(5, message.EndLine); Assert.Equal(13, message.EndColumn); }, message => { Assert.Equal(errors[2].Message, message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(0, message.StartLine); Assert.Equal(-1, message.StartColumn); Assert.Equal(0, message.EndLine); Assert.Equal(0, message.EndColumn); }); }, failure => { Assert.Equal(viewImportsPath, failure.SourceFilePath); Assert.Equal("Global Import Content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal(errors[3].Message, message.Message); Assert.Equal(viewImportsPath, message.SourceFilePath); Assert.Equal(4, message.StartLine); Assert.Equal(8, message.StartColumn); Assert.Equal(4, message.EndLine); Assert.Equal(12, message.EndColumn); }); }); }
public void GetOrAdd_ReturnsFileNotFoundIfFileWasDeleted() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected, result1.CompilationResult); // Act 2 // Delete the file from the file system and set it's expiration token. fileProvider.DeleteFile(ViewPath); fileProvider.GetChangeToken(ViewPath).HasChanged = true; var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.Same(CompilerCacheResult.FileNotFound, result2); Assert.Null(result2.CompilationResult); }
public void Compile_DoesNotThrow_IfFileCannotBeRead() { // Arrange var path = "some-relative-path"; var content = $@" #line 1 ""{path}"" this should fail"; var applicationEnvironment = GetApplicationEnvironment(); var accessor = GetLoadContextAccessor(); var libraryExporter = GetLibraryExporter(); var compilerOptionsProvider = new Mock<ICompilerOptionsProvider>(); compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationName, applicationEnvironment.RuntimeFramework, applicationEnvironment.Configuration)) .Returns(new CompilerOptions()); var mvcRazorHost = Mock.Of<IMvcRazorHost>(); var mockFileInfo = new Mock<IFileInfo>(); mockFileInfo.Setup(f => f.CreateReadStream()) .Throws(new Exception()); var fileProvider = new TestFileProvider(); fileProvider.AddFile(path, mockFileInfo.Object); var compilationService = new RoslynCompilationService(applicationEnvironment, accessor, libraryExporter, compilerOptionsProvider.Object, mvcRazorHost, GetOptions(fileProvider)); var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, path); // Act var result = compilationService.Compile(relativeFileInfo, content); // Assert Assert.IsType<CompilationResult>(result); Assert.Null(result.CompiledType); var compilationFailure = Assert.Single(result.CompilationFailures); Assert.Equal(path, compilationFailure.SourceFilePath); Assert.Null(compilationFailure.SourceFileContent); }