From 0e1881a8208fceb4bcad090340bc8d2b9ba151c4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Sep 2025 11:29:27 +0000
Subject: [PATCH 1/6] URL encode PackageId in scoped CSS asset paths to fix
non-ASCII project names
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
---
....NET.Sdk.StaticWebAssets.ScopedCss.targets | 10 +++----
.../ScopedCssIntegrationTests.cs | 30 +++++++++++++++++++
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
index e74f0589b497..6a415883af2f 100644
--- a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
+++ b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
@@ -233,18 +233,18 @@ Integration with static web assets:
<_ScopedCssAppBundleStaticWebAssetCandidate Include="$(_ScopedCssOutputPath)">
- $(PackageId)#[.{fingerprint}]?.styles.css
- $(PackageId).styles.css
+ $([System.Uri]::EscapeDataString($(PackageId)))#[.{fingerprint}]?.styles.css
+ $([System.Uri]::EscapeDataString($(PackageId))).styles.css
<_ScopedCssProjectBundleStaticWebAssetCandidate Include="$(_ScopedCssProjectOutputPath)">
- $(PackageId)#[.{fingerprint}]!.bundle.scp.css
- $(PackageId).bundle.scp.css
+ $([System.Uri]::EscapeDataString($(PackageId)))#[.{fingerprint}]!.bundle.scp.css
+ $([System.Uri]::EscapeDataString($(PackageId))).bundle.scp.css
<_AddLinkHeaderToAppBundle Include="Append" Condition="'@(_ResolvedScopedCssBundleEndpoints)' != ''">
Header
Link
- @(_ResolvedScopedCssBundleEndpoints->'<%(Identity)>; rel="preload"; as="style"', ', ')
+ @(_ResolvedScopedCssBundleEndpoints->'<$([System.Uri]::EscapeDataString(%(Identity)))>; rel="preload"; as="style"', ', ')
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
index 9668d8656913..c6a7fd8830ed 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
@@ -617,5 +617,35 @@ public void RegeneratingScopedCss_ForProjectWithReferences()
text.Should().Contain("background-color: orangered");
text.Should().MatchRegex(""".*@import '_content/ClassLibrary/ClassLibrary\.[a-zA-Z0-9]+\.bundle\.scp\.css.*""");
}
+
+ [Fact]
+ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
+ {
+ var testAsset = "RazorComponentApp";
+ var projectDirectory = CreateAspNetSdkTestAsset(testAsset);
+
+ // Create a CSS file to trigger scoped CSS processing
+ var cssFile = Path.Combine(projectDirectory.Path, "Components", "Pages", "Index.razor.css");
+ Directory.CreateDirectory(Path.GetDirectoryName(cssFile));
+ File.WriteAllText(cssFile, ".test { color: red; }");
+
+ var build = CreateBuildCommand(projectDirectory);
+ // Set PackageId to contain non-ASCII characters (Chinese characters meaning "project")
+ ExecuteCommand(build, "/p:PackageId=项目").Should().Pass();
+
+ var intermediateOutputPath = build.GetIntermediateDirectory(DefaultTfm, "Debug").ToString();
+
+ // Check that the staticwebassets.build.endpoints.json file contains URL-encoded characters
+ var endpointsFile = Path.Combine(intermediateOutputPath, "staticwebassets.build.endpoints.json");
+ new FileInfo(endpointsFile).Should().Exist();
+
+ var endpointsContent = File.ReadAllText(endpointsFile);
+
+ // Verify that the Link header contains URL-encoded characters (%E9%A1%B9%E7%9B%AE is "项目" encoded)
+ endpointsContent.Should().Contain("%E9%A1%B9%E7%9B%AE");
+
+ // Verify it doesn't contain the unencoded characters
+ endpointsContent.Should().NotContain("项目");
+ }
}
}
From dec378b3db1e2b7d37cfe1ed3a3a47ca5262c191 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Sep 2025 11:32:16 +0000
Subject: [PATCH 2/6] Final verification that URL encoding fix works correctly
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
---
.../ComputeStaticWebAssetsTargetPathsTest.cs | 1 +
.../JsModulesIntegrationTest.cs | 14 +++---
.../LegacyStaticWebAssetsV1IntegrationTest.cs | 2 +-
.../ScopedCssIntegrationTests.cs | 8 ++--
.../StaticWebAssetEndpointsIntegrationTest.cs | 48 +++++++++----------
.../DefineStaticWebAssetEndpointsTest.cs | 6 +--
.../DiscoverPrecompressedAssetsTest.cs | 2 +-
.../DiscoverStaticWebAssetsTest.cs | 8 ++--
.../FilterStaticWebAssetEndpointsTest.cs | 1 +
...rateStaticWebAssetEndpointsManifestTest.cs | 6 +--
...ateStaticWebAssetEndpointsPropsFileTest.cs | 2 +-
.../Globbing/StaticWebAssetGlobMatcherTest.cs | 46 +++++++++---------
.../OverrideHtmlAssetPlaceholdersTest.cs | 2 +-
.../ResolveCompressedAssetsTest.cs | 4 +-
...tedStaticWebAssetEndpointsForAssetsTest.cs | 2 +-
...ateExternallyDefinedStaticWebAssetsTest.cs | 2 +-
.../UpdateStaticWebAssetEndpointsTest.cs | 2 +-
.../StaticWebAssetsBaselineFactory.cs | 1 +
...aticWebAssetsCompressionIntegrationTest.cs | 2 +-
.../StaticWebAssetsFingerprintingTest.cs | 7 +--
.../StaticWebAssetsIntegrationTest.cs | 2 +-
21 files changed, 87 insertions(+), 81 deletions(-)
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
index 8bf1bafb89dd..114a097d7c63 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
@@ -13,6 +13,7 @@
using Moq;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
+
public class ComputeStaticWebAssetsTargetPathsTest
{
[Fact]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
index d96dab0d59e5..56ad90dfc8ed 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
@@ -31,11 +31,12 @@ public void Build_GeneratesManifestWhenItFindsALibrary()
{
var testAsset = "RazorComponentApp";
var projectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p => {
- var fingerprintContent = p.Descendants()
- .SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
- fingerprintContent.Value = "true";
- });
+ .WithProjectChanges(p =>
+ {
+ var fingerprintContent = p.Descendants()
+ .SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
+ fingerprintContent.Value = "true";
+ });
Directory.CreateDirectory(Path.Combine(projectDirectory.TestRoot, "wwwroot"));
File.WriteAllText(Path.Combine(projectDirectory.TestRoot, "wwwroot", "ComponentApp.lib.module.js"), "console.log('Hello world!');");
@@ -89,7 +90,8 @@ public void Publish_PublishesJsModuleBundleBundleToTheRightLocation()
{
var testAsset = "RazorComponentApp";
ProjectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p => {
+ .WithProjectChanges(p =>
+ {
var fingerprintContent = p.Descendants()
.SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
fingerprintContent.Value = "true";
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
index 9089ed148d04..248b025ac4a5 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
@@ -3,7 +3,7 @@
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
-[assembly:CollectionBehavior(DisableTestParallelization = true)]
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests
{
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
index c6a7fd8830ed..245976d4cabe 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
@@ -634,16 +634,16 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
ExecuteCommand(build, "/p:PackageId=项目").Should().Pass();
var intermediateOutputPath = build.GetIntermediateDirectory(DefaultTfm, "Debug").ToString();
-
+
// Check that the staticwebassets.build.endpoints.json file contains URL-encoded characters
var endpointsFile = Path.Combine(intermediateOutputPath, "staticwebassets.build.endpoints.json");
new FileInfo(endpointsFile).Should().Exist();
-
+
var endpointsContent = File.ReadAllText(endpointsFile);
-
+
// Verify that the Link header contains URL-encoded characters (%E9%A1%B9%E7%9B%AE is "项目" encoded)
endpointsContent.Should().Contain("%E9%A1%B9%E7%9B%AE");
-
+
// Verify it doesn't contain the unencoded characters
endpointsContent.Should().NotContain("项目");
}
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
index 79442747cab9..ade219c5f8f4 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
@@ -85,9 +85,9 @@ private bool MatchUncompresedProjectBundlesNoFingerprint(StaticWebAssetEndpoint
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: "", Success: false }
]
};
@@ -96,9 +96,9 @@ private bool MatchCompressedProjectBundlesNoFingerprint(StaticWebAssetEndpoint e
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: var compress, Success: true }
]
} && (compress == ".gz" || compress == ".br");
@@ -107,9 +107,9 @@ private bool MatchUncompressedProjectBundlesWithFingerprint(StaticWebAssetEndpoi
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: "", Success: false }
]
} && fingerprint == ep.EndpointProperties.Single(p => p.Name == "fingerprint").Value;
@@ -118,9 +118,9 @@ private bool MatchCompressedProjectBundlesWithFingerprint(StaticWebAssetEndpoint
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: var compress, Success: true }
]
} && !string.IsNullOrWhiteSpace(fingerprint)
&& (compress == ".gz" || compress == ".br");
@@ -130,9 +130,9 @@ private bool MatchUncompressedAppBundleNoFingerprint(StaticWebAssetEndpoint ep)
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: "", Success: false }
]
};
@@ -141,9 +141,9 @@ private bool MatchCompressedAppBundleNoFingerprint(StaticWebAssetEndpoint ep) =>
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: var compress, Success: true }
]
} && (compress == ".gz" || compress == ".br");
@@ -152,9 +152,9 @@ private bool MatchUncompressedAppBundleWithFingerprint(StaticWebAssetEndpoint ep
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: "", Success: false }
]
} && fingerprint == ep.EndpointProperties.Single(p => p.Name == "fingerprint").Value;
@@ -163,9 +163,9 @@ private bool MatchCompressedAppBundleWithFingerprint(StaticWebAssetEndpoint ep)
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: var compress, Success: true }
]
} && !string.IsNullOrWhiteSpace(fingerprint)
&& (compress == ".gz" || compress == ".br");
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
index dfb709b5865d..ccab6a4fe566 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
@@ -3,15 +3,15 @@
#nullable disable
-using System.Diagnostics.Metrics;
using System.Diagnostics;
+using System.Diagnostics.Metrics;
+using System.Globalization;
+using System.Net;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Moq;
using NuGet.Packaging.Core;
-using System.Net;
-using System.Globalization;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
index 27d7baae60f0..5eccf523e3e7 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
@@ -44,7 +44,7 @@ public void DiscoversPrecompressedAssetsCorrectly()
CopyToOutputDirectory = StaticWebAsset.AssetCopyOptions.Never,
Fingerprint = "uncompressed",
RelatedAsset = string.Empty,
- ContentRoot = Path.Combine(Environment.CurrentDirectory,"wwwroot"),
+ ContentRoot = Path.Combine(Environment.CurrentDirectory, "wwwroot"),
SourceType = StaticWebAsset.SourceTypes.Discovered,
Integrity = "uncompressed-integrity",
AssetRole = StaticWebAsset.AssetRoles.Primary,
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
index f252022d1338..e56d53b8b7d2 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
@@ -217,9 +217,9 @@ public void FingerprintsContentUsingPatternsWhenMoreThanOneExtension(string file
asset.GetMetadata(nameof(StaticWebAsset.OriginalItemSpec)).Should().Be(Path.Combine("wwwroot", fileName));
}
- [Fact]
- [Trait("Category", "FingerprintIdentity")]
- public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdentityNeedsComputation()
+ [Fact]
+ [Trait("Category", "FingerprintIdentity")]
+ public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdentityNeedsComputation()
{
// Arrange: simulate a packaged asset (outside content root) with a RelativePath inside the app
var errorMessages = new List();
@@ -251,7 +251,7 @@ public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdent
})
],
// No RelativePathPattern, we trigger the branch that synthesizes identity under content root.
- FingerprintPatterns = [ new TaskItem("Js", new Dictionary{{"Pattern","*.js"},{"Expression","#[.{fingerprint}]!"}})],
+ FingerprintPatterns = [new TaskItem("Js", new Dictionary { { "Pattern", "*.js" }, { "Expression", "#[.{fingerprint}]!" } })],
FingerprintCandidates = true,
SourceType = "Computed",
SourceId = "Client",
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
index 2cf9ee746d4e..7b8a19394706 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
@@ -9,6 +9,7 @@
using Moq;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests.StaticWebAssets;
+
public class FilterStaticWebAssetEndpointsTest
{
[Fact]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
index a278a732193a..6957302e4830 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
@@ -253,11 +253,11 @@ public void ExcludesEndpoints_BasedOnExclusionPatterns()
// Assert
new FileInfo(path).Should().Exist();
new FileInfo(exclusionCachePath).Should().Exist();
-
+
var manifest = File.ReadAllText(path);
var json = JsonSerializer.Deserialize(manifest);
json.Should().NotBeNull();
-
+
// Only styles.css endpoint should remain as others match _content/MyApp/**
json.Endpoints.Should().HaveCount(1);
json.Endpoints[0].Route.Should().Contain("styles.css");
@@ -406,7 +406,7 @@ public void RegeneratesManifest_WhenExclusionPatternsChange()
// Assert - File should be regenerated
var secondWriteTime = File.GetLastWriteTimeUtc(endpointsManifestPath);
secondWriteTime.Should().BeAfter(firstWriteTime);
-
+
// Verify cache file was updated
var cacheContent = File.ReadAllText(exclusionCachePath);
cacheContent.Should().Contain("different/**");
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
index 90135f0c14ca..6563cebc6bde 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
@@ -157,7 +157,7 @@ public void Fails_WhenEndpointWithoutAssetExists()
result.Should().BeFalse();
errorMessages.Should().ContainSingle();
- errorMessages[0].Should().Be($"""The asset file '{Path.GetFullPath(Path.Combine("wwwroot", "js", "sample.js"))}' specified in the endpoint '{Path.Combine("js","sample.js").Replace('\\', '/')}' does not exist.""");
+ errorMessages[0].Should().Be($"""The asset file '{Path.GetFullPath(Path.Combine("wwwroot", "js", "sample.js"))}' specified in the endpoint '{Path.Combine("js", "sample.js").Replace('\\', '/')}' does not exist.""");
}
private static ITaskItem CreateStaticWebAsset(
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
index fb2746fb1ce5..b5f256aadfa9 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
@@ -27,29 +27,29 @@ namespace Microsoft.AspNetCore.StaticWebAssets.Tasks.Test;
// Recursive wildcard in the middle 'a/**/c'
public partial class StaticWebAssetGlobMatcherTest
{
- [Theory]
- [InlineData("**/*.razor.js", "Components/Pages/RegularComponent.razor.js", "Components/Pages/RegularComponent.razor.js")]
- [InlineData("**/*.razor.js", "Components/User.Profile.Details.razor.js", "Components/User.Profile.Details.razor.js")]
- [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js")]
- [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js")]
- [InlineData("**/*.cshtml.js", "Pages/Shared/_Host.cshtml.js", "Pages/Shared/_Host.cshtml.js")]
- [InlineData("**/*.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js")]
- [InlineData("*.lib.module.js", "Widget.lib.module.js", "Widget.lib.module.js")]
- [InlineData("*.razor.css", "Component.razor.css", "Component.razor.css")]
- [InlineData("*.cshtml.css", "View.cshtml.css", "View.cshtml.css")]
- [InlineData("*.modules.json", "app.modules.json", "app.modules.json")]
- [InlineData("*.lib.module.js", "Rcl.Client.Feature.lib.module.js", "Rcl.Client.Feature.lib.module.js")]
- public void Can_Match_WellKnownExistingPatterns(string pattern, string path, string expectedStem)
- {
- var matcher = new StaticWebAssetGlobMatcherBuilder();
- matcher.AddIncludePatterns(pattern);
- var globMatcher = matcher.Build();
+ [Theory]
+ [InlineData("**/*.razor.js", "Components/Pages/RegularComponent.razor.js", "Components/Pages/RegularComponent.razor.js")]
+ [InlineData("**/*.razor.js", "Components/User.Profile.Details.razor.js", "Components/User.Profile.Details.razor.js")]
+ [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js")]
+ [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js")]
+ [InlineData("**/*.cshtml.js", "Pages/Shared/_Host.cshtml.js", "Pages/Shared/_Host.cshtml.js")]
+ [InlineData("**/*.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js")]
+ [InlineData("*.lib.module.js", "Widget.lib.module.js", "Widget.lib.module.js")]
+ [InlineData("*.razor.css", "Component.razor.css", "Component.razor.css")]
+ [InlineData("*.cshtml.css", "View.cshtml.css", "View.cshtml.css")]
+ [InlineData("*.modules.json", "app.modules.json", "app.modules.json")]
+ [InlineData("*.lib.module.js", "Rcl.Client.Feature.lib.module.js", "Rcl.Client.Feature.lib.module.js")]
+ public void Can_Match_WellKnownExistingPatterns(string pattern, string path, string expectedStem)
+ {
+ var matcher = new StaticWebAssetGlobMatcherBuilder();
+ matcher.AddIncludePatterns(pattern);
+ var globMatcher = matcher.Build();
- var match = globMatcher.Match(path);
- Assert.True(match.IsMatch);
- Assert.Equal(pattern, match.Pattern);
- Assert.Equal(expectedStem, match.Stem);
- }
+ var match = globMatcher.Match(path);
+ Assert.True(match.IsMatch);
+ Assert.Equal(pattern, match.Pattern);
+ Assert.Equal(expectedStem, match.Stem);
+ }
[Fact]
public void CanMatchLiterals()
{
@@ -175,7 +175,7 @@ public void QuestionMarksMatchSingleCharacter(string pattern, string input, bool
var globMatcher = matcher.Build();
var match = globMatcher.Match(input);
Assert.Equal(expectedMatchResult, match.IsMatch);
- if(expectedMatchResult)
+ if (expectedMatchResult)
{
Assert.Equal(pattern, match.Pattern);
Assert.Equal(input, match.Stem);
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
index 31e709b85f12..28cc56b69570 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
@@ -3,8 +3,8 @@
#nullable disable
-using Microsoft.AspNetCore.StaticWebAssets.Tasks;
using System.Text.RegularExpressions;
+using Microsoft.AspNetCore.StaticWebAssets.Tasks;
namespace Microsoft.AspNetCore.Razor.Tasks;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
index 5098c8ac0738..7d5eff350ce2 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
@@ -96,7 +96,7 @@ public void InfersPreCompressedAssetsCorrectly()
CopyToOutputDirectory = StaticWebAsset.AssetCopyOptions.Never,
Fingerprint = "xtxxf3hu2r",
RelatedAsset = string.Empty,
- ContentRoot = Path.Combine(Environment.CurrentDirectory,"wwwroot"),
+ ContentRoot = Path.Combine(Environment.CurrentDirectory, "wwwroot"),
SourceType = StaticWebAsset.SourceTypes.Discovered,
Integrity = "hRQyftXiu1lLX2P9Ly9xa4gHJgLeR1uGN5qegUobtGo=",
FileLength = 10,
@@ -206,7 +206,7 @@ public void ResolvesAssets_WithFingerprint_MatchingIncludePattern()
{
Identity = ItemSpec,
OriginalItemSpec = OriginalItemSpec,
- RelativePath = Path.GetFileNameWithoutExtension(ItemSpec)+"#[.{fingerprint}]" + Path.GetExtension(ItemSpec),
+ RelativePath = Path.GetFileNameWithoutExtension(ItemSpec) + "#[.{fingerprint}]" + Path.GetExtension(ItemSpec),
ContentRoot = Path.GetDirectoryName(ItemSpec),
SourceType = StaticWebAsset.SourceTypes.Discovered,
SourceId = "App",
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
index a27049b45841..6e7f5875090f 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
@@ -41,7 +41,7 @@ public void Standalone_Selects_EndpointMatching_FilePath(string pattern, string
var resolvedEndpoints = new ResolveFingerprintedStaticWebAssetEndpointsForAssets
{
CandidateAssets = [.. candidateAssets],
- CandidateEndpoints = [..endpoints.Select(e => e.ToTaskItem())],
+ CandidateEndpoints = [.. endpoints.Select(e => e.ToTaskItem())],
IsStandalone = true,
BuildEngine = buildEngine.Object
};
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
index 9c2e008f4610..a57f76a816de 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
@@ -23,7 +23,7 @@ public void Execute_UpdatesAssetsWithoutFingerprint()
Directory.CreateDirectory(Path.Combine(AppContext.BaseDirectory, "dist", "assets"));
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "dist", "assets", "index-C5tBAdQX.css"), "body { color: red; }");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "dist", "index.html"), "");
- var assets = new ITaskItem [] {
+ var assets = new ITaskItem[] {
new TaskItem(
Path.Combine(AppContext.BaseDirectory, @"dist\assets\index-C5tBAdQX.css"),
new Dictionary
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
index 43956cf963c3..8fbf56545498 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
@@ -256,7 +256,7 @@ public void CanUpdateEndpoint_RetainsNonModifiedEndpointsWithSameRoute()
EndpointProperties = [.. fingerprintedEndpoints[0].EndpointProperties]
};
- endpoints = [..endpoints, unmodifiedEndpoint];
+ endpoints = [.. endpoints, unmodifiedEndpoint];
foreach (var endpoint in fingerprintedEndpoints)
{
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
index 8d0a563a0b83..d3e1a3f0b80b 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
@@ -10,6 +10,7 @@
using NuGet.ProjectModel;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
+
public partial class StaticWebAssetsBaselineFactory
{
[GeneratedRegex("""(.*\.)([0123456789abcdefghijklmnopqrstuvwxyz]{10})(\.bundle\.scp\.css)((?:\.gz)|(?:\.br))?$""", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
index df2caf4709da..12b39c795d7c 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
@@ -74,7 +74,7 @@ public void Build_Detects_PrecompressedAssets()
endpoint.ResponseHeaders.Where(e => e.Name == "Content-Encoding").Select(e => e.Value).Single().Should().Be("gzip");
var etags = endpoint.ResponseHeaders.Where(e => e.Name == "ETag").Select(e => EntityTagHeaderValue.Parse(e.Value));
- etags.Where(e=> !e.IsWeak).Select(e => e.Tag).Single().Should().BeEquivalentTo($"\"{gzipAsset.Integrity}\"");
+ etags.Where(e => !e.IsWeak).Select(e => e.Tag).Single().Should().BeEquivalentTo($"\"{gzipAsset.Integrity}\"");
if (endpoint.Route.EndsWith(".gz"))
{
continue;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
index e9af1e2755ad..9385832c66d7 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
@@ -3,9 +3,9 @@
#nullable disable
-using Microsoft.AspNetCore.StaticWebAssets.Tasks;
-using System.Text.Json;
using System.IO.Compression;
+using System.Text.Json;
+using Microsoft.AspNetCore.StaticWebAssets.Tasks;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
@@ -17,7 +17,8 @@ public void Build_FingerprintsContent_WhenEnabled()
var expectedManifest = LoadBuildManifest();
var testAsset = "RazorComponentApp";
ProjectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p => {
+ .WithProjectChanges(p =>
+ {
var fingerprintContent = p.Descendants()
.SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
fingerprintContent.Value = "true";
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
index c13c8b2d5c6b..4e2fa680a127 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
@@ -751,7 +751,7 @@ public void BuildProjectWithReferences_NoDependencies_GeneratesJsonManifestAndCo
// Second build
var secondBuild = CreateBuildCommand(ProjectDirectory, "AppWithPackageAndP2PReference");
- ExecuteCommand(secondBuild,"/p:BuildProjectReferences=false").Should().Pass();
+ ExecuteCommand(secondBuild, "/p:BuildProjectReferences=false").Should().Pass();
// GenerateStaticWebAssetsManifest should generate the manifest file.
new FileInfo(path).Should().Exist();
From f44a784cce295cfccadd1ac0f02b78c37a46f4e0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Sep 2025 12:41:15 +0000
Subject: [PATCH 3/6] Address feedback: revert unnecessary changes and fix test
to use proper project structure
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
---
....NET.Sdk.StaticWebAssets.ScopedCss.targets | 8 +--
.../ComputeStaticWebAssetsTargetPathsTest.cs | 1 -
.../JsModulesIntegrationTest.cs | 14 +++---
.../LegacyStaticWebAssetsV1IntegrationTest.cs | 2 +-
.../ScopedCssIntegrationTests.cs | 50 ++++++++++++++-----
.../StaticWebAssetEndpointsIntegrationTest.cs | 48 +++++++++---------
.../DefineStaticWebAssetEndpointsTest.cs | 6 +--
.../DiscoverPrecompressedAssetsTest.cs | 2 +-
.../DiscoverStaticWebAssetsTest.cs | 8 +--
.../FilterStaticWebAssetEndpointsTest.cs | 1 -
...rateStaticWebAssetEndpointsManifestTest.cs | 6 +--
...ateStaticWebAssetEndpointsPropsFileTest.cs | 2 +-
.../Globbing/StaticWebAssetGlobMatcherTest.cs | 46 ++++++++---------
.../OverrideHtmlAssetPlaceholdersTest.cs | 2 +-
.../ResolveCompressedAssetsTest.cs | 4 +-
...tedStaticWebAssetEndpointsForAssetsTest.cs | 2 +-
...ateExternallyDefinedStaticWebAssetsTest.cs | 2 +-
.../UpdateStaticWebAssetEndpointsTest.cs | 2 +-
.../StaticWebAssetsBaselineFactory.cs | 1 -
...aticWebAssetsCompressionIntegrationTest.cs | 2 +-
.../StaticWebAssetsFingerprintingTest.cs | 7 ++-
.../StaticWebAssetsIntegrationTest.cs | 2 +-
22 files changed, 119 insertions(+), 99 deletions(-)
diff --git a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
index 6a415883af2f..60fa20ec13ce 100644
--- a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
+++ b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
@@ -233,12 +233,12 @@ Integration with static web assets:
<_ScopedCssAppBundleStaticWebAssetCandidate Include="$(_ScopedCssOutputPath)">
- $([System.Uri]::EscapeDataString($(PackageId)))#[.{fingerprint}]?.styles.css
- $([System.Uri]::EscapeDataString($(PackageId))).styles.css
+ $(PackageId)#[.{fingerprint}]?.styles.css
+ $(PackageId).styles.css
<_ScopedCssProjectBundleStaticWebAssetCandidate Include="$(_ScopedCssProjectOutputPath)">
- $([System.Uri]::EscapeDataString($(PackageId)))#[.{fingerprint}]!.bundle.scp.css
- $([System.Uri]::EscapeDataString($(PackageId))).bundle.scp.css
+ $(PackageId)#[.{fingerprint}]!.bundle.scp.css
+ $(PackageId).bundle.scp.css
<_AddLinkHeaderToAppBundle Include="Append" Condition="'@(_ResolvedScopedCssBundleEndpoints)' != ''">
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
index 114a097d7c63..8bf1bafb89dd 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ComputeStaticWebAssetsTargetPathsTest.cs
@@ -13,7 +13,6 @@
using Moq;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
-
public class ComputeStaticWebAssetsTargetPathsTest
{
[Fact]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
index 56ad90dfc8ed..d96dab0d59e5 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/JsModulesIntegrationTest.cs
@@ -31,12 +31,11 @@ public void Build_GeneratesManifestWhenItFindsALibrary()
{
var testAsset = "RazorComponentApp";
var projectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p =>
- {
- var fingerprintContent = p.Descendants()
- .SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
- fingerprintContent.Value = "true";
- });
+ .WithProjectChanges(p => {
+ var fingerprintContent = p.Descendants()
+ .SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
+ fingerprintContent.Value = "true";
+ });
Directory.CreateDirectory(Path.Combine(projectDirectory.TestRoot, "wwwroot"));
File.WriteAllText(Path.Combine(projectDirectory.TestRoot, "wwwroot", "ComponentApp.lib.module.js"), "console.log('Hello world!');");
@@ -90,8 +89,7 @@ public void Publish_PublishesJsModuleBundleBundleToTheRightLocation()
{
var testAsset = "RazorComponentApp";
ProjectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p =>
- {
+ .WithProjectChanges(p => {
var fingerprintContent = p.Descendants()
.SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
fingerprintContent.Value = "true";
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
index 248b025ac4a5..9089ed148d04 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/LegacyStaticWebAssetsV1IntegrationTest.cs
@@ -3,7 +3,7 @@
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
-[assembly: CollectionBehavior(DisableTestParallelization = true)]
+[assembly:CollectionBehavior(DisableTestParallelization = true)]
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests
{
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
index 245976d4cabe..dbbfbb61d717 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
@@ -621,17 +621,46 @@ public void RegeneratingScopedCss_ForProjectWithReferences()
[Fact]
public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
{
- var testAsset = "RazorComponentApp";
- var projectDirectory = CreateAspNetSdkTestAsset(testAsset);
+ var testAsset = "RazorAppWithPackageAndP2PReference";
+ ProjectDirectory = CreateAspNetSdkTestAsset(testAsset);
- // Create a CSS file to trigger scoped CSS processing
- var cssFile = Path.Combine(projectDirectory.Path, "Components", "Pages", "Index.razor.css");
- Directory.CreateDirectory(Path.GetDirectoryName(cssFile));
- File.WriteAllText(cssFile, ".test { color: red; }");
+ // Rename the ClassLibrary project to have non-ASCII characters
+ var originalLibPath = Path.Combine(ProjectDirectory.Path, "ClassLibrary");
+ var newLibPath = Path.Combine(ProjectDirectory.Path, "项目");
+ Directory.Move(originalLibPath, newLibPath);
+
+ // Update the project file to set the assembly name and package ID
+ var libProjectFile = Path.Combine(newLibPath, "ClassLibrary.csproj");
+ var newLibProjectFile = Path.Combine(newLibPath, "项目.csproj");
+ File.Move(libProjectFile, newLibProjectFile);
+
+ // Add assembly name property to ensure consistent naming
+ var libProjectContent = File.ReadAllText(newLibProjectFile);
+ libProjectContent = libProjectContent.Replace("",
+ " 项目\n 项目\n ", 1);
+ File.WriteAllText(newLibProjectFile, libProjectContent);
+
+ // Update the main project to reference the renamed library
+ var mainProjectFile = Path.Combine(ProjectDirectory.Path, "AppWithPackageAndP2PReference", "AppWithPackageAndP2PReference.csproj");
+ var mainProjectContent = File.ReadAllText(mainProjectFile);
+ mainProjectContent = mainProjectContent.Replace(@"..\ClassLibrary\ClassLibrary.csproj", @"..\项目\项目.csproj");
+ File.WriteAllText(mainProjectFile, mainProjectContent);
+
+ // Ensure library has scoped CSS
+ var libCssFile = Path.Combine(newLibPath, "Components", "Component1.razor.css");
+ if (!File.Exists(libCssFile))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(libCssFile));
+ File.WriteAllText(libCssFile, ".test { color: red; }");
+ }
- var build = CreateBuildCommand(projectDirectory);
- // Set PackageId to contain non-ASCII characters (Chinese characters meaning "project")
- ExecuteCommand(build, "/p:PackageId=项目").Should().Pass();
+ EnsureLocalPackagesExists();
+
+ var restore = CreateRestoreCommand(ProjectDirectory, "AppWithPackageAndP2PReference");
+ ExecuteCommand(restore).Should().Pass();
+
+ var build = CreateBuildCommand(ProjectDirectory, "AppWithPackageAndP2PReference");
+ ExecuteCommand(build).Should().Pass();
var intermediateOutputPath = build.GetIntermediateDirectory(DefaultTfm, "Debug").ToString();
@@ -643,9 +672,6 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
// Verify that the Link header contains URL-encoded characters (%E9%A1%B9%E7%9B%AE is "项目" encoded)
endpointsContent.Should().Contain("%E9%A1%B9%E7%9B%AE");
-
- // Verify it doesn't contain the unencoded characters
- endpointsContent.Should().NotContain("项目");
}
}
}
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
index ade219c5f8f4..79442747cab9 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetEndpointsIntegrationTest.cs
@@ -85,9 +85,9 @@ private bool MatchUncompresedProjectBundlesNoFingerprint(StaticWebAssetEndpoint
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: "", Success: false }
]
};
@@ -96,9 +96,9 @@ private bool MatchCompressedProjectBundlesNoFingerprint(StaticWebAssetEndpoint e
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: var compress, Success: true }
]
} && (compress == ".gz" || compress == ".br");
@@ -107,9 +107,9 @@ private bool MatchUncompressedProjectBundlesWithFingerprint(StaticWebAssetEndpoi
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: "", Success: false }
]
} && fingerprint == ep.EndpointProperties.Single(p => p.Name == "fingerprint").Value;
@@ -118,9 +118,9 @@ private bool MatchCompressedProjectBundlesWithFingerprint(StaticWebAssetEndpoint
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: var compress, Success: true }
]
} && !string.IsNullOrWhiteSpace(fingerprint)
&& (compress == ".gz" || compress == ".br");
@@ -130,9 +130,9 @@ private bool MatchUncompressedAppBundleNoFingerprint(StaticWebAssetEndpoint ep)
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: "", Success: false }
]
};
@@ -141,9 +141,9 @@ private bool MatchCompressedAppBundleNoFingerprint(StaticWebAssetEndpoint ep) =>
Success: true,
Groups: [
var _,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: "", Success: false },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: "", Success: false },
+ { Name: "compress", Value: var compress, Success: true }
]
} && (compress == ".gz" || compress == ".br");
@@ -152,9 +152,9 @@ private bool MatchUncompressedAppBundleWithFingerprint(StaticWebAssetEndpoint ep
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: "", Success: false }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: "", Success: false }
]
} && fingerprint == ep.EndpointProperties.Single(p => p.Name == "fingerprint").Value;
@@ -163,9 +163,9 @@ private bool MatchCompressedAppBundleWithFingerprint(StaticWebAssetEndpoint ep)
Success: true,
Groups: [
var m,
- { Name: "project", Value: "ComponentApp", Success: true, },
- { Name: "fingerprint", Value: var fingerprint, Success: true },
- { Name: "compress", Value: var compress, Success: true }
+ { Name: "project", Value: "ComponentApp", Success: true, },
+ { Name: "fingerprint", Value: var fingerprint, Success: true },
+ { Name: "compress", Value: var compress, Success: true }
]
} && !string.IsNullOrWhiteSpace(fingerprint)
&& (compress == ".gz" || compress == ".br");
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
index ccab6a4fe566..dfb709b5865d 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DefineStaticWebAssetEndpointsTest.cs
@@ -3,15 +3,15 @@
#nullable disable
-using System.Diagnostics;
using System.Diagnostics.Metrics;
-using System.Globalization;
-using System.Net;
+using System.Diagnostics;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Moq;
using NuGet.Packaging.Core;
+using System.Net;
+using System.Globalization;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
index 5eccf523e3e7..27d7baae60f0 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverPrecompressedAssetsTest.cs
@@ -44,7 +44,7 @@ public void DiscoversPrecompressedAssetsCorrectly()
CopyToOutputDirectory = StaticWebAsset.AssetCopyOptions.Never,
Fingerprint = "uncompressed",
RelatedAsset = string.Empty,
- ContentRoot = Path.Combine(Environment.CurrentDirectory, "wwwroot"),
+ ContentRoot = Path.Combine(Environment.CurrentDirectory,"wwwroot"),
SourceType = StaticWebAsset.SourceTypes.Discovered,
Integrity = "uncompressed-integrity",
AssetRole = StaticWebAsset.AssetRoles.Primary,
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
index e56d53b8b7d2..f252022d1338 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/DiscoverStaticWebAssetsTest.cs
@@ -217,9 +217,9 @@ public void FingerprintsContentUsingPatternsWhenMoreThanOneExtension(string file
asset.GetMetadata(nameof(StaticWebAsset.OriginalItemSpec)).Should().Be(Path.Combine("wwwroot", fileName));
}
- [Fact]
- [Trait("Category", "FingerprintIdentity")]
- public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdentityNeedsComputation()
+ [Fact]
+ [Trait("Category", "FingerprintIdentity")]
+ public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdentityNeedsComputation()
{
// Arrange: simulate a packaged asset (outside content root) with a RelativePath inside the app
var errorMessages = new List();
@@ -251,7 +251,7 @@ public void ComputesIdentity_UsingFingerprintPattern_ForComputedAssets_WhenIdent
})
],
// No RelativePathPattern, we trigger the branch that synthesizes identity under content root.
- FingerprintPatterns = [new TaskItem("Js", new Dictionary { { "Pattern", "*.js" }, { "Expression", "#[.{fingerprint}]!" } })],
+ FingerprintPatterns = [ new TaskItem("Js", new Dictionary{{"Pattern","*.js"},{"Expression","#[.{fingerprint}]!"}})],
FingerprintCandidates = true,
SourceType = "Computed",
SourceId = "Client",
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
index 7b8a19394706..2cf9ee746d4e 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/FilterStaticWebAssetEndpointsTest.cs
@@ -9,7 +9,6 @@
using Moq;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests.StaticWebAssets;
-
public class FilterStaticWebAssetEndpointsTest
{
[Fact]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
index 6957302e4830..a278a732193a 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsManifestTest.cs
@@ -253,11 +253,11 @@ public void ExcludesEndpoints_BasedOnExclusionPatterns()
// Assert
new FileInfo(path).Should().Exist();
new FileInfo(exclusionCachePath).Should().Exist();
-
+
var manifest = File.ReadAllText(path);
var json = JsonSerializer.Deserialize(manifest);
json.Should().NotBeNull();
-
+
// Only styles.css endpoint should remain as others match _content/MyApp/**
json.Endpoints.Should().HaveCount(1);
json.Endpoints[0].Route.Should().Contain("styles.css");
@@ -406,7 +406,7 @@ public void RegeneratesManifest_WhenExclusionPatternsChange()
// Assert - File should be regenerated
var secondWriteTime = File.GetLastWriteTimeUtc(endpointsManifestPath);
secondWriteTime.Should().BeAfter(firstWriteTime);
-
+
// Verify cache file was updated
var cacheContent = File.ReadAllText(exclusionCachePath);
cacheContent.Should().Contain("different/**");
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
index 6563cebc6bde..90135f0c14ca 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetEndpointsPropsFileTest.cs
@@ -157,7 +157,7 @@ public void Fails_WhenEndpointWithoutAssetExists()
result.Should().BeFalse();
errorMessages.Should().ContainSingle();
- errorMessages[0].Should().Be($"""The asset file '{Path.GetFullPath(Path.Combine("wwwroot", "js", "sample.js"))}' specified in the endpoint '{Path.Combine("js", "sample.js").Replace('\\', '/')}' does not exist.""");
+ errorMessages[0].Should().Be($"""The asset file '{Path.GetFullPath(Path.Combine("wwwroot", "js", "sample.js"))}' specified in the endpoint '{Path.Combine("js","sample.js").Replace('\\', '/')}' does not exist.""");
}
private static ITaskItem CreateStaticWebAsset(
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
index b5f256aadfa9..fb2746fb1ce5 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/Globbing/StaticWebAssetGlobMatcherTest.cs
@@ -27,29 +27,29 @@ namespace Microsoft.AspNetCore.StaticWebAssets.Tasks.Test;
// Recursive wildcard in the middle 'a/**/c'
public partial class StaticWebAssetGlobMatcherTest
{
- [Theory]
- [InlineData("**/*.razor.js", "Components/Pages/RegularComponent.razor.js", "Components/Pages/RegularComponent.razor.js")]
- [InlineData("**/*.razor.js", "Components/User.Profile.Details.razor.js", "Components/User.Profile.Details.razor.js")]
- [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js")]
- [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js")]
- [InlineData("**/*.cshtml.js", "Pages/Shared/_Host.cshtml.js", "Pages/Shared/_Host.cshtml.js")]
- [InlineData("**/*.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js")]
- [InlineData("*.lib.module.js", "Widget.lib.module.js", "Widget.lib.module.js")]
- [InlineData("*.razor.css", "Component.razor.css", "Component.razor.css")]
- [InlineData("*.cshtml.css", "View.cshtml.css", "View.cshtml.css")]
- [InlineData("*.modules.json", "app.modules.json", "app.modules.json")]
- [InlineData("*.lib.module.js", "Rcl.Client.Feature.lib.module.js", "Rcl.Client.Feature.lib.module.js")]
- public void Can_Match_WellKnownExistingPatterns(string pattern, string path, string expectedStem)
- {
- var matcher = new StaticWebAssetGlobMatcherBuilder();
- matcher.AddIncludePatterns(pattern);
- var globMatcher = matcher.Build();
+ [Theory]
+ [InlineData("**/*.razor.js", "Components/Pages/RegularComponent.razor.js", "Components/Pages/RegularComponent.razor.js")]
+ [InlineData("**/*.razor.js", "Components/User.Profile.Details.razor.js", "Components/User.Profile.Details.razor.js")]
+ [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js", "Components/Area/Sub/Feature/User.Profile.Details.razor.js")]
+ [InlineData("**/*.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js", "Components/Area/Sub/Feature/Deep.Component.Name.With.Many.Parts.razor.js")]
+ [InlineData("**/*.cshtml.js", "Pages/Shared/_Host.cshtml.js", "Pages/Shared/_Host.cshtml.js")]
+ [InlineData("**/*.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js", "Areas/Admin/Pages/Dashboard.cshtml.js")]
+ [InlineData("*.lib.module.js", "Widget.lib.module.js", "Widget.lib.module.js")]
+ [InlineData("*.razor.css", "Component.razor.css", "Component.razor.css")]
+ [InlineData("*.cshtml.css", "View.cshtml.css", "View.cshtml.css")]
+ [InlineData("*.modules.json", "app.modules.json", "app.modules.json")]
+ [InlineData("*.lib.module.js", "Rcl.Client.Feature.lib.module.js", "Rcl.Client.Feature.lib.module.js")]
+ public void Can_Match_WellKnownExistingPatterns(string pattern, string path, string expectedStem)
+ {
+ var matcher = new StaticWebAssetGlobMatcherBuilder();
+ matcher.AddIncludePatterns(pattern);
+ var globMatcher = matcher.Build();
- var match = globMatcher.Match(path);
- Assert.True(match.IsMatch);
- Assert.Equal(pattern, match.Pattern);
- Assert.Equal(expectedStem, match.Stem);
- }
+ var match = globMatcher.Match(path);
+ Assert.True(match.IsMatch);
+ Assert.Equal(pattern, match.Pattern);
+ Assert.Equal(expectedStem, match.Stem);
+ }
[Fact]
public void CanMatchLiterals()
{
@@ -175,7 +175,7 @@ public void QuestionMarksMatchSingleCharacter(string pattern, string input, bool
var globMatcher = matcher.Build();
var match = globMatcher.Match(input);
Assert.Equal(expectedMatchResult, match.IsMatch);
- if (expectedMatchResult)
+ if(expectedMatchResult)
{
Assert.Equal(pattern, match.Pattern);
Assert.Equal(input, match.Stem);
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
index 28cc56b69570..31e709b85f12 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/OverrideHtmlAssetPlaceholdersTest.cs
@@ -3,8 +3,8 @@
#nullable disable
-using System.Text.RegularExpressions;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
+using System.Text.RegularExpressions;
namespace Microsoft.AspNetCore.Razor.Tasks;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
index 7d5eff350ce2..5098c8ac0738 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveCompressedAssetsTest.cs
@@ -96,7 +96,7 @@ public void InfersPreCompressedAssetsCorrectly()
CopyToOutputDirectory = StaticWebAsset.AssetCopyOptions.Never,
Fingerprint = "xtxxf3hu2r",
RelatedAsset = string.Empty,
- ContentRoot = Path.Combine(Environment.CurrentDirectory, "wwwroot"),
+ ContentRoot = Path.Combine(Environment.CurrentDirectory,"wwwroot"),
SourceType = StaticWebAsset.SourceTypes.Discovered,
Integrity = "hRQyftXiu1lLX2P9Ly9xa4gHJgLeR1uGN5qegUobtGo=",
FileLength = 10,
@@ -206,7 +206,7 @@ public void ResolvesAssets_WithFingerprint_MatchingIncludePattern()
{
Identity = ItemSpec,
OriginalItemSpec = OriginalItemSpec,
- RelativePath = Path.GetFileNameWithoutExtension(ItemSpec) + "#[.{fingerprint}]" + Path.GetExtension(ItemSpec),
+ RelativePath = Path.GetFileNameWithoutExtension(ItemSpec)+"#[.{fingerprint}]" + Path.GetExtension(ItemSpec),
ContentRoot = Path.GetDirectoryName(ItemSpec),
SourceType = StaticWebAsset.SourceTypes.Discovered,
SourceId = "App",
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
index 6e7f5875090f..a27049b45841 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ResolveFingerprintedStaticWebAssetEndpointsForAssetsTest.cs
@@ -41,7 +41,7 @@ public void Standalone_Selects_EndpointMatching_FilePath(string pattern, string
var resolvedEndpoints = new ResolveFingerprintedStaticWebAssetEndpointsForAssets
{
CandidateAssets = [.. candidateAssets],
- CandidateEndpoints = [.. endpoints.Select(e => e.ToTaskItem())],
+ CandidateEndpoints = [..endpoints.Select(e => e.ToTaskItem())],
IsStandalone = true,
BuildEngine = buildEngine.Object
};
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
index a57f76a816de..9c2e008f4610 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateExternallyDefinedStaticWebAssetsTest.cs
@@ -23,7 +23,7 @@ public void Execute_UpdatesAssetsWithoutFingerprint()
Directory.CreateDirectory(Path.Combine(AppContext.BaseDirectory, "dist", "assets"));
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "dist", "assets", "index-C5tBAdQX.css"), "body { color: red; }");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "dist", "index.html"), "");
- var assets = new ITaskItem[] {
+ var assets = new ITaskItem [] {
new TaskItem(
Path.Combine(AppContext.BaseDirectory, @"dist\assets\index-C5tBAdQX.css"),
new Dictionary
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
index 8fbf56545498..43956cf963c3 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/UpdateStaticWebAssetEndpointsTest.cs
@@ -256,7 +256,7 @@ public void CanUpdateEndpoint_RetainsNonModifiedEndpointsWithSameRoute()
EndpointProperties = [.. fingerprintedEndpoints[0].EndpointProperties]
};
- endpoints = [.. endpoints, unmodifiedEndpoint];
+ endpoints = [..endpoints, unmodifiedEndpoint];
foreach (var endpoint in fingerprintedEndpoints)
{
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
index d3e1a3f0b80b..8d0a563a0b83 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs
@@ -10,7 +10,6 @@
using NuGet.ProjectModel;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
-
public partial class StaticWebAssetsBaselineFactory
{
[GeneratedRegex("""(.*\.)([0123456789abcdefghijklmnopqrstuvwxyz]{10})(\.bundle\.scp\.css)((?:\.gz)|(?:\.br))?$""", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
index 12b39c795d7c..df2caf4709da 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsCompressionIntegrationTest.cs
@@ -74,7 +74,7 @@ public void Build_Detects_PrecompressedAssets()
endpoint.ResponseHeaders.Where(e => e.Name == "Content-Encoding").Select(e => e.Value).Single().Should().Be("gzip");
var etags = endpoint.ResponseHeaders.Where(e => e.Name == "ETag").Select(e => EntityTagHeaderValue.Parse(e.Value));
- etags.Where(e => !e.IsWeak).Select(e => e.Tag).Single().Should().BeEquivalentTo($"\"{gzipAsset.Integrity}\"");
+ etags.Where(e=> !e.IsWeak).Select(e => e.Tag).Single().Should().BeEquivalentTo($"\"{gzipAsset.Integrity}\"");
if (endpoint.Route.EndsWith(".gz"))
{
continue;
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
index 9385832c66d7..e9af1e2755ad 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsFingerprintingTest.cs
@@ -3,9 +3,9 @@
#nullable disable
-using System.IO.Compression;
-using System.Text.Json;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
+using System.Text.Json;
+using System.IO.Compression;
namespace Microsoft.NET.Sdk.StaticWebAssets.Tests;
@@ -17,8 +17,7 @@ public void Build_FingerprintsContent_WhenEnabled()
var expectedManifest = LoadBuildManifest();
var testAsset = "RazorComponentApp";
ProjectDirectory = CreateAspNetSdkTestAsset(testAsset)
- .WithProjectChanges(p =>
- {
+ .WithProjectChanges(p => {
var fingerprintContent = p.Descendants()
.SingleOrDefault(e => e.Name.LocalName == "StaticWebAssetsFingerprintContent");
fingerprintContent.Value = "true";
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
index 4e2fa680a127..c13c8b2d5c6b 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsIntegrationTest.cs
@@ -751,7 +751,7 @@ public void BuildProjectWithReferences_NoDependencies_GeneratesJsonManifestAndCo
// Second build
var secondBuild = CreateBuildCommand(ProjectDirectory, "AppWithPackageAndP2PReference");
- ExecuteCommand(secondBuild, "/p:BuildProjectReferences=false").Should().Pass();
+ ExecuteCommand(secondBuild,"/p:BuildProjectReferences=false").Should().Pass();
// GenerateStaticWebAssetsManifest should generate the manifest file.
new FileInfo(path).Should().Exist();
From 21a64d78fc9ab92d9e7ab9a3ce3e64035eb756fa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Sep 2025 12:44:56 +0000
Subject: [PATCH 4/6] Fix syntax error in test method
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
---
.../ScopedCssIntegrationTests.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
index dbbfbb61d717..1c05d38cf0dc 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
@@ -636,8 +636,14 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
// Add assembly name property to ensure consistent naming
var libProjectContent = File.ReadAllText(newLibProjectFile);
- libProjectContent = libProjectContent.Replace("",
- " 项目\n 项目\n ", 1);
+ // Find the first PropertyGroup closing tag and replace it
+ var targetPattern = "";
+ var replacement = " 项目\n 项目\n ";
+ var index = libProjectContent.IndexOf(targetPattern);
+ if (index >= 0)
+ {
+ libProjectContent = libProjectContent.Substring(0, index) + replacement + libProjectContent.Substring(index + targetPattern.Length);
+ }
File.WriteAllText(newLibProjectFile, libProjectContent);
// Update the main project to reference the renamed library
From 85554444a81e9a0f81c7327db49cea7dfe6bc177 Mon Sep 17 00:00:00 2001
From: Javier Calvarro Nelson
Date: Sat, 27 Sep 2025 19:46:17 +0200
Subject: [PATCH 5/6] fix test
---
...t.NET.Sdk.StaticWebAssets.ScopedCss.targets | 2 +-
.../ScopedCssIntegrationTests.cs | 18 ++++++++++++------
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
index 60fa20ec13ce..e74f0589b497 100644
--- a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
+++ b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets
@@ -244,7 +244,7 @@ Integration with static web assets:
<_AddLinkHeaderToAppBundle Include="Append" Condition="'@(_ResolvedScopedCssBundleEndpoints)' != ''">
Header
Link
- @(_ResolvedScopedCssBundleEndpoints->'<$([System.Uri]::EscapeDataString(%(Identity)))>; rel="preload"; as="style"', ', ')
+ @(_ResolvedScopedCssBundleEndpoints->'<%(Identity)>; rel="preload"; as="style"', ', ')
diff --git a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
index 1c05d38cf0dc..6155a3498987 100644
--- a/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
+++ b/test/Microsoft.NET.Sdk.StaticWebAssets.Tests/ScopedCssIntegrationTests.cs
@@ -3,6 +3,7 @@
#nullable disable
+using System.Text.Json;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
@@ -625,12 +626,12 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
ProjectDirectory = CreateAspNetSdkTestAsset(testAsset);
// Rename the ClassLibrary project to have non-ASCII characters
- var originalLibPath = Path.Combine(ProjectDirectory.Path, "ClassLibrary");
+ var originalLibPath = Path.Combine(ProjectDirectory.Path, "AnotherClassLib");
var newLibPath = Path.Combine(ProjectDirectory.Path, "项目");
Directory.Move(originalLibPath, newLibPath);
// Update the project file to set the assembly name and package ID
- var libProjectFile = Path.Combine(newLibPath, "ClassLibrary.csproj");
+ var libProjectFile = Path.Combine(newLibPath, "AnotherClassLib.csproj");
var newLibProjectFile = Path.Combine(newLibPath, "项目.csproj");
File.Move(libProjectFile, newLibProjectFile);
@@ -649,11 +650,11 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
// Update the main project to reference the renamed library
var mainProjectFile = Path.Combine(ProjectDirectory.Path, "AppWithPackageAndP2PReference", "AppWithPackageAndP2PReference.csproj");
var mainProjectContent = File.ReadAllText(mainProjectFile);
- mainProjectContent = mainProjectContent.Replace(@"..\ClassLibrary\ClassLibrary.csproj", @"..\项目\项目.csproj");
+ mainProjectContent = mainProjectContent.Replace(@"..\AnotherClassLib\AnotherClassLib.csproj", @"..\项目\项目.csproj");
File.WriteAllText(mainProjectFile, mainProjectContent);
// Ensure library has scoped CSS
- var libCssFile = Path.Combine(newLibPath, "Components", "Component1.razor.css");
+ var libCssFile = Path.Combine(newLibPath, "Views", "Shared", "Index.cshtml.css");
if (!File.Exists(libCssFile))
{
Directory.CreateDirectory(Path.GetDirectoryName(libCssFile));
@@ -675,9 +676,14 @@ public void Build_GeneratesUrlEncodedLinkHeaderForNonAsciiProjectName()
new FileInfo(endpointsFile).Should().Exist();
var endpointsContent = File.ReadAllText(endpointsFile);
+ var json = JsonSerializer.Deserialize(endpointsContent, new JsonSerializerOptions(JsonSerializerDefaults.Web));
- // Verify that the Link header contains URL-encoded characters (%E9%A1%B9%E7%9B%AE is "项目" encoded)
- endpointsContent.Should().Contain("%E9%A1%B9%E7%9B%AE");
+ var styles = json.Endpoints.Where(e => e.Route.EndsWith("styles.css"));
+
+ foreach (var styleEndpoint in styles)
+ {
+ styleEndpoint.ResponseHeaders.Should().Contain(h => h.Name.Equals("Link", StringComparison.OrdinalIgnoreCase) && h.Value.Contains("%E9%A1%B9%E7%9B%AE"));
+ }
}
}
}
From 95dcef5b9d439e8c42e5fbe2c8e8db303caa311a Mon Sep 17 00:00:00 2001
From: Javier Calvarro Nelson
Date: Sat, 27 Sep 2025 20:24:53 +0200
Subject: [PATCH 6/6] Fix encoding when generating the manifest instead
---
...GenerateStaticWebAssetEndpointsManifest.cs | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetEndpointsManifest.cs b/src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetEndpointsManifest.cs
index 0387bb131057..f996a75b7168 100644
--- a/src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetEndpointsManifest.cs
+++ b/src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetEndpointsManifest.cs
@@ -116,6 +116,8 @@ public override bool Execute()
endpoint.AssetFile = asset.ResolvedAsset.ComputeTargetPath("", '/', StaticWebAssetTokenResolver.Instance);
endpoint.Route = route;
+ EncodeLinkHeadersIfNeeded(endpoint);
+
Log.LogMessage(MessageImportance.Low, "Including endpoint '{0}' for asset '{1}' with final location '{2}'", endpoint.Route, endpoint.AssetFile, asset.TargetPath);
}
@@ -137,6 +139,48 @@ public override bool Execute()
return !Log.HasLoggedErrors;
}
+ private static void EncodeLinkHeadersIfNeeded(StaticWebAssetEndpoint endpoint)
+ {
+ for (var i = 0; i < endpoint.ResponseHeaders.Length; i++)
+ {
+ ref var header = ref endpoint.ResponseHeaders[i];
+ if (!string.Equals(header.Name, "Link", StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+ var headerValues = header.Value.Split([','], StringSplitOptions.RemoveEmptyEntries);
+ for (var j = 0; j < headerValues.Length; j++)
+ {
+ ref var value = ref headerValues[j];
+ value = EncodeHeaderValue(value);
+ }
+ header.Value = string.Join(",", headerValues);
+ }
+ }
+
+ private static string EncodeHeaderValue(string header)
+ {
+ var index = header.IndexOf('<');
+ if (index == -1)
+ {
+ return header;
+ }
+ index++;
+ var endIndex = header.IndexOf('>', index);
+ if (endIndex == -1)
+ {
+ return header;
+ }
+ var link = header.AsSpan(index, endIndex - index).ToString();
+ var segments = link.Split('/');
+ for (var j = 0; j < segments.Length; j++)
+ {
+ segments[j] = System.Net.WebUtility.UrlEncode(segments[j]);
+ }
+ var encoded = string.Join("/", segments);
+ return $"{header.Substring(0, index)}{encoded}{header.Substring(endIndex)}";
+ }
+
private static (string, string[]) ParseAndSortPatterns(string patterns)
{
if (string.IsNullOrEmpty(patterns))