Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5af7e06

Browse files
authored
Merge pull requestmicrosoft#23972 from Microsoft/batchTestConfigurationsForBrowser
Batch enumerateFiles into a single web request
2 parents6f9dc2f +9b04dc3 commit5af7e06

File tree

10 files changed

+284
-82
lines changed

10 files changed

+284
-82
lines changed

‎src/harness/compilerRunner.ts

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ const enum CompilerTestType {
1212
Test262
1313
}
1414

15+
interfaceCompilerFileBasedTestextendsHarness.FileBasedTest{
16+
payload?:Harness.TestCaseParser.TestCaseContent;
17+
}
18+
1519
classCompilerBaselineRunnerextendsRunnerBase{
1620
privatebasePath="tests/cases";
1721
privatetestSuiteName:TestRunnerKind;
@@ -42,7 +46,8 @@ class CompilerBaselineRunner extends RunnerBase {
4246
}
4347

4448
publicenumerateTestFiles(){
45-
returnthis.enumerateFiles(this.basePath,/\.tsx?$/,{recursive:true});
49+
// see also: `enumerateTestFiles` in tests/webTestServer.ts
50+
returnthis.enumerateFiles(this.basePath,/\.tsx?$/,{recursive:true}).map(CompilerTest.getConfigurations);
4651
}
4752

4853
publicinitializeTests(){
@@ -52,24 +57,32 @@ class CompilerBaselineRunner extends RunnerBase {
5257
});
5358

5459
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
55-
constfiles=this.tests.length>0 ?this.tests :this.enumerateTestFiles();
56-
files.forEach(file=>{this.checkTestCodeOutput(vpath.normalizeSeparators(file));});
60+
constfiles=this.tests.length>0 ?this.tests :Harness.IO.enumerateTestFiles(this);
61+
files.forEach(test=>{
62+
constfile=typeoftest==="string" ?test :test.file;
63+
this.checkTestCodeOutput(vpath.normalizeSeparators(file),typeoftest==="string" ?CompilerTest.getConfigurations(test) :test);
64+
});
5765
});
5866
}
5967

