public void ParserShouldProduceExpectedResultOrSyntaxError(ParserTestData testData) { var(outAst, outMinJs, outMinJsMap, outNiceJs, outNiceJsMap) = ParseTestCore(testData); Assert.Equal(testData.ExpectedAst, outAst); Assert.Equal(testData.ExpectedMinJs, outMinJs); Assert.Equal(testData.ExpectedMinJsMap, outMinJsMap); Assert.Equal(testData.ExpectedNiceJs, outNiceJs); Assert.Equal(testData.ExpectedNiceJsMap, outNiceJsMap); }
public IEnumerable <ParserTestData> GetParserData() { return(InputFiles.Select(inputFile => { var inputMapFile = PathUtils.ChangeExtension(inputFile, InputMapFileExtension); var outputFile = PathUtils.ChangeExtension(inputFile, OutputFileExtension); var niceJsFile = PathUtils.ChangeExtension(inputFile, NiceJsFileExtension); var niceJsMapFile = PathUtils.ChangeExtension(inputFile, NiceJsMapFileExtension); var minJsFile = PathUtils.ChangeExtension(inputFile, MinJsFileExtension); var minJsMapFile = PathUtils.ChangeExtension(inputFile, MinJsMapFileExtension); var isInvalid = !File.Exists(niceJsFile) || !File.Exists(minJsFile); var testData = new ParserTestData { Name = PathUtils.WithoutExtension(inputFile), Input = File.ReadAllText(inputFile), SourceName = PathUtils.Name(inputFile), ExpectedAst = File.Exists(outputFile) ? File.ReadAllText(outputFile) : "", IsInvalid = isInvalid, EcmaScriptVersion = GetEcmaVersion(inputFile) }; if (File.Exists(inputMapFile)) { testData.InputSourceMap = File.ReadAllText(inputMapFile); } if (isInvalid) { return testData; } testData.ExpectedMinJs = File.ReadAllText(minJsFile); testData.ExpectedMinJsMap = File.ReadAllText(minJsMapFile); testData.ExpectedNiceJs = File.ReadAllText(niceJsFile); testData.ExpectedNiceJsMap = File.ReadAllText(niceJsMapFile); return testData; })); }
ParseTestCore( ParserTestData testData) { string outAst; var outMinJs = string.Empty; var outMinJsMap = string.Empty; var outNiceJs = string.Empty; var outNiceJsMap = string.Empty; try { var comments = new List <(bool block, string content, SourceLocation location)>(); var commentListener = new CommentListener(); var parser = new Parser( new() { SourceFile = testData.SourceName, EcmaVersion = testData.EcmaScriptVersion, OnComment = (block, content, location) => { commentListener.OnComment(block, content, location); comments.Add((block, content, location)); }, SourceType = testData.SourceName.StartsWith("module-") ? SourceType.Module : SourceType.Script }, testData.Input); var toplevel = parser.Parse(); commentListener.Walk(toplevel); SourceMap?inputSourceMap = null; if (testData.InputSourceMap != null) { inputSourceMap = SourceMap.Parse(testData.InputSourceMap, "."); inputSourceMap.ResolveInAst(toplevel); } var strSink = new StringLineSink(); toplevel.FigureOutScope(); var dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); foreach (var(block, content, location) in comments) { strSink.Print( $"{(block ? "Block" : "Line")} Comment ({location.Start.ToShortString()}-{location.End.ToShortString()}): {content}"); } outAst = strSink.ToString(); var outMinJsBuilder = new SourceMapBuilder(); var outputOptions = new OutputOptions { Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outMinJsBuilder, outputOptions); outMinJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "minjs.map")}"); if (inputSourceMap != null) { outMinJsBuilder.AttachSourcesContent(inputSourceMap); } outMinJs = outMinJsBuilder.Content(); outMinJsMap = outMinJsBuilder.Build(".", ".").ToString(); var outNiceJsBuilder = new SourceMapBuilder(); outputOptions = new() { Beautify = true, Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outNiceJsBuilder, outputOptions); outNiceJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "nicejs.map")}"); if (inputSourceMap != null) { outNiceJsBuilder.AttachSourcesContent(inputSourceMap); } outNiceJs = outNiceJsBuilder.Content(); outNiceJsMap = outNiceJsBuilder.Build(".", ".").ToString(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var beforeClone = strSink.ToString(); toplevel = toplevel.DeepClone(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var afterClone = strSink.ToString(); if (beforeClone != afterClone) { throw new Exception("Dump of clone is not identical"); } toplevel.Mangle(); } catch (SyntaxError e) { outAst = e.Message; } return(outAst, outMinJs, outMinJsMap, outNiceJs, outNiceJsMap); }