From 5d8d3414e373c088360154ade6e6f93800c5c835 Mon Sep 17 00:00:00 2001 From: "Krasmik, Maxim" Date: Thu, 25 Aug 2022 10:26:01 +0200 Subject: [PATCH 1/9] #Test for linebreaks-minification for all possible files in input-directory --- src/NUglify.Tests/App.config | 10 +- .../JavaScript/AllJavascriptSyntaxTest.cs | 17 ++++ .../JavaScript/Common/TestHelper.cs | 97 +++++++++++++++++++ src/NUglify.Tests/NUglify.Tests.csproj | 57 ++++++++++- 4 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 src/NUglify.Tests/JavaScript/AllJavascriptSyntaxTest.cs diff --git a/src/NUglify.Tests/App.config b/src/NUglify.Tests/App.config index 45437954..9fabdef4 100644 --- a/src/NUglify.Tests/App.config +++ b/src/NUglify.Tests/App.config @@ -1,6 +1,14 @@ - + + + + + + + + + diff --git a/src/NUglify.Tests/JavaScript/AllJavascriptSyntaxTest.cs b/src/NUglify.Tests/JavaScript/AllJavascriptSyntaxTest.cs new file mode 100644 index 00000000..a963614d --- /dev/null +++ b/src/NUglify.Tests/JavaScript/AllJavascriptSyntaxTest.cs @@ -0,0 +1,17 @@ +using NUglify.Tests.JavaScript.Common; +using NUnit.Framework; + +namespace NUglify.Tests.JavaScript +{ + [TestFixture] + public class AllJavascriptSyntaxTest + { + /// + /// check all possible files in input-directory for syntax errors after minification + /// + [Test] + public void SyntaxTestForAllFilesLineBreaks() { + TestHelper.Instance.RunSyntaxTestForAllFilesLineBreaks(); + } + } +} \ No newline at end of file diff --git a/src/NUglify.Tests/JavaScript/Common/TestHelper.cs b/src/NUglify.Tests/JavaScript/Common/TestHelper.cs index e85afd6b..a5b1e8df 100644 --- a/src/NUglify.Tests/JavaScript/Common/TestHelper.cs +++ b/src/NUglify.Tests/JavaScript/Common/TestHelper.cs @@ -18,10 +18,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; using System.Xml; +using Microsoft.ClearScript; +using Microsoft.ClearScript.V8; using NUglify.JavaScript; using NUglify.JavaScript.Visitors; using NUnit.Framework; @@ -700,6 +704,99 @@ public void RunErrorTest(params JSError[] expectedErrorArray) RunErrorTest(string.Empty, expectedErrorArray); } + /// + /// check all files in input-directory for syntax errors after minification + /// execute javascript in V8 engine + /// each file that starts successfully without minification will be rerun after minification. + /// in some cases minifier generate endless running code. Example: D:\Git2\NUglify\src\NUglify.Tests\bin\Debug\TestData\JS\Input\ES2015\GeneratorFunction.js + /// + /// + public void RunSyntaxTestForAllFilesLineBreaks() { + int timeOutSeconds = 2; + DirectoryInfo dir = new DirectoryInfo(InputFolder); + List alltTestFiles = dir.GetFiles("*.js", SearchOption.AllDirectories).ToList(); + var switchParser = new UglifyCommandParser(); + switchParser.Parse("-line:1"); + var filesToTest = alltTestFiles.Select(fi => { + string jsSource = File.ReadAllText(fi.FullName); + var engine = new V8ScriptEngine(); + bool testPassed = false; + + var task = Task.Run(() => { + try { + Trace.Write($"Testing unminified file: {fi.Name} "); + engine.Execute(jsSource); + testPassed = true; + } catch (ScriptEngineException e) { + if (e.ExecutionStarted) { + testPassed = true; + } + } + }); + bool timedOut = !task.Wait(TimeSpan.FromSeconds(timeOutSeconds)); + Trace.WriteLine(timedOut ? "finished." : "timed out, but execution started."); + return new { + testPassed = testPassed, + timedOut = timedOut, + file = fi, + jsSource = jsSource + }; + }).Where(f => f.testPassed).ToList(); + var failedFiles = filesToTest.Select(f => { + var engine = new V8ScriptEngine(); + var sb = new StringBuilder(); + var parser = new JSParser(); + var testPassed = false; + ScriptEngineException exception = new ScriptEngineException(); + using (var writer = new StringWriter(sb)) { + if (switchParser.JSSettings.PreprocessOnly) { + parser.EchoWriter = writer; + } + // normal -- just run it through the parser + var block = parser.Parse(new DocumentContext(f.jsSource) { FileContext = f.file.FullName }, switchParser.JSSettings); + if (!switchParser.JSSettings.PreprocessOnly) { + // look at the settings for the proper output visitor + if (switchParser.JSSettings.Format == JavaScriptFormat.JSON) { + { + if (!JsonOutputVisitor.Apply(writer, block, switchParser.JSSettings)) { + Trace.WriteLine("JSON OUTPUT ERRORS!"); + } + } + } else { + OutputVisitor.Apply(writer, block, switchParser.JSSettings); + } + } + } + var crunchedCode = sb.ToString(); + var task = Task.Run(() => { + try { + Trace.Write($"Testing minified file: {f.file.Name} "); + engine.Execute(crunchedCode); + testPassed = true; + } catch (ScriptEngineException e) { + exception = e; + if (e.ExecutionStarted) { + testPassed = true; + } + } + }); + bool timedOut = !task.Wait(TimeSpan.FromSeconds(timeOutSeconds)); + Trace.WriteLine(timedOut ? "finished" : "timed out, but execution started."); + if (!testPassed && f.timedOut == timedOut && exception.ErrorDetails.StartsWith("An error occurred during script execution")) { // if test timed out before its probably not a wrong syntax. + testPassed = true; + } + return new { + testPassed = testPassed, + exception = exception, + filePath = f.file.FullName, + minifiedContent = crunchedCode + }; + }).Where(f => !f.testPassed).ToList(); + if (failedFiles.Count > 0) { + throw new AggregateException("Test failed, following files have wrong syntax after minification." + Environment.NewLine + String.Join(Environment.NewLine, failedFiles.Select(f => $"{f.filePath} => {f.exception.ErrorDetails}{Environment.NewLine}{f.minifiedContent}{Environment.NewLine}")), failedFiles.Select(f => f.exception)); + } + } + public void RunErrorTest(string settingsSwitches, params JSError[] expectedErrorArray) { // open the stack trace for this call diff --git a/src/NUglify.Tests/NUglify.Tests.csproj b/src/NUglify.Tests/NUglify.Tests.csproj index 4b8c3e01..5a8e2535 100644 --- a/src/NUglify.Tests/NUglify.Tests.csproj +++ b/src/NUglify.Tests/NUglify.Tests.csproj @@ -1,5 +1,8 @@  + + + Debug @@ -43,13 +46,55 @@ + + ..\packages\Microsoft.ClearScript.Core.7.3.1\lib\net45\ClearScript.Core.dll + + + ..\packages\Microsoft.ClearScript.V8.7.3.1\lib\net45\ClearScript.V8.dll + + + ..\packages\Microsoft.ClearScript.V8.ICUData.7.3.1\lib\netstandard1.0\ClearScript.V8.ICUData.dll + + + ..\packages\Microsoft.ClearScript.Windows.7.3.1\lib\net45\ClearScript.Windows.dll + + + ..\packages\Microsoft.ClearScript.Windows.Core.7.3.1\lib\net45\ClearScript.Windows.Core.dll + + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NUnit.3.13.3\lib\net45\nunit.framework.dll + + + ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + - @@ -98,6 +143,7 @@ + @@ -166,6 +212,7 @@ + PreserveNewest @@ -4187,6 +4234,14 @@ + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + + +