public void StraightDownTheRoadCopyShouldSucceed() { var source = new TextFileContents( "styles.css", new DateTime(2013, 2, 6, 18, 19, 0), ".Woo{color:black}" ); var contentRepresentation = DiskCachingTextFileLoader.GetFileContentRepresentation(source, 68); TextFileContents copy; using (var reader = new StringReader(contentRepresentation)) { copy = DiskCachingTextFileLoader.GetFileContents(reader); } Assert.Equal <TextFileContents>( source, copy, new TextFileContentsComparer() ); }
/// <summary> /// This will combine a stylesheet with all of its imports (and any imports within those, and within those, etc..) and minify the resulting content for cases only /// where all files are in the same folder and no relative or absolute paths are specified in the import declarations. It incorporates caching of the minified /// content and implements 304 responses for cases where the request came with an If-Modified-Since header indicating that current content already exists on the /// client. The last-modified-date for the content is determined by retrieving the most recent LastWriteTime for any file in the folder - although this may lead /// to some false-positives if unrelated files are updated, it does mean that if any file that IS part of the combined stylesheet is updated then the content /// will be identified as stale and re-generated. The cached content will likewise be invalidated and updated if any files in the folder have changed since the /// date recorded for the cached data. GZip and Deflate compression of the response are supported where specified in Accept-Encoding request headers. /// </summary> private ActionResult Process( string relativePath, ICacheThingsWithModifiedDates <TextFileContents> memoryCache, DateTime?lastModifiedDateFromRequest) { if (string.IsNullOrWhiteSpace(relativePath)) { throw new ArgumentException("Null/blank relativePath specified"); } if (memoryCache == null) { throw new ArgumentNullException("memoryCache"); } // Using the SingleFolderLastModifiedDateRetriever means that we can determine whether cached content (either in the ASP.Net cache or in the browser cache) // is up to date without having to perform the complete import flattening process. It may lead to some unnecessary work if an unrelated file in the folder // is updated but for the most common cases it should be an efficient approach. var lastModifiedDateRetriever = new SingleFolderLastModifiedDateRetriever(new ServerUtilityPathMapper(Server), new[] { "css", "less" }); var lastModifiedDate = lastModifiedDateRetriever.GetLastModifiedDate(relativePath); if ((lastModifiedDateFromRequest != null) && AreDatesApproximatelyEqual(lastModifiedDateFromRequest.Value, lastModifiedDate)) { Response.StatusCode = 304; Response.StatusDescription = "Not Modified"; return(Content("", "text/css")); } // In the interests of compatability with this generic example project, we'll use the DefaultNonCachedLessCssLoaderFactory which will enable LESS compilation, // import-flattening, minification and pseudo-source-mapping but doesn't support the advanced features that the EnhancedNonCachedLessCssLoaderFactory does // such as media-query-grouping and scope-restricting html-tag stripping (see comments in the EnhancedNonCachedLessCssLoaderFactory for more information) var cssLoader = (new DefaultNonCachedLessCssLoaderFactory(Server)).Get(); // Layers of caching are added to persist the processed content in memory and on disk (last-modified-date checking is incorporated so that cache entries are // expired if the source files have changed since the cached data was stored) var diskCachingCssLoader = new DiskCachingTextFileLoader( cssLoader, relativePathRequested => new FileInfo(Server.MapPath(relativePathRequested) + ".cache"), lastModifiedDateRetriever, DiskCachingTextFileLoader.InvalidContentBehaviourOptions.Delete, ErrorBehaviourOptions.LogAndRaiseException, new NullLogger() ); var memoryAndDiskCachingCssLoader = new CachingTextFileLoader( diskCachingCssLoader, lastModifiedDateRetriever, memoryCache ); var content = memoryAndDiskCachingCssLoader.Load(relativePath); if (content == null) { throw new Exception("Received null response from Css Loader - this should not happen"); } if ((lastModifiedDateFromRequest != null) && AreDatesApproximatelyEqual(lastModifiedDateFromRequest.Value, lastModifiedDate)) { Response.StatusCode = 304; Response.StatusDescription = "Not Modified"; return(Content("", "text/css")); } SetResponseCacheHeadersForSuccess(content.LastModified); return(Content(content.Content, "text/css")); }