123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- using Microsoft.AspNetCore.StaticWebAssets.Tasks;
- using Microsoft.Build.Framework;
- using Moq;
- using static Microsoft.AspNetCore.StaticWebAssets.Tasks.GenerateStaticWebAssetsDevelopmentManifest;
- namespace Microsoft.NET.Sdk.Razor.Tests
- {
- public class GenerateStaticWebAssetsDevelopmentManifestTest
- {
- [Fact]
- public void SkipsManifestGenerationWhen_ThereAreNoAssetsNorDiscoveryPatterns()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Assets = Array.Empty<ITaskItem>(),
- DiscoveryPatterns = Array.Empty<ITaskItem>()
- };
- // Act
- var result = task.Execute();
- // Assert
- result.Should().BeTrue();
- messages.Should().HaveCount(1);
- }
- [Fact]
- public void ComputeDevelopmentManifest_IncludesBuildAssets()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("index.html", CreateMatchNode(0, "index.html"))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- };
- var assets = new[] { CreateAsset("index.html", "index.html", assetKind: StaticWebAsset.AssetKinds.Build) };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_IncludesAllAssets()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("index.html", CreateMatchNode(0, "index.html"))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- };
- var assets = new[] { CreateAsset("index.html", "index.html", assetKind: StaticWebAsset.AssetKinds.All) };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_ExcludesPublishAssets()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode());
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- };
- var assets = new[] { CreateAsset("index.html", "index.html", assetKind: StaticWebAsset.AssetKinds.Publish) };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_ExcludesReferenceAssets()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode());
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[] { CreateAsset("index.html", "index.html", assetMode: StaticWebAsset.AssetModes.Reference) };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_PrefersBuildAssetsOverAllAssets()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("index.html", CreateMatchNode(0, "index.build.html"))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[] {
- CreateAsset("index.build.html", "index.html", assetKind: StaticWebAsset.AssetKinds.Build),
- CreateAsset("index.html", "index.html", assetKind: StaticWebAsset.AssetKinds.All)
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_UsesIdentityWhenContentRootStartsByIdentity()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("index.html", CreateMatchNode(0, StaticWebAsset.Normalize(Path.Combine("some", "subfolder", "index.build.html"))))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[] {
- CreateAsset(Path.Combine("some", "subfolder", "index.build.html"), "index.html"),
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_UsesRelativePathContentRootDoesNotStartByIdentity()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("index.html", CreateMatchNode(0, "index.html"))),
- Path.GetFullPath(Path.Combine("bin", "debug", "wwwroot")));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[] {
- CreateAsset(Path.Combine("some", "subfolder", "index.build.html"), "index.html", contentRoot: Path.Combine("bin", "debug", "wwwroot")),
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_MapsPatternsFromCurrentProject()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode()
- .AddPatterns((0, "**", 0)),
- Path.GetFullPath("wwwroot"));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = Array.Empty<StaticWebAsset>();
- var patterns = new[] { CreatePattern() };
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_MapsPatternsFromOtherProjects()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("_other", CreateIntermediateNode(
- ("_project", CreateIntermediateNode().AddPatterns((0, "**", 2)))))),
- Path.GetFullPath("wwwroot"));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = Array.Empty<StaticWebAsset>();
- var patterns = new[] { CreatePattern(basePath: "_other/_project", source: "OtherProject") };
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_CanMapMultiplePatternsOnSameNode()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("_other", CreateIntermediateNode(
- ("_project", CreateIntermediateNode().AddPatterns(
- (0, "*.js", 2),
- (0, "*.css", 2)))))),
- Path.GetFullPath("wwwroot"));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = Array.Empty<StaticWebAsset>();
- var patterns = new[]
- {
- CreatePattern(basePath: "_other/_project", source: "OtherProject", pattern: "*.js"),
- CreatePattern(basePath: "_other/_project", source: "OtherProject", pattern: "*.css")
- };
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_CanMapMultiplePatternsOnSameNodeWithDifferentContentRoots()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("_other", CreateIntermediateNode(
- ("_project", CreateIntermediateNode().AddPatterns(
- (0, "*.js", 2),
- (1, "*.css", 2)))))),
- Path.GetFullPath("wwwroot"),
- Path.GetFullPath("styles"));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = Array.Empty<StaticWebAsset>();
- var patterns = new[]
- {
- CreatePattern(basePath: "_other/_project", source: "OtherProject", pattern: "*.js"),
- CreatePattern(basePath: "_other/_project", source: "OtherProject", pattern: "*.css", contentRoot: Path.GetFullPath("styles"))
- };
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_MultipleAssetsSameContentRoot()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("css", CreateIntermediateNode(("site.css", CreateMatchNode(0, "css/site.css")))),
- ("js", CreateIntermediateNode(("index.js", CreateMatchNode(0, "js/index.js"))))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[]
- {
- CreateAsset(Path.Combine(Environment.CurrentDirectory, "css", "site.css"), "css/site.css"),
- CreateAsset(Path.Combine(Environment.CurrentDirectory, "js", "index.js"), "js/index.js")
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_DifferentCasingEndUpInDifferentNodes()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("css", CreateIntermediateNode(("site.css", CreateMatchNode(0, "css/site.css")))),
- ("CSS", CreateIntermediateNode(("site.css", CreateMatchNode(0, "CSS/site.css"))))),
- Environment.CurrentDirectory);
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[]
- {
- CreateAsset(Path.Combine(Environment.CurrentDirectory, "css", "site.css"), "css/site.css"),
- CreateAsset(Path.Combine(Environment.CurrentDirectory, "CSS", "site.css"), "CSS/site.css"),
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- [Fact]
- public void ComputeDevelopmentManifest_UsesBasePathForAssetsFromDifferentProjects()
- {
- // Arrange
- var messages = new List<string>();
- var buildEngine = new Mock<IBuildEngine>();
- buildEngine.Setup(e => e.LogMessageEvent(It.IsAny<BuildMessageEventArgs>()))
- .Callback<BuildMessageEventArgs>(args => messages.Add(args.Message));
- var expectedManifest = CreateExpectedManifest(
- CreateIntermediateNode(
- ("css", CreateIntermediateNode(("site.css", CreateMatchNode(0, "css/site.css")))),
- ("_content", CreateIntermediateNode(
- ("OtherProject", CreateIntermediateNode(
- ("CSS", CreateIntermediateNode(("site.css", CreateMatchNode(1, "CSS/site.css"))))))))),
- Environment.CurrentDirectory,
- Path.GetFullPath("otherProject"));
- var task = new GenerateStaticWebAssetsDevelopmentManifest()
- {
- BuildEngine = buildEngine.Object,
- Source = "CurrentProjectId"
- };
- var assets = new[]
- {
- CreateAsset(Path.Combine(Environment.CurrentDirectory, "css", "site.css"), "css/site.css"),
- CreateAsset(
- Path.Combine(Environment.CurrentDirectory, "CSS", "site.css"),
- "CSS/site.css",
- basePath: "_content/OtherProject",
- sourceType: "Project",
- contentRoot: Path.GetFullPath("otherProject")),
- };
- var patterns = Array.Empty<StaticWebAssetsDiscoveryPattern>();
- // Act
- var manifest = task.ComputeDevelopmentManifest(assets, patterns);
- // Assert
- manifest.Should().BeEquivalentTo(expectedManifest);
- }
- private static StaticWebAssetsDiscoveryPattern CreatePattern(
- string name = null,
- string contentRoot = null,
- string pattern = null,
- string basePath = null,
- string source = null) =>
- new()
- {
- Name = name ?? "CurrentProjectId\\wwwroot",
- Pattern = pattern ?? "**",
- BasePath = basePath ?? "_content/CurrentProjectId",
- Source = source ?? "CurrentProjectId",
- ContentRoot = StaticWebAsset.NormalizeContentRootPath(contentRoot ?? Path.Combine(Environment.CurrentDirectory, "wwwroot"))
- };
- private static StaticWebAssetsDevelopmentManifest CreateExpectedManifest(StaticWebAssetNode root, params string[] contentRoots)
- {
- return new StaticWebAssetsDevelopmentManifest()
- {
- ContentRoots = contentRoots.Select(cr => StaticWebAsset.NormalizeContentRootPath(cr)).ToArray(),
- Root = root
- };
- }
- private static StaticWebAssetNode CreateIntermediateNode(params (string key, StaticWebAssetNode node)[] children) => new()
- {
- Children = children.Length == 0 ? null : children.ToDictionary(pair => pair.key, pair => pair.node)
- };
- private static StaticWebAssetNode CreateMatchNode(int index, string subpath) => new()
- {
- Asset = new StaticWebAssetMatch { ContentRootIndex = index, SubPath = subpath }
- };
- private StaticWebAsset CreateAsset(
- string identity,
- string relativePath,
- string assetKind = default,
- string assetMode = default,
- string sourceId = default,
- string sourceType = default,
- string basePath = default,
- string contentRoot = default)
- {
- return new StaticWebAsset()
- {
- Identity = Path.GetFullPath(identity),
- SourceId = sourceId ?? "CurrentProjectId",
- SourceType = sourceType ?? StaticWebAsset.SourceTypes.Discovered,
- BasePath = basePath ?? "_content/Base",
- RelativePath = relativePath,
- AssetKind = assetKind ?? StaticWebAsset.AssetKinds.All,
- AssetMode = assetMode ?? StaticWebAsset.AssetModes.All,
- AssetRole = StaticWebAsset.AssetRoles.Primary,
- ContentRoot = StaticWebAsset.NormalizeContentRootPath(contentRoot ?? Environment.CurrentDirectory),
- OriginalItemSpec = identity
- };
- }
- }
- internal static class StaticWebAssetNodeTestExtensions
- {
- public static StaticWebAssetNode AddPatterns(this StaticWebAssetNode node, params (int contentRoot, string pattern, int depth)[] patterns)
- {
- node.Patterns = patterns.Select(p => new StaticWebAssetPattern { ContentRootIndex = p.contentRoot, Pattern = p.pattern, Depth = p.depth }).ToArray();
- return node;
- }
- }
- }
|