mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-16 07:13:45 -05:00
Handles time on vfs and write non empty shadowed files in baseline even if they were not read (#48703)
* Use fixed time for vfs so baselining is consistent * Baseline buildinfos * Write new file text in baseline even if the file wasnt read on the shadow * Remove unnecessary debugger statement
This commit is contained in:
@@ -55,12 +55,12 @@ namespace vfs {
|
||||
} = {};
|
||||
|
||||
private _cwd: string; // current working directory
|
||||
private _time: number | Date | (() => number | Date);
|
||||
private _time: number;
|
||||
private _shadowRoot: FileSystem | undefined;
|
||||
private _dirStack: string[] | undefined;
|
||||
|
||||
constructor(ignoreCase: boolean, options: FileSystemOptions = {}) {
|
||||
const { time = -1, files, meta } = options;
|
||||
const { time = ts.TestFSWithWatch.timeIncrements, files, meta } = options;
|
||||
this.ignoreCase = ignoreCase;
|
||||
this.stringComparer = this.ignoreCase ? vpath.compareCaseInsensitive : vpath.compareCaseSensitive;
|
||||
this._time = time;
|
||||
@@ -167,16 +167,15 @@ namespace vfs {
|
||||
*
|
||||
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
|
||||
*/
|
||||
public time(value?: number | Date | (() => number | Date)): number {
|
||||
if (value !== undefined && this.isReadonly) throw createIOError("EPERM");
|
||||
let result = this._time;
|
||||
if (typeof result === "function") result = result();
|
||||
if (typeof result === "object") result = result.getTime();
|
||||
if (result === -1) result = Date.now();
|
||||
public time(value?: number): number {
|
||||
if (value !== undefined) {
|
||||
if (this.isReadonly) throw createIOError("EPERM");
|
||||
this._time = value;
|
||||
}
|
||||
return result;
|
||||
else if (!this.isReadonly) {
|
||||
this._time += ts.TestFSWithWatch.timeIncrements;
|
||||
}
|
||||
return this._time;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -843,7 +842,7 @@ namespace vfs {
|
||||
container[basename] = new Symlink(node.symlink);
|
||||
}
|
||||
else {
|
||||
container[basename] = new File(node.buffer || "");
|
||||
container[basename] = new File(changed._getBuffer(node));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1172,9 +1171,8 @@ namespace vfs {
|
||||
}
|
||||
|
||||
export interface FileSystemOptions {
|
||||
// Sets the initial timestamp for new files and directories, or the function used
|
||||
// to calculate timestamps.
|
||||
time?: number | Date | (() => number | Date);
|
||||
// Sets the initial timestamp for new files and directories
|
||||
time?: number;
|
||||
|
||||
// A set of file system entries to initially add to the file system.
|
||||
files?: FileSet;
|
||||
|
||||
@@ -360,7 +360,7 @@ interface Array<T> { length: number; [n: number]: T; }`
|
||||
DynamicPolling = "RecursiveDirectoryUsingDynamicPriorityPolling"
|
||||
}
|
||||
|
||||
const timeIncrements = 1000;
|
||||
export const timeIncrements = 1000;
|
||||
export interface TestServerHostOptions {
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
executingFilePath: string;
|
||||
|
||||
@@ -78,26 +78,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function getTime() {
|
||||
let currentTime = 100;
|
||||
return { tick, time, touch };
|
||||
|
||||
function tick() {
|
||||
currentTime += 60_000;
|
||||
}
|
||||
|
||||
function time() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
function touch(fs: vfs.FileSystem, path: string) {
|
||||
if (!fs.statSync(path).isFile()) {
|
||||
throw new Error(`File ${path} does not exist`);
|
||||
}
|
||||
fs.utimesSync(path, new Date(time()), new Date(time()));
|
||||
}
|
||||
}
|
||||
|
||||
export const libContent = `${TestFSWithWatch.libFile.content}
|
||||
interface ReadonlyArray<T> {}
|
||||
declare const console: { log(msg: any): void; };`;
|
||||
@@ -154,26 +134,6 @@ interface Symbol {
|
||||
fs.makeReadonly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FS mountuing existing fs's /src and /lib folder
|
||||
*/
|
||||
export function getFsWithTime(baseFs: vfs.FileSystem) {
|
||||
const { time, tick } = getTime();
|
||||
const host = new fakes.System(baseFs) as any as vfs.FileSystemResolverHost;
|
||||
host.getWorkspaceRoot = notImplemented;
|
||||
const resolver = vfs.createResolver(host);
|
||||
const fs = new vfs.FileSystem(/*ignoreCase*/ true, {
|
||||
files: {
|
||||
["/src"]: new vfs.Mount("/src", resolver),
|
||||
["/lib"]: new vfs.Mount("/lib", resolver)
|
||||
},
|
||||
cwd: "/",
|
||||
meta: { defaultLibLocation: "/lib" },
|
||||
time
|
||||
});
|
||||
return { fs, time, tick };
|
||||
}
|
||||
|
||||
export function verifyOutputsPresent(fs: vfs.FileSystem, outputs: readonly string[]) {
|
||||
for (const output of outputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
@@ -336,7 +296,6 @@ interface Symbol {
|
||||
commandLineArgs: TestTscCompile["commandLineArgs"];
|
||||
modifyFs: TestTscCompile["modifyFs"];
|
||||
editFs: TestTscEdit["modifyFs"];
|
||||
tick: () => void;
|
||||
baseFs: vfs.FileSystem;
|
||||
newSys: TscCompileSystem;
|
||||
cleanBuildDiscrepancies: TestTscEdit["cleanBuildDiscrepancies"];
|
||||
@@ -347,7 +306,7 @@ interface Symbol {
|
||||
const {
|
||||
scenario, commandLineArgs, cleanBuildDiscrepancies,
|
||||
modifyFs, editFs,
|
||||
tick, baseFs, newSys
|
||||
baseFs, newSys
|
||||
} = input();
|
||||
const sys = testTscCompile({
|
||||
scenario,
|
||||
@@ -355,7 +314,6 @@ interface Symbol {
|
||||
fs: () => baseFs.makeReadonly(),
|
||||
commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
tick();
|
||||
if (modifyFs) modifyFs(fs);
|
||||
editFs(fs);
|
||||
},
|
||||
@@ -532,22 +490,18 @@ interface Symbol {
|
||||
edits
|
||||
}: VerifyTscWithEditsWorkerInput) {
|
||||
describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario} serializedEdits`, () => {
|
||||
let tick: () => void;
|
||||
let sys: TscCompileSystem;
|
||||
let baseFs: vfs.FileSystem;
|
||||
let editsSys: TscCompileSystem[];
|
||||
before(() => {
|
||||
Debug.assert(!!edits.length, `${scenario}/${subScenario}:: No incremental scenarios, you probably want to use verifyTsc instead.`);
|
||||
({ fs: baseFs, tick } = getFsWithTime(fs()));
|
||||
baseFs = fs().makeReadonly();
|
||||
sys = testTscCompile({
|
||||
scenario,
|
||||
subScenario,
|
||||
fs: () => baseFs.makeReadonly(),
|
||||
fs: () => baseFs,
|
||||
commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
if (modifyFs) modifyFs(fs);
|
||||
tick();
|
||||
},
|
||||
modifyFs,
|
||||
baselineSourceMap,
|
||||
baselineReadFileCalls,
|
||||
baselinePrograms
|
||||
@@ -556,18 +510,13 @@ interface Symbol {
|
||||
{ modifyFs, subScenario: editScenario, commandLineArgs: editCommandLineArgs },
|
||||
index
|
||||
) => {
|
||||
tick();
|
||||
(editsSys || (editsSys = [])).push(testTscCompile({
|
||||
scenario,
|
||||
subScenario: editScenario || subScenario,
|
||||
diffWithInitial: true,
|
||||
fs: () => index === 0 ? sys.vfs : editsSys[index - 1].vfs,
|
||||
commandLineArgs: editCommandLineArgs || commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
tick();
|
||||
modifyFs(fs);
|
||||
tick();
|
||||
},
|
||||
modifyFs,
|
||||
baselineSourceMap,
|
||||
baselineReadFileCalls,
|
||||
baselinePrograms
|
||||
@@ -577,7 +526,6 @@ interface Symbol {
|
||||
after(() => {
|
||||
baseFs = undefined!;
|
||||
sys = undefined!;
|
||||
tick = undefined!;
|
||||
editsSys = undefined!;
|
||||
});
|
||||
describe("tsc invocation after edit", () => {
|
||||
@@ -608,7 +556,6 @@ interface Symbol {
|
||||
}
|
||||
},
|
||||
modifyFs,
|
||||
tick
|
||||
}), index, subScenario));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,10 +10,6 @@ namespace ts {
|
||||
outFileWithBuildFs = undefined!;
|
||||
});
|
||||
|
||||
function createSolutionBuilder(host: fakes.SolutionBuilderHost, baseOptions?: BuildOptions) {
|
||||
return ts.createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true, ...(baseOptions || {}) });
|
||||
}
|
||||
|
||||
interface VerifyOutFileScenarioInput {
|
||||
subScenario: string;
|
||||
modifyFs?: (fs: vfs.FileSystem) => void;
|
||||
@@ -108,8 +104,9 @@ namespace ts {
|
||||
function getOutFileFsAfterBuild() {
|
||||
if (outFileWithBuildFs) return outFileWithBuildFs;
|
||||
const fs = outFileFs.shadow();
|
||||
const host = fakes.SolutionBuilderHost.create(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" });
|
||||
const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem);
|
||||
const builder = createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true });
|
||||
builder.build();
|
||||
fs.makeReadonly();
|
||||
return outFileWithBuildFs = fs;
|
||||
@@ -147,7 +144,7 @@ namespace ts {
|
||||
compile: sys => {
|
||||
// Buildinfo will have version which does not match with current ts version
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion");
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third"], { verbose: true });
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third"], { verbose: true });
|
||||
sys.exit(builder.build());
|
||||
}
|
||||
});
|
||||
@@ -181,7 +178,7 @@ namespace ts {
|
||||
commandLineArgs: ["--build", "/src/second/tsconfig.json"],
|
||||
compile: sys => {
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys);
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {});
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {});
|
||||
sys.exit(builder.build("/src/second/tsconfig.json"));
|
||||
}
|
||||
});
|
||||
@@ -193,7 +190,7 @@ namespace ts {
|
||||
commandLineArgs: ["--build", "--clean", "/src/second/tsconfig.json"],
|
||||
compile: sys => {
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys);
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true });
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true });
|
||||
sys.exit(builder.clean("/src/second/tsconfig.json"));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace ts {
|
||||
describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => {
|
||||
let sys: TscCompileSystem;
|
||||
before(() => {
|
||||
const initialFs = getFsWithTime(loadProjectFromFiles({
|
||||
const inputFs = loadProjectFromFiles({
|
||||
"/src/tsconfig.json": JSON.stringify({
|
||||
references: [
|
||||
{ path: "./shared/tsconfig.json" },
|
||||
@@ -29,9 +29,7 @@ export class c2 { }
|
||||
export enum e2 { }
|
||||
// leading
|
||||
export function f22() { } // trailing`,
|
||||
})).fs.makeReadonly();
|
||||
const inputFs = initialFs.shadow();
|
||||
inputFs.makeReadonly();
|
||||
}).makeReadonly();
|
||||
const fs = inputFs.shadow();
|
||||
|
||||
// Create system
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace ts {
|
||||
function getSampleFsAfterBuild() {
|
||||
if (projFsWithBuild) return projFsWithBuild;
|
||||
const fs = projFs.shadow();
|
||||
const host = fakes.SolutionBuilderHost.create(fs);
|
||||
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" });
|
||||
const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.build();
|
||||
fs.makeReadonly();
|
||||
|
||||
@@ -214,7 +214,7 @@ ${patch ? vfs.formatPatch(patch) : ""}`
|
||||
describe(input.subScenario, () => {
|
||||
verifyTscBaseline(() => verifier({
|
||||
...input,
|
||||
fs: () => getFsWithTime(input.fs()).fs.makeReadonly()
|
||||
fs: () => input.fs().makeReadonly()
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user