Skip to content

Handles time on vfs and write non empty shadowed files in baseline even if they were not read #48703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions src/harness/vfsUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/harness/virtualFileSystemWithWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
63 changes: 5 additions & 58 deletions src/testRunner/unittests/tsbuild/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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; };`;
Expand Down Expand Up @@ -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`);
Expand Down Expand Up @@ -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"];
Expand All @@ -347,15 +306,14 @@ interface Symbol {
const {
scenario, commandLineArgs, cleanBuildDiscrepancies,
modifyFs, editFs,
tick, baseFs, newSys
baseFs, newSys
} = input();
const sys = testTscCompile({
scenario,
subScenario,
fs: () => baseFs.makeReadonly(),
commandLineArgs,
modifyFs: fs => {
tick();
if (modifyFs) modifyFs(fs);
editFs(fs);
},
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -577,7 +526,6 @@ interface Symbol {
after(() => {
baseFs = undefined!;
sys = undefined!;
tick = undefined!;
editsSys = undefined!;
});
describe("tsc invocation after edit", () => {
Expand Down Expand Up @@ -608,7 +556,6 @@ interface Symbol {
}
},
modifyFs,
tick
}), index, subScenario));
});
});
Expand Down
15 changes: 6 additions & 9 deletions src/testRunner/unittests/tsbuild/outFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}
});
Expand Down Expand Up @@ -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"));
}
});
Expand All @@ -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"));
}
});
Expand Down
6 changes: 2 additions & 4 deletions src/testRunner/unittests/tsbuild/publicApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/testRunner/unittests/tsbuild/sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsc/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ ${patch ? vfs.formatPatch(patch) : ""}`
describe(input.subScenario, () => {
verifyTscBaseline(() => verifier({
...input,
fs: () => getFsWithTime(input.fs()).fs.makeReadonly()
fs: () => input.fs().makeReadonly()
}));
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ const globalConst = 10;

Output::
/lib/tsc --b /src/app --verbose
[12:01:00 AM] Projects in this build:
[12:00:06 AM] Projects in this build:
* src/lib/tsconfig.json
* src/app/tsconfig.json

[12:01:00 AM] Project 'src/lib/tsconfig.json' is out of date because output file 'src/lib/module.js' does not exist
[12:00:07 AM] Project 'src/lib/tsconfig.json' is out of date because output file 'src/lib/module.js' does not exist

[12:01:00 AM] Building project '/src/lib/tsconfig.json'...
[12:00:08 AM] Building project '/src/lib/tsconfig.json'...

[12:01:00 AM] Project 'src/app/tsconfig.json' is out of date because output file 'src/app/module.js' does not exist
[12:00:16 AM] Project 'src/app/tsconfig.json' is out of date because output file 'src/app/module.js' does not exist

[12:01:00 AM] Building project '/src/app/tsconfig.json'...
[12:00:17 AM] Building project '/src/app/tsconfig.json'...

exitCode:: ExitStatus.Success

Expand Down Expand Up @@ -936,19 +936,19 @@ export const x = 10;console.log(x);

Output::
/lib/tsc --b /src/app --verbose
[12:04:00 AM] Projects in this build:
[12:00:30 AM] Projects in this build:
* src/lib/tsconfig.json
* src/app/tsconfig.json

[12:04:00 AM] Project 'src/lib/tsconfig.json' is out of date because oldest output 'src/lib/module.js' is older than newest input 'src/lib/file1.ts'
[12:00:31 AM] Project 'src/lib/tsconfig.json' is out of date because oldest output 'src/lib/module.js' is older than newest input 'src/lib/file1.ts'

[12:04:00 AM] Building project '/src/lib/tsconfig.json'...
[12:00:32 AM] Building project '/src/lib/tsconfig.json'...

[12:04:00 AM] Project 'src/app/tsconfig.json' is out of date because output of its dependency 'src/lib' has changed
[12:00:40 AM] Project 'src/app/tsconfig.json' is out of date because output of its dependency 'src/lib' has changed

[12:04:00 AM] Updating output of project '/src/app/tsconfig.json'...
[12:00:41 AM] Updating output of project '/src/app/tsconfig.json'...

[12:04:00 AM] Updating unchanged output timestamps of project '/src/app/tsconfig.json'...
[12:00:46 AM] Updating unchanged output timestamps of project '/src/app/tsconfig.json'...

exitCode:: ExitStatus.Success

Expand Down
Loading