Пример #1
0
        public void CssHackSelectorsTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile      = Path.Combine(sourceDirectory, @"Input\Case3\HackValidation.css");
            minifyCssActivity.DestinationFile = Path.Combine(sourceDirectory, @"Output\Case3\HackValidation.css");
            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            foreach (var hack in BlackListedSelectors)
            {
                minifyCssActivity.HackSelectors.Add(hack);
            }

            Exception exception = null;

            try
            {
                minifyCssActivity.Execute();
            }
            catch (AggregateException aggregateException)
            {
                exception = aggregateException.InnerExceptions.FirstOrDefault();
            }
            catch (WorkflowException workflowException)
            {
                exception = workflowException;
            }

            // shouldn't assert, but should log the error and NOT create output file
            Assert.IsFalse(File.Exists(minifyCssActivity.DestinationFile));
        }
Пример #2
0
        /// <summary>Processes css files for images to merge (sprite)</summary>
        /// <param name="context">The context.</param>
        private static void ExecuteImageSpriting(IWebGreaseContext context)
        {
            // whiles this uses the minification activity, it is only assembling images
            var spriter = new MinifyCssActivity(context)
            {
                ShouldMinify   = false,
                ShouldOptimize = false,
                ShouldAssembleBackgroundImages = true
            };


            foreach (var fileSet in context.Configuration.CssFileSets.Where(file => file.InputSpecs.Any()))
            {
                // for each file set, get the configuration and setup the assembler object.
                var spriteConfig = fileSet.ImageSpriting.GetNamedConfig(context.Configuration.ConfigType);

                if (spriteConfig.ShouldAutoSprite)
                {
                    var outputPath    = GetOutputFolder(fileSet.Output, context.Configuration.DestinationDirectory);
                    var directoryName = string.IsNullOrWhiteSpace(Path.GetExtension(outputPath)) ? outputPath : Path.GetDirectoryName(outputPath);

                    spriter.ShouldAssembleBackgroundImages = spriteConfig.ShouldAutoSprite;
                    spriter.ImageAssemblyPadding           = spriteConfig.ImagePadding;
                    spriter.ImageAssembleReferencesToIgnore.Clear();
                    foreach (var image in spriteConfig.ImagesToIgnore)
                    {
                        spriter.ImageAssembleReferencesToIgnore.Add(image);
                    }

                    // run the spriter on every file in each of the input specs
                    foreach (var source in fileSet.InputSpecs.SelectMany(inputSpec => GetFiles(inputSpec.Path, inputSpec.SearchPattern, inputSpec.SearchOption)))
                    {
                        spriter.SourceFile = source;

                        spriter.DestinationFile       = Path.Combine(directoryName, Path.GetFileName(source));
                        spriter.ImagesOutputDirectory = Path.IsPathRooted(spriteConfig.DestinationImageFolder)
                                                            ? spriteConfig.DestinationImageFolder
                                                            : Path.Combine(directoryName, spriteConfig.DestinationImageFolder);

                        var file         = Path.GetFileNameWithoutExtension(spriter.DestinationFile);
                        var scanFilePath = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(file) + ".scan." + Strings.Css);
                        spriter.ImageAssembleScanDestinationFile = scanFilePath;
                        try
                        {
                            spriter.Execute();
                        }
                        catch (WorkflowException ex)
                        {
                            HandleError(ex.InnerException ?? ex, source);
                        }
                    }
                }
            }
        }
