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 ConfigureRazorViewEngine_ConfiguresOptionsProperly() { // Arrange var services = new ServiceCollection().AddOptions(); var fileProvider = new TestFileProvider(); // Act services.ConfigureRazorViewEngine(options => { options.FileProvider = fileProvider; }); var serviceProvider = services.BuildServiceProvider(); // Assert var accessor = serviceProvider.GetRequiredService<IOptions<RazorViewEngineOptions>>(); Assert.Same(fileProvider, accessor.Options.FileProvider); }
public void AddRazorOptions_ConfiguresOptionsAsExpected() { // Arrange var services = new ServiceCollection().AddOptions(); var fileProvider = new TestFileProvider(); // Act var builder = new MvcBuilder(services); builder.AddRazorOptions(options => { options.FileProviders.Add(fileProvider); }); var serviceProvider = services.BuildServiceProvider(); // Assert var accessor = serviceProvider.GetRequiredService<IOptions<RazorViewEngineOptions>>(); Assert.Same(fileProvider, accessor.Value.FileProviders[0]); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = GetType(); 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 InjectVisitorWithSemicolon_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultCodeTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping(7, 0, 7, 222, 6, 7, 7), BuildLineMapping(24, 1, 8, 729, 26, 8, 20), BuildLineMapping(58, 2, 8, 941, 34, 8, 23), BuildLineMapping(93, 3, 8, 1156, 42, 8, 21), BuildLineMapping(129, 4, 8, 1369, 50, 8, 24), }; // Act and Assert RunDesignTimeTest(host, "InjectWithSemicolon", expectedLineMappings); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), fileProvider); var fileInfo = new TestFileInfo { LastModified = DateTime.FromFileTimeUtc(10000) }; var type = GetType(); var expected = UncachedCompilationResult.Successful(type, "hello world"); var runtimeFileInfo = new RelativeFileInfo(fileInfo, "ab"); // Act var actual = cache.GetOrAdd(runtimeFileInfo, _ => expected); // Assert Assert.Same(expected, actual); Assert.Equal("hello world", actual.CompiledContent); Assert.Same(type, actual.CompiledType); }
public void GetOrAdd_RecompilesFile_IfContentAndLengthAreChanged( Type resultViewType, long fileTimeUTC) { // Arrange var instance = (View)Activator.CreateInstance(resultViewType); var length = Encoding.UTF8.GetByteCount(instance.Content); var collection = new ViewCollection(); var fileProvider = new TestFileProvider(); var cache = new CompilerCache(new[] { new ViewCollection() }, fileProvider); var fileInfo = new TestFileInfo { Length = length, LastModified = DateTime.FromFileTimeUtc(fileTimeUTC), Content = instance.Content }; var runtimeFileInfo = new RelativeFileInfo(fileInfo, "ab"); var precompiledContent = new PreCompile().Content; var razorFileInfo = new RazorFileInfo { FullTypeName = typeof(PreCompile).FullName, Hash = RazorFileHash.GetHash(GetMemoryStream(precompiledContent)), LastModified = DateTime.FromFileTimeUtc(10000), Length = Encoding.UTF8.GetByteCount(precompiledContent), RelativePath = "ab", }; // Act var actual = cache.GetOrAdd(runtimeFileInfo, compile: _ => CompilationResult.Successful(resultViewType)); // Assert Assert.Equal(resultViewType, actual.CompiledType); }
public void GetOrAdd_IgnoresCachedValueIfFileIsIdentical_ButViewStartWasAdedSinceTheCacheWasCreated() { // Arrange var expectedType = typeof(RuntimeCompileDifferent); var lastModified = DateTime.UtcNow; var fileProvider = new TestFileProvider(); var collection = new ViewCollection(); var precompiledFile = collection.FileInfos[0]; precompiledFile.RelativePath = "Views\\home\\index.cshtml"; var cache = new CompilerCache(new[] { collection }, fileProvider); var testFile = new TestFileInfo { Content = new PreCompile().Content, LastModified = precompiledFile.LastModified, PhysicalPath = precompiledFile.RelativePath }; fileProvider.AddFile(precompiledFile.RelativePath, testFile); var relativeFile = new RelativeFileInfo(testFile, testFile.PhysicalPath); // Act 1 var actual1 = cache.GetOrAdd(relativeFile, compile: _ => { throw new Exception("should not be called"); }); // Assert 1 Assert.Equal(typeof(PreCompile), actual1.CompiledType); // Act 2 fileProvider.AddFile("Views\\_ViewStart.cshtml", ""); var actual2 = cache.GetOrAdd(relativeFile, compile: _ => CompilationResult.Successful(expectedType)); // Assert 2 Assert.Equal(expectedType, actual2.CompiledType); }
public void InjectVisitorWithModel_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping(7, 0, 7, 214, 6, 7, 7), BuildLineMapping(24, 1, 8, 731, 26, 8, 20), BuildLineMapping(54, 2, 8, 957, 34, 8, 23) }; // Act and Assert RunDesignTimeTest(host, "InjectWithModel", expectedLineMappings); }
public void InjectVisitor_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new List<LineMapping> { BuildLineMapping(1, 0, 1, 59, 3, 0, 17), BuildLineMapping(28, 1, 8, 706, 26, 8, 20) }; // Act and Assert RunDesignTimeTest(host, "Inject", expectedLineMappings); }
public void BasicVisitor_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 13, documentLineIndex: 0, documentCharacterIndex: 13, generatedAbsoluteIndex: 1269, generatedLineIndex: 32, generatedCharacterIndex: 13, contentLength: 4), BuildLineMapping( documentAbsoluteIndex: 43, documentLineIndex: 2, documentCharacterIndex: 5, generatedAbsoluteIndex: 1353, generatedLineIndex: 37, generatedCharacterIndex: 6, contentLength: 21), }; // Act and Assert RunDesignTimeTest(host, "Basic", expectedLineMappings); }
public void MvcRazorHost_ParsesAndGeneratesCodeForBasicScenarios(string scenarioName) { // Arrange var fileProvider = new TestFileProvider(); var host = new TestMvcRazorHost(new DefaultChunkTreeCache(fileProvider)); // Act and Assert RunRuntimeTest(host, scenarioName); }
public void MvcRazorHost_GeneratesTagHelperModelExpressionCode_DesignTime() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; var expectedLineMappings = new List<LineMapping> { BuildLineMapping(documentAbsoluteIndex: 7, documentLineIndex: 0, documentCharacterIndex: 7, generatedAbsoluteIndex: 444, generatedLineIndex: 12, generatedCharacterIndex: 7, contentLength: 8), BuildLineMapping(documentAbsoluteIndex: 33, documentLineIndex: 2, documentCharacterIndex: 14, generatedAbsoluteIndex: 823, generatedLineIndex: 25, generatedCharacterIndex: 14, contentLength: 85), BuildLineMapping(documentAbsoluteIndex: 139, documentLineIndex: 4, documentCharacterIndex: 17, generatedAbsoluteIndex: 2313, generatedLineIndex: 55, generatedCharacterIndex: 95, contentLength: 3), BuildLineMapping( documentAbsoluteIndex: 166, documentLineIndex: 5, documentCharacterIndex: 18, generatedAbsoluteIndex: 2626, generatedLineIndex: 61, generatedCharacterIndex: 87, contentLength: 5), }; // Act and Assert RunDesignTimeTest(host, testName: "ModelExpressionTagHelper", expectedLineMappings: expectedLineMappings); }
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 fileVersionProvider = new FileVersionProvider( fileProvider, new MemoryCache(new MemoryCacheOptions()), GetRequestPathBase()); // Act var result = fileVersionProvider.AddFileVersionToPath("/hello/world"); // Assert Assert.True(stream.Disposed); }
public void MvcRazorHost_EnablesInstrumentationByDefault() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)); // Act var instrumented = host.EnableInstrumentation; // Assert Assert.True(instrumented); }
private static CodeGeneratorContext CreateContext() { var fileProvider = new TestFileProvider(); return new CodeGeneratorContext( new ChunkGeneratorContext( new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)), "MyClass", "MyNamespace", string.Empty, shouldGenerateLinePragmas: true), new ErrorSink()); }
public void ModelVisitor_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); using (var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }) { host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 7, documentLineIndex: 0, documentCharacterIndex: 7, generatedAbsoluteIndex: 394, generatedLineIndex: 11, generatedCharacterIndex: 28, contentLength: 30), }; // Act and Assert RunDesignTimeTest(host, "Model", expectedLineMappings); } }
public void InjectVisitorWithSemicolon_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); using (var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }) { host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 7, documentLineIndex: 0, documentCharacterIndex: 7, generatedAbsoluteIndex: 399, generatedLineIndex: 11, generatedCharacterIndex: 28, contentLength: 7), BuildLineMapping( documentAbsoluteIndex: 24, documentLineIndex: 1, documentCharacterIndex: 8, generatedAbsoluteIndex: 771, generatedLineIndex: 25, generatedCharacterIndex: 8, contentLength: 20), BuildLineMapping( documentAbsoluteIndex: 58, documentLineIndex: 2, documentCharacterIndex: 8, generatedAbsoluteIndex: 1001, generatedLineIndex: 33, generatedCharacterIndex: 8, contentLength: 23), BuildLineMapping( documentAbsoluteIndex: 93, documentLineIndex: 3, documentCharacterIndex: 8, generatedAbsoluteIndex: 1234, generatedLineIndex: 41, generatedCharacterIndex: 8, contentLength: 21), BuildLineMapping( documentAbsoluteIndex: 129, documentLineIndex: 4, documentCharacterIndex: 8, generatedAbsoluteIndex: 1465, generatedLineIndex: 49, generatedCharacterIndex: 8, contentLength: 24), }; // Act and Assert RunDesignTimeTest(host, "InjectWithSemicolon", expectedLineMappings); } }
public void MvcRazorHost_GeneratesCorrectLineMappingsAndUsingStatementsForViewImports() { // Arrange var fileProvider = new TestFileProvider(); using (var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }) { host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 8, documentLineIndex: 0, documentCharacterIndex: 8, generatedAbsoluteIndex: 661, generatedLineIndex: 21, generatedCharacterIndex: 8, contentLength: 26), }; // Act and Assert RunDesignTimeTest(host, "_ViewImports", expectedLineMappings); } }
public void MvcRazorHost_GeneratesTagHelperModelExpressionCode_DesignTime() { // Arrange var fileProvider = new TestFileProvider(); using (var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }) { var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 33, documentLineIndex: 2, documentCharacterIndex: 14, generatedAbsoluteIndex: 590, generatedLineIndex: 16, generatedCharacterIndex: 48, contentLength: 83), BuildLineMapping( documentAbsoluteIndex: 7, documentLineIndex: 0, documentCharacterIndex: 7, generatedAbsoluteIndex: 764, generatedLineIndex: 18, generatedCharacterIndex: 28, contentLength: 8), BuildLineMapping( documentAbsoluteIndex: 137, documentLineIndex: 4, documentCharacterIndex: 17, generatedAbsoluteIndex: 2180, generatedLineIndex: 47, generatedCharacterIndex: 95, contentLength: 3), BuildLineMapping( documentAbsoluteIndex: 164, documentLineIndex: 5, documentCharacterIndex: 18, generatedAbsoluteIndex: 2501, generatedLineIndex: 53, generatedCharacterIndex: 87, contentLength: 5), }; // Act and Assert RunDesignTimeTest( host, testName: "ModelExpressionTagHelper", expectedLineMappings: expectedLineMappings); } }
public void InjectVisitorWithModel_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping( documentAbsoluteIndex: 7, documentLineIndex: 0, documentCharacterIndex: 7, generatedAbsoluteIndex: 214, generatedLineIndex: 6, generatedCharacterIndex: 7, contentLength: 7), BuildLineMapping( documentAbsoluteIndex: 24, documentLineIndex: 1, documentCharacterIndex: 8, generatedAbsoluteIndex: 731, generatedLineIndex: 26, generatedCharacterIndex: 8, contentLength: 20), BuildLineMapping( documentAbsoluteIndex: 54, documentLineIndex: 2, documentCharacterIndex: 8, generatedAbsoluteIndex: 957, generatedLineIndex: 34, generatedCharacterIndex: 8, contentLength: 23), }; // Act and Assert RunDesignTimeTest(host, "InjectWithModel", expectedLineMappings); }
public void InjectVisitorWithSemicolon_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping(7, 0, 7, 222, 6, 7, 7), BuildLineMapping(24, 1, 8, 747, 26, 8, 20), BuildLineMapping(58, 2, 8, 977, 34, 8, 23), BuildLineMapping(93, 3, 8, 1210, 42, 8, 21), BuildLineMapping(129, 4, 8, 1441, 50, 8, 24), }; // Act and Assert RunDesignTimeTest(host, "InjectWithSemicolon", expectedLineMappings); }
public void ModelVisitor_GeneratesCorrectLineMappings() { // Arrange var fileProvider = new TestFileProvider(); var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }; host.NamespaceImports.Clear(); var expectedLineMappings = new[] { BuildLineMapping(7, 0, 7, 194, 6, 7, 30), }; // Act and Assert RunDesignTimeTest(host, "Model", expectedLineMappings); }
public void GetOrAdd_IgnoresCachedValueIfFileIsIdentical_ButGlobalWasDeletedSinceCacheWasCreated() { // Arrange var expectedType = typeof(RuntimeCompileDifferent); var lastModified = DateTime.UtcNow; var fileProvider = new TestFileProvider(); var viewCollection = new ViewCollection(); var precompiledView = viewCollection.FileInfos[0]; precompiledView.RelativePath = "Views\\Index.cshtml"; var viewFileInfo = new TestFileInfo { Content = new PreCompile().Content, LastModified = precompiledView.LastModified, PhysicalPath = precompiledView.RelativePath }; fileProvider.AddFile(viewFileInfo.PhysicalPath, viewFileInfo); var globalFileInfo = new TestFileInfo { PhysicalPath = "Views\\_GlobalImport.cshtml", Content = "viewstart-content", LastModified = lastModified }; var globalFile = new RazorFileInfo { FullTypeName = typeof(RuntimeCompileIdentical).FullName, RelativePath = globalFileInfo.PhysicalPath, LastModified = globalFileInfo.LastModified, Hash = RazorFileHash.GetHash(globalFileInfo, hashAlgorithmVersion: 1), HashAlgorithmVersion = 1, Length = globalFileInfo.Length }; fileProvider.AddFile(globalFileInfo.PhysicalPath, globalFileInfo); viewCollection.Add(globalFile); var cache = new CompilerCache(new[] { viewCollection }, TestLoadContext, fileProvider); // Act 1 var result1 = cache.GetOrAdd(viewFileInfo.PhysicalPath, compile: _ => { throw new Exception("should not be called"); }); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); var actual1 = result1.CompilationResult; Assert.NotNull(actual1); Assert.Equal(typeof(PreCompile), actual1.CompiledType); // Act 2 var trigger = fileProvider.GetTrigger(globalFileInfo.PhysicalPath); trigger.IsExpired = true; var result2 = cache.GetOrAdd(viewFileInfo.PhysicalPath, compile: _ => CompilationResult.Successful(expectedType)); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); var actual2 = result2.CompilationResult; Assert.NotNull(actual2); Assert.Equal(expectedType, actual2.CompiledType); }
public void ModelVisitor_GeneratesLineMappingsForLastModel_WhenMultipleModelsArePresent() { // Arrange var fileProvider = new TestFileProvider(); using (var host = new MvcRazorHostWithNormalizedNewLine(new DefaultChunkTreeCache(fileProvider)) { DesignTimeMode = true }) { host.NamespaceImports.Clear(); var inputFile = "TestFiles/Input/MultipleModels.cshtml"; var outputFile = "TestFiles/Output/DesignTime/MultipleModels.cs"; var expectedCode = ResourceFile.ReadResource(_assembly, outputFile, sourceFile: false); // Act GeneratorResults results; using (var stream = ResourceFile.GetResourceStream(_assembly, inputFile, sourceFile: true)) { results = host.GenerateCode(inputFile, stream); } // Assert Assert.False(results.Success); var parserError = Assert.Single(results.ParserErrors); Assert.Equal("Only one 'model' statement is allowed in a file.", parserError.Message); #if GENERATE_BASELINES ResourceFile.UpdateFile(_assembly, outputFile, expectedCode, results.GeneratedCode); #else Assert.Equal(expectedCode, results.GeneratedCode, ignoreLineEndingDifferences: true); #endif } }
public void AddFileVersionToPath_UpdatesEntryWhenCacheExpires_ForExistingFile_WithRequestPathBase() { // Arrange var fileProvider = new TestFileProvider(); var fileVersionProvider = new FileVersionProvider( fileProvider, new MemoryCache(new MemoryCacheOptions()), GetRequestPathBase("/wwwroot/")); fileProvider.AddFile("file.txt", "Hello World!"); // Act 1 - File exists var result = fileVersionProvider.AddFileVersionToPath("/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("/wwwroot/file.txt"); // Assert 2 Assert.Equal("/wwwroot/file.txt", result); }