60-
publiccheckTestCodeOutput(fileName:string){
61-
for(const{ name, payload}ofCompilerTest.getConfigurations(fileName)){
62-
describe(`${this.testSuiteName} tests for${fileName}${name ?` (${name})` :``}`,()=>{
63-
this.runSuite(fileName,payload);
68+
publiccheckTestCodeOutput(fileName:string,test?:CompilerFileBasedTest){
69+
if(test&&test.configurations){
70+
test.configurations.forEach(configuration=>{
71+
describe(`${this.testSuiteName} tests for${fileName}${configuration ?` (${Harness.getFileBasedTestConfigurationDescription(configuration)})` :``}`,()=>{
72+
this.runSuite(fileName,test,configuration);
73+
});
6474
});
6575
}
76+
describe(`${this.testSuiteName} tests for${fileName}}`,()=>{
77+
this.runSuite(fileName,test);
78+
});
6679
}
6780

68-
privaterunSuite(fileName:string,testCaseContent:Harness.TestCaseParser.TestCaseContent){
81+
privaterunSuite(fileName:string,test?:CompilerFileBasedTest,configuration?:Harness.FileBasedTestConfiguration){
6982
// Mocha holds onto the closure environment of the describe callback even after the test is done.
7083
// Everything declared here should be cleared out in the "after" callback.
7184
letcompilerTest:CompilerTest|undefined;
72-
before(()=>{compilerTest=newCompilerTest(fileName,testCaseContent);});
85+
before(()=>{compilerTest=newCompilerTest(fileName,test&&test.payload,configuration);});
7386
it(`Correct errors for${fileName}`,()=>{compilerTest.verifyDiagnostics();});
7487
it(`Correct module resolution tracing for${fileName}`,()=>{compilerTest.verifyModuleResolution();});
7588
it(`Correct sourcemap content for${fileName}`,()=>{compilerTest.verifySourceMapRecord();});
@@ -97,11 +110,6 @@ class CompilerBaselineRunner extends RunnerBase {
97110
}
98111
}
99112

100-
interfaceCompilerTestConfiguration{
101-
name:string;
102-
payload:Harness.TestCaseParser.TestCaseContent;
103-
}
104-
105113
classCompilerTest{
106114
privatefileName:string;
107115
privatejustName:string;
@@ -116,10 +124,20 @@ class CompilerTest {
116124
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
117125
privateotherFiles:Harness.Compiler.TestFile[];
118126

119-
constructor(fileName:string,testCaseContent:Harness.TestCaseParser.TestCaseContent){
127+
constructor(fileName:string,testCaseContent?:Harness.TestCaseParser.TestCaseContent,configurationOverrides?:Harness.TestCaseParser.CompilerSettings){
120128
this.fileName=fileName;
121129
this.justName=vpath.basename(fileName);
130+
122131
constrootDir=fileName.indexOf("conformance")===-1 ?"tests/cases/compiler/" :ts.getDirectoryPath(fileName)+"/";
132+
133+
if(testCaseContent===undefined){
134+
testCaseContent=Harness.TestCaseParser.makeUnitsFromTest(Harness.IO.readFile(fileName),fileName,rootDir);
135+
}
136+
137+
if(configurationOverrides){
138+
testCaseContent={ ...testCaseContent,settings:{ ...testCaseContent.settings, ...configurationOverrides}};
139+
}
140+
123141
constunits=testCaseContent.testUnitData;
124142
this.harnessSettings=testCaseContent.settings;
125143
lettsConfigOptions:ts.CompilerOptions;
@@ -174,32 +192,14 @@ class CompilerTest {
174192
this.options=this.result.options;
175193
}
176194

177-
publicstaticgetConfigurations(fileName:string){
178-
constcontent=Harness.IO.readFile(fileName);
179-
constrootDir=fileName.indexOf("conformance")===-1 ?"tests/cases/compiler/" :ts.getDirectoryPath(fileName)+"/";
180-
consttestCaseContent=Harness.TestCaseParser.makeUnitsFromTest(content,fileName,rootDir);
181-
constconfigurations:CompilerTestConfiguration[]=[];
182-
constscriptTargets=this._split(testCaseContent.settings.target);
183-
constmoduleKinds=this._split(testCaseContent.settings.module);
184-
for(constscriptTargetofscriptTargets){
185-
for(constmoduleKindofmoduleKinds){
186-
letname="";
187-
if(moduleKinds.length>1){
188-
name+=`@module:${moduleKind||"none"}`;
189-
}
190-
if(scriptTargets.length>1){
191-
if(name)name+=", ";
192-
name+=`@target:${scriptTarget||"none"}`;
193-
}
194-
195-
constsettings={ ...testCaseContent.settings};
196-
if(scriptTarget)settings.target=scriptTarget;
197-
if(moduleKind)settings.module=moduleKind;
198-
configurations.push({ name,payload:{ ...testCaseContent, settings}});
199-
}
200-
}
201-
202-
returnconfigurations;
195+
publicstaticgetConfigurations(file:string):CompilerFileBasedTest{
196+
// also see `parseCompilerTestConfigurations` in tests/webTestServer.ts
197+
constcontent=Harness.IO.readFile(file);
198+
constrootDir=file.indexOf("conformance")===-1 ?"tests/cases/compiler/" :ts.getDirectoryPath(file)+"/";
199+
constpayload=Harness.TestCaseParser.makeUnitsFromTest(content,file,rootDir);
200+
constsettings=Harness.TestCaseParser.extractCompilerSettings(content);
201+
constconfigurations=Harness.getFileBasedTestConfigurations(settings,/*varyBy*/["module","target"]);
202+
return{ file, payload, configurations};
203203
}
204204

205205
publicverifyDiagnostics(){
@@ -267,11 +267,6 @@ class CompilerTest {
267267
this.toBeCompiled.concat(this.otherFiles).filter(file=>!!this.result.program.getSourceFile(file.unitName)));
268268
}
269269

270-
privatestatic_split(text:string){
271-
constentries=text&&text.split(",").map(s=>s.toLowerCase().trim()).filter(s=>s.length>0);
272-
returnentries&&entries.length>0 ?entries :[""];
273-
}
274-
275270
privatemakeUnitName(name:string,root:string){
276271
constpath=ts.toPath(name,root,ts.identity);
277272
constpathStart=ts.toPath(Harness.IO.getCurrentDirectory(),"",ts.identity);

‎src/harness/externalCompileRunner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
2828

2929
describe(`${this.kind()} code samples`,()=>{
3030
for(consttestoftestList){
31-
this.runTest(test);
31+
this.runTest(typeoftest==="string" ?test :test.file);
3232
}
3333
});
3434
}

‎src/harness/fourslashRunner.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class FourSlashRunner extends RunnerBase {
3636
}
3737

3838
publicenumerateTestFiles(){
39+
// see also: `enumerateTestFiles` in tests/webTestServer.ts
3940
returnthis.enumerateFiles(this.basePath,/\.ts/i,{recursive:false});
4041
}
4142

@@ -45,22 +46,23 @@ class FourSlashRunner extends RunnerBase {
4546

4647
publicinitializeTests(){
4748
if(this.tests.length===0){
48-
this.tests=this.enumerateTestFiles();
49+
this.tests=Harness.IO.enumerateTestFiles(this);
4950
}
5051

5152
describe(this.testSuiteName+" tests",()=>{
52-
this.tests.forEach((fn:string)=>{
53-
describe(fn,()=>{
54-
fn=ts.normalizeSlashes(fn);
55-
constjustName=fn.replace(/^.*[\\\/]/,"");
53+
this.tests.forEach(test=>{
54+
constfile=typeoftest==="string" ?test :test.file;
55+
describe(file,()=>{
56+
letfn=ts.normalizeSlashes(file);
57+
constjustName=fn.replace(/^.*[\\\/]/,"");
5658

57-
// Convert to relative path
58-
consttestIndex=fn.indexOf("tests/");
59-
if(testIndex>=0)fn=fn.substr(testIndex);
59+
// Convert to relative path
60+
consttestIndex=fn.indexOf("tests/");
61+
if(testIndex>=0)fn=fn.substr(testIndex);
6062

61-
if(justName&&!justName.match(/fourslash\.ts$/i)&&!justName.match(/\.d\.ts$/i)){
62-
it(this.testSuiteName+" test "+justName+" runs correctly",()=>{
63-
FourSlash.runFourSlashTest(this.basePath,this.testType,fn);
63+
if(justName&&!justName.match(/fourslash\.ts$/i)&&!justName.match(/\.d\.ts$/i)){
64+
it(this.testSuiteName+" test "+justName+" runs correctly",()=>{
65+
FourSlash.runFourSlashTest(this.basePath,this.testType,fn);
6466
});
6567
}
6668
});

‎src/harness/harness.ts

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ namespace Harness {
514514
fileExists(fileName:string):boolean;
515515
directoryExists(path:string):boolean;
516516
deleteFile(fileName:string):void;
517+
enumerateTestFiles(runner:RunnerBase):(string|FileBasedTest)[];
517518
listFiles(path:string,filter?:RegExp,options?:{recursive?:boolean}):string[];
518519
log(text:string):void;
519520
args():string[];
@@ -559,6 +560,10 @@ namespace Harness {
559560
returndirPath===path ?undefined :dirPath;
560561
}
561562

563+
functionenumerateTestFiles(runner:RunnerBase){
564+
returnrunner.enumerateTestFiles();
565+
}
566+
562567
functionlistFiles(path:string,spec:RegExp,options?:{recursive?:boolean}){
563568
options=options||{};
564569

@@ -639,6 +644,7 @@ namespace Harness {
639644
directoryExists:path=>ts.sys.directoryExists(path),
640645
deleteFile,
641646
listFiles,
647+
enumerateTestFiles,
642648
log:s=>console.log(s),
643649
args:()=>ts.sys.args,
644650
getExecutingFilePath:()=>ts.sys.getExecutingFilePath(),
@@ -913,6 +919,11 @@ namespace Harness {
913919
returnts.getDirectoryPath(ts.normalizeSlashes(url.pathname||"/"));
914920
}
915921

922+
functionenumerateTestFiles(runner:RunnerBase):(string|FileBasedTest)[]{
923+
constresponse=send(HttpRequestMessage.post(newURL("/api/enumerateTestFiles",serverRoot),HttpContent.text(runner.kind())));
924+
returnhasJsonContent(response) ?JSON.parse(response.content.content) :[];
925+
}
926+
916927
functionlistFiles(dirname:string,spec?:RegExp,options?:{recursive?:boolean}):string[]{
917928
if(spec||(options&&!options.recursive)){
918929
letresults=IO.listFiles(dirname);
@@ -959,6 +970,7 @@ namespace Harness {
959970
directoryExists,
960971
deleteFile,
961972
listFiles:Utils.memoize(listFiles,(path,spec,options)=>`${path}|${spec}|${options ?options.recursive===true :true}`),
973+
enumerateTestFiles:Utils.memoize(enumerateTestFiles,runner=>runner.kind()),
962974
log:s=>console.log(s),
963975
args:()=>[],
964976
getExecutingFilePath:()=>"",
@@ -1761,6 +1773,74 @@ namespace Harness {
17611773
}
17621774
}
17631775

1776+
exportinterfaceFileBasedTest{
1777+
file:string;
1778+
configurations?:FileBasedTestConfiguration[];
1779+
}
1780+
1781+
exportinterfaceFileBasedTestConfiguration{
1782+
[key:string]:string;
1783+
}
1784+
1785+
functionsplitVaryBySettingValue(text:string):string[]|undefined{
1786+
if(!text)returnundefined;
1787+
constentries=text.split(/,/).map(s=>s.trim().toLowerCase()).filter(s=>s.length>0);
1788+
returnentries&&entries.length>1 ?entries :undefined;
1789+
}
1790+
1791+
functioncomputeFileBasedTestConfigurationVariations(configurations:FileBasedTestConfiguration[],variationState:FileBasedTestConfiguration,varyByEntries:[string,string[]][],offset:number){
1792+
if(offset>=varyByEntries.length){
1793+
// make a copy of the current variation state
1794+
configurations.push({ ...variationState});
1795+
return;
1796+
}
1797+
1798+
const[varyBy,entries]=varyByEntries[offset];
1799+
for(constentryofentries){
1800+
// set or overwrite the variation, then compute the next variation
1801+
variationState[varyBy]=entry;
1802+
computeFileBasedTestConfigurationVariations(configurations,variationState,varyByEntries,offset+1);
1803+
}
1804+
}
1805+
1806+
/**
1807+
* Compute FileBasedTestConfiguration variations based on a supplied list of variable settings.
1808+
*/
1809+
exportfunctiongetFileBasedTestConfigurations(settings:TestCaseParser.CompilerSettings,varyBy:string[]):FileBasedTestConfiguration[]|undefined{
1810+
letvaryByEntries:[string,string[]][]|undefined;
1811+
for(constvaryByKeyofvaryBy){
1812+
if(ts.hasProperty(settings,varyByKey)){
1813+
// we only consider variations when there are 2 or more variable entries.
1814+
constentries=splitVaryBySettingValue(settings[varyByKey]);
1815+
if(entries){
1816+
if(!varyByEntries)varyByEntries=[];
1817+
varyByEntries.push([varyByKey,entries]);
1818+
}
1819+
}
1820+
}
1821+
1822+
if(!varyByEntries)returnundefined;
1823+
1824+
constconfigurations:FileBasedTestConfiguration[]=[];
1825+
computeFileBasedTestConfigurationVariations(configurations,/*variationState*/{},varyByEntries,/*offset*/0);
1826+
returnconfigurations;
1827+
}
1828+
1829+
/**
1830+
* Compute a description for this configuration based on its entries
1831+
*/
1832+
exportfunctiongetFileBasedTestConfigurationDescription(configuration:FileBasedTestConfiguration){
1833+
letname="";
1834+
if(configuration){
1835+
constkeys=Object.keys(configuration).sort();
1836+
for(constkeyofkeys){
1837+
if(name)name+=", ";
1838+
name+=`@${key}:${configuration[key]}`;
1839+
}
1840+
}
1841+
returnname;
1842+
}
1843+
17641844
exportnamespaceTestCaseParser{
17651845
/** all the necessary information to set the right compiler settings */
17661846
exportinterfaceCompilerSettings{
@@ -1779,7 +1859,7 @@ namespace Harness {
17791859
// Regex for parsing options in the format "@Alpha: Value of any sort"
17801860
constoptionRegex=/^[\/]{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm;// multiple matches on multiple lines
17811861

1782-
functionextractCompilerSettings(content:string):CompilerSettings{
1862+
exportfunctionextractCompilerSettings(content:string):CompilerSettings{
17831863
constopts:CompilerSettings={};
17841864

17851865
letmatch:RegExpExecArray;
@@ -1800,9 +1880,7 @@ namespace Harness {
18001880
}
18011881

18021882
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
1803-
exportfunctionmakeUnitsFromTest(code:string,fileName:string,rootDir?:string):TestCaseContent{
1804-
constsettings=extractCompilerSettings(code);
1805-
1883+
exportfunctionmakeUnitsFromTest(code:string,fileName:string,rootDir?:string,settings=extractCompilerSettings(code)):TestCaseContent{
18061884
// List of all the subfiles we've parsed out
18071885
consttestUnitData:TestUnitData[]=[];
18081886

‎src/harness/parallel/host.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ namespace Harness.Parallel.Host {
8181
const{ statSync}:{statSync(path:string):{size:number};}=require("fs");
8282
constpath:{join:(...args:string[])=>string}=require("path");
8383
for(construnnerofrunners){
84-
for(constfileofrunner.enumerateTestFiles()){
84+
for(consttestofrunner.enumerateTestFiles()){
85+
constfile=typeoftest==="string" ?test :test.file;
8586
letsize:number;
8687
if(!perfData){
8788
try{

‎src/harness/projectsRunner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace project {
5151
describe("projects tests",()=>{
5252
consttests=this.tests.length===0 ?this.enumerateTestFiles() :this.tests;
5353
for(consttestoftests){
54-
this.runProjectTestCase(test);
54+
this.runProjectTestCase(typeoftest==="string" ?test :test.file);
5555
}
5656
});
5757
}

‎src/harness/runnerbase.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
/// <reference path="harness.ts" />
2-
3-
41
typeTestRunnerKind=CompilerTestKind|FourslashTestKind|"project"|"rwc"|"test262"|"user"|"dt";
52
typeCompilerTestKind="conformance"|"compiler";
63
typeFourslashTestKind="fourslash"|"fourslash-shims"|"fourslash-shims-pp"|"fourslash-server";
74

85
abstractclassRunnerBase{
96
// contains the tests to run
10-
publictests:string[]=[];
7+
publictests:(string|Harness.FileBasedTest)[]=[];
118

129
/** Add a source file to the runner's list of tests that need to be initialized with initializeTests */
1310
publicaddTest(fileName:string){
@@ -20,7 +17,7 @@ abstract class RunnerBase {
2017

2118
abstractkind():TestRunnerKind;
2219

23-
abstractenumerateTestFiles():string[];
20+
abstractenumerateTestFiles():(string|Harness.FileBasedTest)[];
2421

2522
/** The working directory where tests are found. Needed for batch testing where the input path will differ from the output path inside baselines */
2623
publicworkingDirectory="";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp