public void GetHierarchicalItems_Works() { // Arrange var projectSystem = new VirtualRazorProjectFileSystem(); var viewImport1 = new TestRazorProjectItem("/_ViewImports.cshtml"); var viewImport2 = new TestRazorProjectItem("/Views/Home/_ViewImports.cshtml"); projectSystem.Add(viewImport1); projectSystem.Add(viewImport2); // Act var items = projectSystem.FindHierarchicalItems("/", "/Views/Home/Index.cshtml", "_ViewImports.cshtml"); // Assert Assert.Collection( items, item => Assert.Same(viewImport2, item), item => Assert.False(item.Exists), item => Assert.Same(viewImport1, item)); }
private static RazorCodeDocument GetCodeDocument(TestRazorProjectItem projectItem, TestRazorProjectItem imports = null) { var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(projectItem); var codeDocument = RazorCodeDocument.Create(sourceDocument); if (imports != null) { fileSystem.Add(imports); codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { RazorSourceDocument.ReadFrom(imports) }); } var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; razorEngine.Process(codeDocument); return(codeDocument); }
public void EnumerateItems_AtSubDirectory_ReturnsAllFilesUnderDirectoryHierarchy() { // Arrange var projectSystem = new VirtualRazorProjectFileSystem(); var file1 = new TestRazorProjectItem("/subDirectory/dir2/file1.cshtml"); var file2 = new TestRazorProjectItem("/file2.cshtml"); var file3 = new TestRazorProjectItem("/dir3/file3.cshtml"); var file4 = new TestRazorProjectItem("/subDirectory/file4.cshtml"); projectSystem.Add(file1); projectSystem.Add(file2); projectSystem.Add(file3); projectSystem.Add(file4); // Act var result = projectSystem.EnumerateItems("/subDirectory"); // Assert Assert.Equal(new[] { file4, file1 }, result); }
public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk() { // Arrange var imports = new List <RazorProjectItem>(); var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml"); var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem }); var mvcImportFeature = new MvcImportProjectFeature() { ProjectEngine = Mock.Of <RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem) }; // Act mvcImportFeature.AddHierarchicalImports(projectItem, imports); // Assert Assert.Collection(imports, import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath), import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath)); }
private static RazorSyntaxTree GetSyntaxTree(StringTextSnapshot source, IEnumerable <DirectiveDescriptor> directives = null) { directives = directives ?? Enumerable.Empty <DirectiveDescriptor>(); var engine = RazorProjectEngine.Create(builder => { foreach (var directive in directives) { builder.AddDirective(directive); } }); var sourceProjectItem = new TestRazorProjectItem("test.cshtml") { Content = source.GetText() }; var codeDocument = engine.ProcessDesignTime(sourceProjectItem); return(codeDocument.GetSyntaxTree()); }
public void ProcessDesignTime_SetsOptions_DesignTime() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.ProcessDesignTime(projectItem); // Assert var parserOptions = codeDocument.GetParserOptions(); Assert.True(parserOptions.DesignTime); var codeGenerationOptions = codeDocument.GetCodeGenerationOptions(); Assert.True(codeGenerationOptions.DesignTime); Assert.True(codeGenerationOptions.SuppressChecksum); Assert.True(codeGenerationOptions.SuppressMetadataAttributes); }
public void CSharpDocument_DesignTime_PreservesParserErrors() { // Arrange var projectEngine = CreateProjectEngine(); var projectItem = new TestRazorProjectItem("test.cshtml") { Content = "@{" }; var expected = RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF( new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"); // Act var codeDocument = projectEngine.ProcessDesignTime(projectItem); // Assert var csharpDocument = codeDocument.GetCSharpDocument(); var error = Assert.Single(csharpDocument.Diagnostics); Assert.Equal(expected, error); }
public void GetCompilationFailedResult_ReadsContentFromImports() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var importsPath = "/Views/_MyImports.cshtml"; var fileContent = "@ "; var importsContent = "@(abc"; var projectItem = new TestRazorProjectItem(viewPath, fileContent); var importsItem = new TestRazorProjectItem(importsPath, importsContent); var codeDocument = GetCodeDocument(projectItem, importsItem); var csharpDocument = codeDocument.GetCSharpDocument(); // Act var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert Assert.Collection( compilationResult.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Collection(failure.Messages, message => { Assert.Equal(@"A space or line break was encountered after the ""@"" character. Only valid identifiers, keywords, comments, ""("" and ""{"" are valid at the start of a code block and they must occur immediately following ""@"" with no space in between.", message.Message); }); }, failure => { Assert.Equal(importsPath, failure.SourceFilePath); Assert.Collection(failure.Messages, message => { Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.", message.Message); }); }); }
public void GenerateCodeWithSetNamespace() { // Arrange var filePath = Path.Combine(TestProjectRoot, $"{FileName}.cshtml"); var content = File.ReadAllText(filePath); var projectItem = new TestRazorProjectItem($"{FileName}.cshtml", "") { Content = content, }; var project = new TestRazorProject(new[] { projectItem }); var razorEngine = RazorEngine.Create(engine => { engine.SetNamespace("MyApp.Razor.Views"); }); var templateEngine = new RazorTemplateEngine(razorEngine, project); // Act var cSharpDocument = templateEngine.GenerateCode(projectItem.FilePath); // Assert AssertCSharpDocumentMatchesBaseline(cSharpDocument); }
public void EnumerateItems_ReturnsResultsFromAllFileSystems() { // Arrange var basePath = "base-path"; var file1 = new TestRazorProjectItem("file1"); var file2 = new TestRazorProjectItem("file2"); var file3 = new TestRazorProjectItem("file3"); var fileSystem1 = Mock.Of <RazorProjectFileSystem>( f => f.EnumerateItems(basePath) == new[] { file1 }); var fileSystem2 = Mock.Of <RazorProjectFileSystem>( f => f.EnumerateItems(basePath) == Enumerable.Empty <RazorProjectItem>()); var fileSystem3 = Mock.Of <RazorProjectFileSystem>( f => f.EnumerateItems(basePath) == new[] { file2, file3, }); var compositeRazorProjectFileSystem = new CompositeRazorProjectFileSystem(new[] { fileSystem1, fileSystem2, fileSystem3 }); // Act var result = compositeRazorProjectFileSystem.EnumerateItems(basePath); // Assert Assert.Equal(new[] { file1, file2, file3 }, result); }
public void CSharpDocument_Runtime_PreservesParserErrors() { // Arrange var projectEngine = CreateProjectEngine(); var projectItem = new TestRazorProjectItem("test.cshtml") { Content = "@!!!" }; var expected = RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock( new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1), "!"); // Act var codeDocument = projectEngine.Process(projectItem); // Assert var csharpDocument = codeDocument.GetCSharpDocument(); var error = Assert.Single(csharpDocument.Diagnostics); Assert.Equal(expected, error); }
public void GetItem_ReturnsFirstInstanceThatExists() { // Arrange var basePath = "base-path"; var filePath = "file-path"; var file1 = new NotFoundProjectItem(basePath, filePath, fileKind: null); var file2 = new TestRazorProjectItem(filePath); RazorProjectItem nullItem = null; var fileSystem1 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == file1); var fileSystem2 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == nullItem); var fileSystem3 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == file2); var compositeRazorProjectFileSystem = new CompositeRazorProjectFileSystem(new[] { fileSystem1, fileSystem2, fileSystem3 }); // Act var result = compositeRazorProjectFileSystem.GetItem(filePath, fileKind: null); // Assert Assert.Same(file2, result); }
private static RazorCodeDocument GetCodeDocument(string source) { var taghelper = TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") .BoundAttributeDescriptor(attr => attr.Name("show").TypeName("System.Boolean")) .BoundAttributeDescriptor(attr => attr.Name("id").TypeName("System.Int32")) .TagMatchingRuleDescriptor(rule => rule.RequireTagName("taghelper")) .TypeName("TestTagHelper") .Build(); var engine = RazorProjectEngine.Create(builder => { builder.AddTagHelpers(taghelper); builder.SetImportFeature(new TestImportProjectFeature()); }); var sourceProjectItem = new TestRazorProjectItem("test.cshtml") { Content = source }; var codeDocument = engine.ProcessDesignTime(sourceProjectItem); return(codeDocument); }
public void ProcessDesignTime_WithImportsAndTagHelpers_SetsOnCodeDocument() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var importItem = new TestRazorProjectItem("_import.cshtml"); var expectedImports = new[] { RazorSourceDocument.ReadFrom(importItem) }; var expectedTagHelpers = new[] { TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly").Build(), TagHelperDescriptorBuilder.Create("Test2TagHelper", "TestAssembly").Build(), }; var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.ProcessDesignTime(RazorSourceDocument.ReadFrom(projectItem), "test", expectedImports, expectedTagHelpers); // Assert var tagHelpers = codeDocument.GetTagHelpers(); Assert.Same(expectedTagHelpers, tagHelpers); Assert.Equal(expectedImports, codeDocument.Imports); }
public void CreateCodeDocument_SetsRelativePathOnOutput() { // Arrange var path = "/Views/Home/Index.cshtml"; var item = new TestRazorProjectItem(path) { Content = "Hello world", }; var project = new TestRazorProject(new List <RazorProjectItem>() { item, }); var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( RazorEngine.Create(), project); // Act var codeDocument = mvcRazorTemplateEngine.CreateCodeDocument(path); // Assert Assert.Equal(path, codeDocument.GetRelativePath()); }
public void TagHelperAttributesAreLocatedAndAcceptChangesCorrectly(object editObject, object partialParseResultObject) { // Arrange var edit = (TestEdit)editObject; var partialParseResult = (PartialParseResultInternal)partialParseResultObject; var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "Test"); builder.SetTypeName("PTagHelper"); builder.TagMatchingRule(rule => rule.TagName = "p"); builder.BindAttribute(attribute => { attribute.Name = "obj-attr"; attribute.TypeName = typeof(object).FullName; attribute.SetPropertyName("ObjectAttribute"); }); builder.BindAttribute(attribute => { attribute.Name = "str-attr"; attribute.TypeName = typeof(string).FullName; attribute.SetPropertyName("StringAttribute"); }); var descriptors = new[] { builder.Build() }; var projectEngine = CreateProjectEngine(tagHelpers: descriptors); var sourceDocument = new TestRazorProjectItem("Index.cshtml") { Content = edit.OldSnapshot.GetText() }; var codeDocument = projectEngine.Process(sourceDocument); var syntaxTree = codeDocument.GetSyntaxTree(); var parser = new RazorSyntaxTreePartialParser(syntaxTree); // Act var result = parser.Parse(edit.Change); // Assert Assert.Equal(partialParseResult, result); }
public void DirectoryNode_AddsFiles_ToSiblingDirectories() { // Arrange var root = new DirectoryNode("/"); var projectItem1 = new TestRazorProjectItem("/Pages/Products/Index.cshtml"); var projectItem2 = new TestRazorProjectItem("/Pages/Accounts/About.cshtml"); // Act root.AddFile(new FileNode(projectItem1.FilePath, projectItem1)); root.AddFile(new FileNode(projectItem2.FilePath, projectItem2)); // Assert Assert.Collection( root.Directories, directory => { Assert.Equal("/Pages/", directory.Path); Assert.Empty(directory.Files); Assert.Collection( directory.Directories, subDirectory => { Assert.Equal("/Pages/Products/", subDirectory.Path); Assert.Collection( subDirectory.Files, file => Assert.Same(projectItem1, file.ProjectItem)); }, subDirectory => { Assert.Equal("/Pages/Accounts/", subDirectory.Path); Assert.Collection( subDirectory.Files, file => Assert.Same(projectItem2, file.ProjectItem)); }); }); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (_inner is null) { return(Array.Empty <RazorProjectItem>()); } var normalizedImports = new List <RazorProjectItem>(); var imports = _inner.GetImports(projectItem); foreach (var import in imports) { if (import.Exists) { var text = string.Empty; using (var stream = import.Read()) using (var reader = new StreamReader(stream)) { text = reader.ReadToEnd().Trim(); } // It's important that we normalize the newlines in the default imports. The default imports will // be created with Environment.NewLine, but we need to normalize to `\r\n` so that the indices // are the same on xplat. var normalizedText = NormalizeNewLines(text, _lineEnding); var normalizedImport = new TestRazorProjectItem(import.FilePath, import.PhysicalPath, import.RelativePhysicalPath, import.BasePath) { Content = normalizedText }; normalizedImports.Add(normalizedImport); } } return(normalizedImports); }
public void GetCompilationFailedResult_ReadsContentFromSourceDocuments() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var fileContent = @" @if (User.IsAdmin) { <span> } </span>"; var projectItem = new TestRazorProjectItem(viewPath, fileContent); var codeDocument = GetCodeDocument(projectItem); var csharpDocument = codeDocument.GetCSharpDocument(); // Act var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert var failure = Assert.Single(compilationResult.CompilationFailures); Assert.Equal(fileContent, failure.SourceFileContent); }
private DocumentSnapshot CreateRazorDocumentSnapshot(RazorProjectEngine projectEngine, TestRazorProjectItem item, string rootNamespaceName, IReadOnlyList <TagHelperDescriptor> tagHelpers) { var codeDocument = projectEngine.ProcessDesignTime(item); var namespaceNode = (NamespaceDeclarationIntermediateNode)codeDocument .GetDocumentIntermediateNode() .FindDescendantNodes <IntermediateNode>() .FirstOrDefault(n => n is NamespaceDeclarationIntermediateNode); namespaceNode.Content = rootNamespaceName; var sourceText = SourceText.From(new string(item.Content)); var projectWorkspaceState = new ProjectWorkspaceState(tagHelpers, LanguageVersion.Default); var projectSnapshot = TestProjectSnapshot.Create("C:/project.csproj", projectWorkspaceState); var documentSnapshot = Mock.Of <DocumentSnapshot>(d => d.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) && d.FilePath == item.FilePath && d.FileKind == FileKinds.Component && d.GetTextAsync() == Task.FromResult(sourceText) && d.Project == projectSnapshot, MockBehavior.Strict); return(documentSnapshot); }