Пример #3
0
        public void CssImageSpriteTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile = Path.Combine(sourceDirectory, @"Input\Case6\SpriteTest.css");
            minifyCssActivity.ImageAssembleScanDestinationFile = Path.Combine(sourceDirectory, @"Output\Case6\SpriteTest_Scan.css");
            minifyCssActivity.ImagesOutputDirectory            = Path.Combine(sourceDirectory, @"Output\Case6\Images\");
            minifyCssActivity.DestinationFile = Path.Combine(sourceDirectory, @"Output\Case6\SpriteTest.css");
            minifyCssActivity.ShouldAssembleBackgroundImages = true;
            minifyCssActivity.OutputUnit       = "rem";
            minifyCssActivity.OutputUnitFactor = 0.1;
            minifyCssActivity.ShouldMinify     = true;
            minifyCssActivity.ShouldOptimize   = true;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            // mapping file (so we can look up the target name of the assembled image, as the generated image can be different based on gdi dll versions)
            var mapFilePath = minifyCssActivity.ImageAssembleScanDestinationFile + ".xml";
            var testImage   = "media.gif";

            Assert.IsTrue(File.Exists(outputFilePath));

            Assert.IsTrue(File.Exists(mapFilePath));
            // verify our test file is in the xml file and get the source folder and assembled file name.
            string relativePath;

            using (var fs = File.OpenRead(mapFilePath))
            {
                var mapFile      = XDocument.Load(fs);
                var inputElement = mapFile.Root.Descendants()
                                   // get at the input elements
                                   .Descendants().Where(e => e.Name == "input")
                                   // now at the source file name
                                   .Descendants().FirstOrDefault(i => i.Name == "originalfile" && i.Value.Contains(testImage));

                // get the output
                var outputElement = inputElement.Parent.Parent;

                // get the input path from the location of the css file and the output path where the destination file is.
                var inputPath  = Path.GetDirectoryName(inputElement.Value).ToLowerInvariant();
                var outputPath = outputElement.Attribute("file").Value.ToLowerInvariant();

                // diff the paths to get the relative path (as found in the final file)
                relativePath = outputPath.MakeRelativeTo(inputPath);
            }

            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(text.Contains("background:0 0 url(" + relativePath + ") no-repeat;"));
        }
Пример #4
0
        private static void ProcessCssFileSet(MinifyCssActivity cssCruncher, CssFileSet fileSet, string configType, string baseOutputPath)
        {
            var cssConfig = fileSet.Minification.GetNamedConfig(configType);

            if (cssConfig.ShouldMinify)
            {
                foreach (var file in fileSet.InputSpecs.SelectMany(inputSpec => GetFiles(inputSpec.Path, inputSpec.SearchPattern, inputSpec.SearchOption)))
                {
                    cssCruncher.ShouldMinify   = cssConfig.ShouldMinify;
                    cssCruncher.ShouldOptimize = cssConfig.ShouldMinify;

                    foreach (string hack in cssConfig.ForbiddenSelectors)
                    {
                        cssCruncher.HackSelectors.Add(hack);
                    }

                    cssCruncher.SourceFile = file;
                    cssCruncher.ShouldExcludeProperties = true;

                    // disable lower case validation (this is on by default).
                    cssCruncher.ShouldValidateForLowerCase = cssConfig.ShouldValidateLowerCase;

                    // we are just minifying. Image assembly is a different action.
                    cssCruncher.ShouldAssembleBackgroundImages = false;
                    var outputPath = GetOutputFolder(fileSet.Output, baseOutputPath);
                    cssCruncher.DestinationFile = GetOutputFilename(file, outputPath, true);

                    try
                    {
                        cssCruncher.Execute();
                    }
                    catch (Exception ex)
                    {
                        AggregateException aggEx;

                        if (ex.InnerException != null &&
                            (aggEx = ex.InnerException as AggregateException) != null)
                        {
                            // antlr can throw a blob of errors, so they need to be deduped to get the real set of errors
                            IEnumerable <string> messages = ErrorHelper.DedupeCSSErrors(aggEx);
                            DisplayErrors(messages, file);
                        }
                        else
                        {
                            // Catch, record and display error
                            HandleError(ex, file);
                        }
                    }
                }
            }
        }
Пример #5
0
        public void CssImageSpriteTest2()
        {
            var sourceDirectory = Path.Combine(
                TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile = Path.Combine(sourceDirectory, @"Input\Case7\SpriteTest.css");
            minifyCssActivity.ImageAssembleScanDestinationFile = Path.Combine(
                sourceDirectory, @"Output\Case7\SpriteTest_Scan.css");
            Path.Combine(
                sourceDirectory, @"Output\Case7\SpriteTest_Update.css");
            minifyCssActivity.ImagesOutputDirectory          = Path.Combine(sourceDirectory, @"Output\Case6\Images\");
            minifyCssActivity.DestinationFile                = Path.Combine(sourceDirectory, @"Output\Case7\SpriteTest.css");
            minifyCssActivity.ShouldAssembleBackgroundImages = true;
            minifyCssActivity.OutputUnit       = "rem";
            minifyCssActivity.OutputUnitFactor = 0.1;
            minifyCssActivity.ShouldMinify     = true;
            minifyCssActivity.ShouldOptimize   = true;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            // mapping file (so we can look up the target name of the assembled image, as the generated image can be different based on gdi dll versions)
            var mapFilePath = minifyCssActivity.ImageAssembleScanDestinationFile + ".xml";
            var testImage   = "media.gif";

            Assert.IsTrue(File.Exists(outputFilePath));

            Assert.IsTrue(File.Exists(mapFilePath));
            // verify our test file is in the xml file and get the source folder and assembled file name.
            using (var fs = File.OpenRead(mapFilePath))
            {
                var mapFile = XDocument.Load(fs);
                mapFile.Root.Descendants()
                // get at the input elements
                .Descendants().Where(e => e.Name == "input")
                // now at the source file name
                .Descendants().FirstOrDefault(i => i.Name == "originalfile" && i.Value.Contains(testImage));
            }

            // Minified result
            outputFilePath = minifyCssActivity.DestinationFile;
            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(!text.Contains("/*"));
            Assert.IsTrue(!text.Contains("*/"));
            Assert.IsTrue(!text.Contains(";;"));
        }
Пример #6
0
        /// <summary>
        /// Executes the minification task
        /// </summary>
        /// <param name="context">context with settings to be used. Only used for the input/output settings.</param>
        private static void ExecuteMinification(IWebGreaseContext context)
        {
            var jsCruncher  = new MinifyJSActivity(context);
            var cssCruncher = new MinifyCssActivity(context);

            // only run the crunchers if the configuration has files for that particular file type
            foreach (var fileSet in context.Configuration.JSFileSets.Where(set => set.InputSpecs.Any()))
            {
                ProcessJsFileSet(jsCruncher, fileSet, context.Configuration.ConfigType, context.Configuration.DestinationDirectory);
            }

            // do the same thing for CSS files... nested loops are fun!
            foreach (var fileSet in context.Configuration.CssFileSets.Where(set => set.InputSpecs.Any()))
            {
                ProcessCssFileSet(cssCruncher, fileSet, context.Configuration.ConfigType, context.Configuration.DestinationDirectory);
            }
        }
Пример #7
0
        public void MultipleFontFaceUrlTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration {
                SourceDirectory = Path.Combine(sourceDirectory, @"Input\Case10")
            }));

            minifyCssActivity.ImageDirectories = new List <string> {
                Path.Combine(sourceDirectory, @"Input\Case10\fonts")
            };
            minifyCssActivity.ImageExtensions = new List <string> {
                "*.eot", "*.svg", "*.ttf", "*.woff"
            };
            minifyCssActivity.SourceFile        = Path.Combine(sourceDirectory, @"Input\Case10\FontFaceHashing.css");
            minifyCssActivity.DestinationFile   = Path.Combine(sourceDirectory, @"Output\Case10\FontFaceHashing.css");
            minifyCssActivity.NonMergeSelectors = new HashSet <string> {
                "@font-face"
            };
            minifyCssActivity.ShouldValidateForLowerCase     = true;
            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            minifyCssActivity.ShouldOptimize = false;
            minifyCssActivity.ShouldMinify   = true;

            var fileHasherActivity = new FileHasherActivity(new WebGreaseContext(new WebGreaseConfiguration()));
            //fileHasherActivity.SourceDirectories.Add(Path.Combine(sourceDirectory, "fonts"));
            var destinationDirectory = Path.Combine(TestDeploymentPaths.TestDirectory, @"Output\Case10\fonts");

            fileHasherActivity.DestinationDirectory = destinationDirectory;
            fileHasherActivity.CreateExtraDirectoryLevelFromHashes    = true;
            fileHasherActivity.ShouldPreserveSourceDirectoryStructure = false;
            fileHasherActivity.ConfigType = string.Empty;
            fileHasherActivity.BasePrefixToRemoveFromOutputPathInLog = destinationDirectory;
            fileHasherActivity.LogFileName = Path.Combine(sourceDirectory, @"Output\Case10\css_log.xml");

            minifyCssActivity.Execute(imageHasher: fileHasherActivity);

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text         = File.ReadAllText(outputFilePath);
            var expectedText = File.ReadAllText(Path.Combine(sourceDirectory, @"Input\Case10\FontFaceHashing-hashed.css"));

            Assert.IsTrue(text.Equals(expectedText, StringComparison.OrdinalIgnoreCase));
        }
