Skip to content

Commit

Permalink
In WebMarkupMin.Yui a JS error summary has been excluded from the lis…
Browse files Browse the repository at this point in the history
…t of errors
  • Loading branch information
Taritsyn committed Jun 20, 2022
1 parent f32e44e commit 4bc6faa
Show file tree
Hide file tree
Showing 8 changed files with 478 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/WebMarkupMin.Yui/WebMarkupMin.Yui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Description>WebMarkupMin.Yui contains 2 minifier-adapters: `YuiCssMinifier` (for minification of CSS code) and `YuiJsMinifier` (for minification of JS code). These adapters perform minification using the YUI Compressor for .NET (https://github.com/YUICompressor-NET/YUICompressor.NET).</Description>
<PackageTags>WebMarkupMin;Markup;HTML;XHTML;CSS;JavaScript;JS;Minification;Minifier;Minify;Obfuscation;YUICompressor</PackageTags>
<PackageReleaseNotes>Added support of the YUI Compressor for .NET version 3.1.0.</PackageReleaseNotes>
<PackageReleaseNotes>JS error summary has been excluded from the list of errors.</PackageReleaseNotes>
</PropertyGroup>

<Import Project="../../build/common.props" />
Expand Down
12 changes: 11 additions & 1 deletion src/WebMarkupMin.Yui/YuiJsMinifier.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

using EcmaScript.NET;
using Yahoo.Yui.Compressor;
Expand Down Expand Up @@ -35,6 +36,12 @@ public sealed class YuiJsMinifier : YuiMinifierBase, IJsMinifier
/// </summary>
private readonly object _minificationSynchronizer = new object();

/// <summary>
/// Regular expression for working with the error message with summary
/// </summary>
private static readonly Regex _errorMessageWithSummaryRegex =
new Regex(@"^Compilation produced \d+ syntax errors.$");


/// <summary>
/// Constructs an instance of the YUI JS Minifier
Expand Down Expand Up @@ -133,7 +140,10 @@ public CodeMinificationResult Minify(string content, bool isInlineCode, Encoding
}
catch (EcmaScriptRuntimeException e)
{
errors.Add(new MinificationErrorInfo(e.Message, e.LineNumber, e.ColumnNumber, e.LineSource));
if (!_errorMessageWithSummaryRegex.IsMatch(e.Message))
{
errors.Add(new MinificationErrorInfo(e.Message, e.LineNumber, e.ColumnNumber, e.LineSource));
}
}
catch (EcmaScriptException e)
{
Expand Down
2 changes: 1 addition & 1 deletion src/WebMarkupMin.Yui/readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
=============
RELEASE NOTES
=============
Added support of the YUI Compressor for .NET version 3.1.0.
JS error summary has been excluded from the list of errors.

=============
DOCUMENTATION
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
using System;
using System.Collections.Generic;

using Xunit;

using WebMarkupMin.Core;
using WebMarkupMin.MsAjax;
using WebMarkupMin.NUglify;
using WebMarkupMin.Yui;

namespace WebMarkupMin.Tests.Html.Common.Minification
{
public class HandlingEmbeddedCssCodeMinificationErrorsTests : IDisposable
{
private HtmlMinifier _nullMinifier;
private HtmlMinifier _kristensenMinifier;
private HtmlMinifier _msAjaxMinifier;
private HtmlMinifier _nuglifyMinifier;
private HtmlMinifier _yuiMinifier;


public HandlingEmbeddedCssCodeMinificationErrorsTests()
{
var settings = new HtmlMinificationSettings(true) { MinifyEmbeddedCssCode = true };

_nullMinifier = new HtmlMinifier(settings, cssMinifier: new NullCssMinifier());
_kristensenMinifier = new HtmlMinifier(settings, cssMinifier: new KristensenCssMinifier());
_msAjaxMinifier = new HtmlMinifier(settings, cssMinifier: new MsAjaxCssMinifier());
_nuglifyMinifier = new HtmlMinifier(settings, cssMinifier: new NUglifyCssMinifier());
_yuiMinifier = new HtmlMinifier(settings, cssMinifier: new YuiCssMinifier());
}


[Fact]
public void HandlingMinificationErrorsInStyleTagIsCorrect()
{
// Arrange
const string input = "<style type=\"text/css\">\n" +
" .main-content a:visited::before {\n" +
" content: \"\\2713 ;\n" +
" }\n\n" +
" .footer {\n" +
" background-color: #eee;\n" +
" rgba(85, 85, 85, 1;\n" +
" text-decoration: none;\n" +
" }\n" +
"</style>"
;

// Act
IList<MinificationErrorInfo> errorsA = _nullMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsB = _kristensenMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsC = _msAjaxMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsD = _nuglifyMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsE = _yuiMinifier.Minify(input).Errors;

// Assert
Assert.Equal(0, errorsA.Count);

Assert.Equal(0, errorsB.Count);

Assert.Equal(3, errorsC.Count);
Assert.Equal("Unterminated string: \"✓;", errorsC[0].Message);
Assert.Equal(4, errorsC[0].LineNumber);
Assert.Equal(0, errorsC[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsC[1].Message);
Assert.Equal(3, errorsC[1].LineNumber);
Assert.Equal(18, errorsC[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsC[2].Message);
Assert.Equal(8, errorsC[2].LineNumber);
Assert.Equal(9, errorsC[2].ColumnNumber);

Assert.Equal(3, errorsD.Count);
Assert.Equal("Unterminated string: \"✓;", errorsD[0].Message);
Assert.Equal(3, errorsD[0].LineNumber);
Assert.Equal(25, errorsD[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsD[1].Message);
Assert.Equal(3, errorsD[1].LineNumber);
Assert.Equal(18, errorsD[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsD[2].Message);
Assert.Equal(8, errorsD[2].LineNumber);
Assert.Equal(9, errorsD[2].ColumnNumber);

Assert.Equal(0, errorsE.Count);
}

[Fact]
public void HandlingMinificationErrorsInStyleTagWithHtmlCommentIsCorrect()
{
// Arrange
const string input = "<style type=\"text/css\">\n" +
" <!--\n" +
" .main-content a:visited::before {\n" +
" content: \"\\2713 ;\n" +
" }\n\n" +
" .footer {\n" +
" background-color: #eee;\n" +
" rgba(85, 85, 85, 1;\n" +
" text-decoration: none;\n" +
" }\n" +
" -->\n" +
"</style>"
;

// Act
IList<MinificationErrorInfo> errorsA = _nullMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsB = _kristensenMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsC = _msAjaxMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsD = _nuglifyMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsE = _yuiMinifier.Minify(input).Errors;

// Assert
Assert.Equal(0, errorsA.Count);

Assert.Equal(0, errorsB.Count);

Assert.Equal(3, errorsC.Count);
Assert.Equal("Unterminated string: \"✓;", errorsC[0].Message);
Assert.Equal(5, errorsC[0].LineNumber);
Assert.Equal(0, errorsC[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsC[1].Message);
Assert.Equal(4, errorsC[1].LineNumber);
Assert.Equal(18, errorsC[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsC[2].Message);
Assert.Equal(9, errorsC[2].LineNumber);
Assert.Equal(9, errorsC[2].ColumnNumber);

Assert.Equal(3, errorsD.Count);
Assert.Equal("Unterminated string: \"✓;", errorsD[0].Message);
Assert.Equal(4, errorsD[0].LineNumber);
Assert.Equal(25, errorsD[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsD[1].Message);
Assert.Equal(4, errorsD[1].LineNumber);
Assert.Equal(18, errorsD[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsD[2].Message);
Assert.Equal(9, errorsD[2].LineNumber);
Assert.Equal(9, errorsD[2].ColumnNumber);

Assert.Equal(0, errorsE.Count);
}

[Fact]
public void HandlingMinificationErrorsInStyleTagWithCdataSectionIsCorrect()
{
// Arrange
const string input = "<style type=\"text/css\">\n" +
" /*<![CDATA[*/\n" +
" .main-content a:visited::before {\n" +
" content: \"\\2713 ;\n" +
" }\n\n" +
" .footer {\n" +
" background-color: #eee;\n" +
" rgba(85, 85, 85, 1;\n" +
" text-decoration: none;\n" +
" }\n" +
" /*]]>*/\n" +
"</style>"
;

// Act
IList<MinificationErrorInfo> errorsA = _nullMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsB = _kristensenMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsC = _msAjaxMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsD = _nuglifyMinifier.Minify(input).Errors;
IList<MinificationErrorInfo> errorsE = _yuiMinifier.Minify(input).Errors;

// Assert
Assert.Equal(0, errorsA.Count);

Assert.Equal(0, errorsB.Count);

Assert.Equal(3, errorsC.Count);
Assert.Equal("Unterminated string: \"✓;", errorsC[0].Message);
Assert.Equal(5, errorsC[0].LineNumber);
Assert.Equal(0, errorsC[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsC[1].Message);
Assert.Equal(4, errorsC[1].LineNumber);
Assert.Equal(18, errorsC[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsC[2].Message);
Assert.Equal(9, errorsC[2].LineNumber);
Assert.Equal(9, errorsC[2].ColumnNumber);

Assert.Equal(3, errorsD.Count);
Assert.Equal("Unterminated string: \"✓;", errorsD[0].Message);
Assert.Equal(4, errorsD[0].LineNumber);
Assert.Equal(25, errorsD[0].ColumnNumber);
Assert.Equal("Expected expression, found '\"✓;\r\n'", errorsD[1].Message);
Assert.Equal(4, errorsD[1].LineNumber);
Assert.Equal(18, errorsD[1].ColumnNumber);
Assert.Equal("Expected semicolon or closing curly-brace, found 'rgba('", errorsD[2].Message);
Assert.Equal(9, errorsD[2].LineNumber);
Assert.Equal(9, errorsD[2].ColumnNumber);

Assert.Equal(0, errorsE.Count);
}

#region IDisposable implementation

public void Dispose()
{
_nullMinifier = null;
_kristensenMinifier = null;
_msAjaxMinifier = null;
_nuglifyMinifier = null;
_yuiMinifier = null;
}

#endregion
}
}
Loading

0 comments on commit 4bc6faa

Please sign in to comment.