public void CachesMatchResults() { // Arrange var changeToken = new Mock <IChangeToken>(); var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); Mock.Get(fileProvider).Setup(f => f.Watch(It.IsAny <string>())).Returns(changeToken.Object); var value = new Mock <ICacheEntry>(); value.Setup(c => c.Value).Returns(null); value.Setup(c => c.ExpirationTokens).Returns(new List <IChangeToken>()); var cache = MakeCache(); Mock.Get(cache).Setup(c => c.CreateEntry( /*key*/ It.IsAny <object>())) .Returns((object key) => value.Object) .Verifiable(); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); Mock.Get(cache).VerifyAll(); }
private void EnsureGlobbingUrlBuilder() { if (GlobbingUrlBuilder == null) { GlobbingUrlBuilder = new GlobbingUrlBuilder( HostingEnvironment.WebRootFileProvider, Cache, ViewContext.HttpContext.Request.PathBase); } }
public void ReturnsOnlyStaticUrlWhenPatternDoesntFindAnyMatches() { // Arrange var fileProvider = MakeFileProvider(); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList("/site.css", "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/site.css", url)); }
public void ReturnsOnlyStaticUrlWhenPatternDoesntFindAnyMatches() { // Arrange var fileProvider = MakeFileProvider(); IMemoryCache cache = null; var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList("/site.css", "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/site.css", url)); }
public void BuildUrlList_AddsToMemoryCache_WithSizeLimit() { // Arrange var cacheEntry = Mock.Of <ICacheEntry>(m => m.ExpirationTokens == new List <IChangeToken>()); var cache = Mock.Of <IMemoryCache>(m => m.CreateEntry(It.IsAny <object>()) == cacheEntry); var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList("/site.css", "**/*.css", excludePattern: null); // Assert Assert.Equal(38, cacheEntry.Size); }
public void DedupesStaticUrlAndPatternMatches() { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); IMemoryCache cache = null; var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList("/site.css", "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/site.css", url), url => Assert.Equal("/blank.css", url)); }
public void DedupesStaticUrlAndPatternMatches() { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList("/site.css", "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/site.css", url), url => Assert.Equal("/blank.css", url)); }
public void OrdersGlobbedMatchResultsCorrectly(string staticUrl, FileNode dirStructure, string[] expectedPaths) { // Arrange var fileProvider = MakeFileProvider(dirStructure); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList(staticUrl, "**/*.*", excludePattern: null); // Assert var collectionAssertions = expectedPaths.Select <string, Action <string> >(expected => actual => Assert.Equal(expected, actual)); Assert.Collection(urlList, collectionAssertions.ToArray()); }
public void HandlesCommaSeparatedPatterns(string includePattern, string[] expectedOutput) { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.js", "site2.txt", "site.js")); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: includePattern, excludePattern: null); // Assert Assert.Equal(expectedOutput, urlList, StringComparer.Ordinal); }
public void ResolvesMatchedUrlsAgainstPathBase(string pathBase) { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = new PathString(pathBase); var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal($"{pathBase}/blank.css", url), url => Assert.Equal($"{pathBase}/site.css", url)); }
public override void Process(TagHelperContext context, TagHelperOutput output) { var urlBuilder = new GlobbingUrlBuilder(_hostingEnvironment.WebRootFileProvider, _cache, ViewContext.HttpContext.Request.PathBase); var files = urlBuilder.BuildUrlList(null, Src + "/*.css", null); var stylesheet = files.SingleOrDefault(f => Path.GetFileName(f).StartsWith("styles", StringComparison.OrdinalIgnoreCase)); if (stylesheet == null) { output.SuppressOutput(); return; } output.TagName = "link"; output.Attributes.Clear(); output.Attributes.Add("rel", "stylesheet"); output.Attributes.Add("href", stylesheet); }
public void UsesCachedMatchResults() { // Arrange var fileProvider = MakeFileProvider(); var expected = new List <string> { "/blank.css", "/site.css" }; var cache = MakeCache(result: expected); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var actual = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(actual, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); }
private void BuildGlobbedScriptTags( TagHelperAttributeList attributes, TagHelperContent builder) { EnsureGlobbingUrlBuilder(); // Build a <script> tag for each matched src as well as the original one in the source file var urls = GlobbingUrlBuilder.BuildUrlList(null, SrcInclude, SrcExclude); foreach (var url in urls) { // "url" values come from bound attributes and globbing. Must always be non-null. Debug.Assert(url != null); if (string.Equals(url, Src, StringComparison.OrdinalIgnoreCase)) { // Don't build duplicate script tag for the original source url. continue; } BuildScriptTag(url, attributes, builder); } }
private void BuildGlobbedLinkTags(TagHelperAttributeList attributes, TagHelperContent builder) { EnsureGlobbingUrlBuilder(); // Build a <link /> tag for each matched href. var urls = GlobbingUrlBuilder.BuildUrlList(null, HrefInclude, HrefExclude); for (var i = 0; i < urls.Count; i++) { var url = urls[i]; // "url" values come from bound attributes and globbing. Must always be non-null. Debug.Assert(url != null); if (string.Equals(Href, url, StringComparison.OrdinalIgnoreCase)) { // Don't build duplicate link tag for the original href url. continue; } BuildLinkTag(url, attributes, builder); } }
public void TrimsLeadingTildeAndSlashFromPatterns(string prefix) { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); var cache = new MemoryCache(new MemoryCacheOptions()); var requestPathBase = PathString.Empty; var includePatterns = new List <string>(); var excludePatterns = new List <string>(); var matcher = MakeMatcher(includePatterns, excludePatterns); var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); globbingUrlBuilder.MatcherBuilder = () => matcher; // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: $"{prefix}**/*.css", excludePattern: $"{prefix}**/*.min.css"); // Assert Assert.Collection(includePatterns, pattern => Assert.Equal("**/*.css", pattern)); Assert.Collection(excludePatterns, pattern => Assert.Equal("**/*.min.css", pattern)); }
public override void Process(TagHelperContext context, TagHelperOutput output) { var urlBuilder = new GlobbingUrlBuilder(_hostingEnvironment.WebRootFileProvider, _cache, ViewContext.HttpContext.Request.PathBase); var files = urlBuilder.BuildUrlList(null, Src + "/*.js", null); files = OrderFiles(files).ToList(); if (!files.Any()) { output.SuppressOutput(); return; } output.TagName = "script-block"; output.Attributes.Clear(); var extraTags = output.PostContent; foreach (var file in files) { extraTags.AppendFormat("<script src=\"{0}\"></script>", file); } }
public void CachesMatchResults() { // Arrange var changeToken = new Mock<IChangeToken>(); var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); Mock.Get(fileProvider).Setup(f => f.Watch(It.IsAny<string>())).Returns(changeToken.Object); var value = new Mock<ICacheEntry>(); value.Setup(c => c.Value).Returns(null); value.Setup(c => c.ExpirationTokens).Returns(new List<IChangeToken>()); var cache = MakeCache(); Mock.Get(cache).Setup(c => c.CreateEntry( /*key*/ It.IsAny<object>())) .Returns((object key) => value.Object) .Verifiable(); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); Mock.Get(cache).VerifyAll(); }
private void BuildFallbackBlock(TagHelperAttributeList attributes, TagHelperContent builder) { EnsureGlobbingUrlBuilder(); var fallbackSrcs = GlobbingUrlBuilder.BuildUrlList(FallbackSrc, FallbackSrcInclude, FallbackSrcExclude); if (fallbackSrcs.Count > 0) { // Build the <script> tag that checks the test method and if it fails, renders the extra script. builder.AppendHtml(Environment.NewLine) .AppendHtml("<script>(") .AppendHtml(FallbackTestExpression) .AppendHtml("||document.write(\""); foreach (var src in fallbackSrcs) { // Fallback "src" values come from bound attributes and globbing. Must always be non-null. Debug.Assert(src != null); StringWriter.Write("<script"); var addSrc = true; // Perf: Avoid allocating enumerator and read interface .Count once rather than per iteration var attributesCount = attributes.Count; for (var i = 0; i < attributesCount; i++) { var attribute = attributes[i]; if (!attribute.Name.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase)) { if (SuppressFallbackIntegrity && string.Equals(IntegrityAttributeName, attribute.Name, StringComparison.OrdinalIgnoreCase)) { continue; } StringWriter.Write(' '); attribute.WriteTo(StringWriter, HtmlEncoder); } else { addSrc = false; WriteVersionedSrc(attribute.Name, src, attribute.ValueStyle, StringWriter); } } if (addSrc) { WriteVersionedSrc(SrcAttributeName, src, HtmlAttributeValueStyle.DoubleQuotes, StringWriter); } StringWriter.Write("></script>"); } var stringBuilder = StringWriter.GetStringBuilder(); var scriptTags = stringBuilder.ToString(); stringBuilder.Clear(); var encodedScriptTags = JavaScriptEncoder.Encode(scriptTags); builder.AppendHtml(encodedScriptTags); builder.AppendHtml("\"));</script>"); } }
public void TrimsOnlySingleLeadingSlashFromPatterns(string leadingSlash) { // Arrange var leadingSlashes = $"{leadingSlash}{leadingSlash}"; var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); IMemoryCache cache = null; var requestPathBase = PathString.Empty; var includePatterns = new List<string>(); var excludePatterns = new List<string>(); var matcher = MakeMatcher(includePatterns, excludePatterns); var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); globbingUrlBuilder.MatcherBuilder = () => matcher; // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: $"{leadingSlashes}**/*.css", excludePattern: $"{leadingSlashes}**/*.min.css"); // Assert Assert.Collection(includePatterns, pattern => Assert.Equal($"{leadingSlash}**/*.css", pattern)); Assert.Collection(excludePatterns, pattern => Assert.Equal($"{leadingSlash}**/*.min.css", pattern)); }
public void CachesMatchResults() { // Arrange var trigger = new Mock<IExpirationTrigger>(); var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); Mock.Get(fileProvider).Setup(f => f.Watch(It.IsAny<string>())).Returns(trigger.Object); var cache = MakeCache(); Mock.Get(cache).Setup(c => c.Set( /*key*/ It.IsAny<string>(), /*value*/ It.IsAny<object>(), /*options*/ It.IsAny<MemoryCacheEntryOptions>())) .Returns(new object()) .Verifiable(); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); Mock.Get(cache).VerifyAll(); }
public void UsesCachedMatchResults() { // Arrange var fileProvider = MakeFileProvider(); var expected = new List<string> { "/blank.css", "/site.css" }; var cache = MakeCache(result: expected); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var actual = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(actual, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); }
public void ResolvesMatchedUrlsAgainstPathBase(string pathBase) { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); IMemoryCache cache = null; var requestPathBase = new PathString(pathBase); var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal($"{pathBase}/blank.css", url), url => Assert.Equal($"{pathBase}/site.css", url)); }
public void OrdersGlobbedMatchResultsCorrectly(string staticUrl, FileNode dirStructure, string[] expectedPaths) { // Arrange var fileProvider = MakeFileProvider(dirStructure); IMemoryCache cache = null; var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList(staticUrl, "**/*.*", excludePattern: null); // Assert var collectionAssertions = expectedPaths.Select<string, Action<string>>(expected => actual => Assert.Equal(expected, actual)); Assert.Collection(urlList, collectionAssertions.ToArray()); }
public void CachesMatchResults() { // Arrange var trigger = new Mock<IExpirationTrigger>(); var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.css")); Mock.Get(fileProvider).Setup(f => f.Watch(It.IsAny<string>())).Returns(trigger.Object); var cache = MakeCache(); var cacheSetContext = new Mock<ICacheSetContext>(); cacheSetContext.Setup(c => c.AddExpirationTrigger(trigger.Object)).Verifiable(); Mock.Get(cache).Setup(c => c.Set( /*key*/ It.IsAny<string>(), /*link*/ It.IsAny<IEntryLink>(), /*state*/ It.IsAny<object>(), /*create*/ It.IsAny<Func<ICacheSetContext, object>>())) .Returns<string, IEntryLink, object, Func<ICacheSetContext, object>>( (key, link, state, create) => { cacheSetContext.Setup(c => c.State).Returns(state); return create(cacheSetContext.Object); }) .Verifiable(); var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: "**/*.css", excludePattern: null); // Assert Assert.Collection(urlList, url => Assert.Equal("/blank.css", url), url => Assert.Equal("/site.css", url)); cacheSetContext.VerifyAll(); Mock.Get(cache).VerifyAll(); }
public void HandlesCommaSeparatedPatterns(string includePattern, string[] expectedOutput) { // Arrange var fileProvider = MakeFileProvider(MakeDirectoryContents("site.css", "blank.js", "site2.txt", "site.js")); IMemoryCache cache = null; var requestPathBase = PathString.Empty; var globbingUrlBuilder = new GlobbingUrlBuilder(fileProvider, cache, requestPathBase); // Act var urlList = globbingUrlBuilder.BuildUrlList( staticUrl: null, includePattern: includePattern, excludePattern: null); // Assert Assert.Equal(expectedOutput, urlList, StringComparer.Ordinal); }
private void BuildFallbackBlock(TagHelperAttributeList attributes, TagHelperContent builder) { EnsureGlobbingUrlBuilder(); var fallbackHrefs = GlobbingUrlBuilder.BuildUrlList( FallbackHref, FallbackHrefInclude, FallbackHrefExclude); if (fallbackHrefs.Count == 0) { return; } builder.AppendHtml(HtmlString.NewLine); // Build the <meta /> tag that's used to test for the presence of the stylesheet builder .AppendHtml("<meta name=\"x-stylesheet-fallback-test\" content=\"\" class=\"") .Append(FallbackTestClass) .AppendHtml("\" />"); // Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra // <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false, // indicating that the primary stylesheet failed to load. // GetEmbeddedJavaScript returns JavaScript to which we add '"{0}","{1}",{2});' builder .AppendHtml("<script>") .AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName)) .AppendHtml("\"") .AppendHtml(JavaScriptEncoder.Encode(FallbackTestProperty)) .AppendHtml("\",\"") .AppendHtml(JavaScriptEncoder.Encode(FallbackTestValue)) .AppendHtml("\","); AppendFallbackHrefs(builder, fallbackHrefs); builder.AppendHtml(", \""); // Perf: Avoid allocating enumerator and read interface .Count once rather than per iteration var attributesCount = attributes.Count; for (var i = 0; i < attributesCount; i++) { var attribute = attributes[i]; if (string.Equals(attribute.Name, HrefAttributeName, StringComparison.OrdinalIgnoreCase)) { continue; } if (SuppressFallbackIntegrity && string.Equals(attribute.Name, IntegrityAttributeName, StringComparison.OrdinalIgnoreCase)) { continue; } attribute.WriteTo(StringWriter, HtmlEncoder); StringWriter.Write(' '); } var stringBuilder = StringWriter.GetStringBuilder(); var scriptTags = stringBuilder.ToString(); stringBuilder.Clear(); var encodedScriptTags = JavaScriptEncoder.Encode(scriptTags); builder.AppendHtml(encodedScriptTags); builder.AppendHtml("\");</script>"); }