Пример #8
0
        public void CssLowerCaseValidationTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile                     = Path.Combine(sourceDirectory, @"Input\Case2\LowerCaseValidation.css");
            minifyCssActivity.DestinationFile                = Path.Combine(sourceDirectory, @"Output\Case2\LowerCaseValidation.css");
            minifyCssActivity.ShouldValidateForLowerCase     = true;
            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(!string.IsNullOrWhiteSpace(text));
        }
Пример #9
0
        public void CSSImportantOutsideCommentTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile                     = Path.Combine(sourceDirectory, @"Input\Case8\commentOutside.css");
            minifyCssActivity.DestinationFile                = Path.Combine(sourceDirectory, @"Output\Case8\commentOutside.css");
            minifyCssActivity.ShouldValidateForLowerCase     = false;
            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(!string.IsNullOrWhiteSpace(text));
            Assert.IsTrue(text.Contains("/*! this is comment outside of ruleset*/"));
            Assert.IsTrue(!text.Contains("/* regular comment */"));
        }
Пример #10
0
        public void TokenUrlsShouldNotBeHashed()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration {
                SourceDirectory = Path.Combine(sourceDirectory, @"Input\Case10")
            }));

            minifyCssActivity.SourceFile      = Path.Combine(sourceDirectory, @"Input\Case11\TokenImageIgnore.css");
            minifyCssActivity.DestinationFile = Path.Combine(sourceDirectory, @"Output\Case11\TokenImageIgnore.css");

            var fileHasherActivity = new FileHasherActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.Execute(imageHasher: fileHasherActivity);

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(text.Contains("%IMAGE:abcdefg%"));
        }
Пример #11
0
        public void CSSBinaryOperatorTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile                     = Path.Combine(sourceDirectory, @"Input\Case9\functionsWithBinaryOperators.css");
            minifyCssActivity.DestinationFile                = Path.Combine(sourceDirectory, @"Output\Case9\functionsWithBinaryOperators.css");
            minifyCssActivity.ShouldValidateForLowerCase     = false;
            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(!string.IsNullOrWhiteSpace(text));
            Assert.IsTrue(text.Contains("calc(100%/3 - 2*1em - 2*1px)"));
            Assert.IsTrue(text.Contains("calc(1em - 2px) calc(1em - 1px)"));
            Assert.IsTrue(text.Contains("min(10% + 20px,300px"));
        }
Пример #12
0
        public void CssBannedSelectorsTest()
        {
            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\MinifyCssActivityTest");
            var minifyCssActivity = new MinifyCssActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            minifyCssActivity.SourceFile      = Path.Combine(sourceDirectory, @"Input\Case4\HackValidation.css");
            minifyCssActivity.DestinationFile = Path.Combine(sourceDirectory, @"Output\Case4\HackValidation.css");
            foreach (var hack in BlackListedSelectors)
            {
                minifyCssActivity.BannedSelectors.Add(hack);
            }

            minifyCssActivity.ShouldAssembleBackgroundImages = false;
            minifyCssActivity.Execute();

            // Assertions
            var outputFilePath = minifyCssActivity.DestinationFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(string.IsNullOrWhiteSpace(text));
        }