-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Update harness to use single robust virtual file system for tests. #20763
Conversation
Can we do a one-time hack to make the 1,400ish baseline diffs go away, then do a separate PR to un-hack that so we can be sure no baselines are changing unexpectedly due to the VFS? |
@@ -200,7 +196,7 @@ function handleTestConfig() { | |||
|
|||
// TODO: project tests don"t work in the browser yet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still the case? Both the projects runner and browser IO impl got major overhauls.
src/harness/harness.ts
Outdated
programFileNames, | ||
options); | ||
|
||
// const fileOutputs = compilation.outputs.map(output => output.asGeneratedFile()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the commented-out code here required in some way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not anymore, I'll remove it.
src/harness/compiler.ts
Outdated
@@ -0,0 +1,256 @@ | |||
/// <reference path="./harness.ts" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are removing all triple-slash references currently in favor of tsconfig.josn file list
src/harness/core/comparers.ts
Outdated
return a < b ? -1 : +1; | ||
} | ||
|
||
export function compareStrings(a: string, b: string, ignoreCase: boolean): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how are these diffrent from the ones in src\compiler\core?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They aren't. Originally I intended to attempt to divorce the harness from the compiler to improve time-to-test by reducing compilation time, but with @RyanCavanaugh's forthcoming changes for project references this is no longer an issue. I am in the process of switching over to using existing functions, which should show up in the next few commits.
src/harness/core/functions.ts
Outdated
@@ -0,0 +1,3 @@ | |||
namespace core { | |||
export function identity<T>(v: T): T { return v; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we have this in core already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Planning to remove. See #20763 (comment) for more information.
src/harness/core/strings.ts
Outdated
break; | ||
|
||
// WhiteSpace | ||
case 0x0009: // <TAB> tab |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isWhiteSpaceSingleLine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function will be removed. See #20763 (comment) for more information.
src/harness/core/strings.ts
Outdated
return lines; | ||
} | ||
|
||
export function computeLineStarts(text: string): LineStarts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should already have this in scanner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Planning to remove. See #20763 (comment) for more information.
src/harness/core.ts
Outdated
@@ -0,0 +1,4 @@ | |||
/// <reference path="./core/functions.ts" /> | |||
/// <reference path="./core/comparers.ts" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would put these in tsconfig.json instead.
src/harness/vpath.ts
Outdated
/** | ||
* Combines two or more paths. If a path is absolute, it replaces any previous path. | ||
*/ | ||
export function combine(path: string, ...paths: string[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
many of the helpers here have counterparts in core, can we reuse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, where possible. I like the logical grouping of path-related functionality in the vpath
namespace (along with the more concise naming), and wonder if it would make sense to similarly consolidate related functionality in the compiler to reduce the volume of functions that show up in completions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is fine, but as we chatted offline, i think this restructuring should be done in the core, and not in the tests, and not by introducing a set of duplicate implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed most of the strict duplications already. What remains are places where the implementations are divergent. When you say "core", are you speaking of a new src/core
folder for those shared dependencies or refactoring existing functions in src/compiler/core.ts
to support the needs of both compiler and harness? I haven't made this change yet as I didn't want to bloat compiler with harness-specific functionality unnecessarily.
src/harness/core/collections.ts
Outdated
} | ||
} | ||
|
||
export class SortedSet<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am not seeing this used anywhere.. is it needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was originally used as part of the file watcher functionality.
@mhegazy, can you take another look? |
private readonly _executingFilePath: string | undefined; | ||
private readonly _env: Record<string, string> | undefined; | ||
|
||
constructor(vfs: vfs.FileSystem, { executingFilePath, newLine = "\r\n", env }: SystemOptions = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you have this another layer? Why not make vfs.FileSystem implement ts.System ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather keep them separate so that FileSystem
is purely a file system abstraction. Breaking things down into multiple components is more maintainable and better delineates functionality. We already have too many monolithic dependencies in the compiler, and we don't always need a full System
implementation (which is why we have so many independent *Host
types).
* A fake `ts.CompilerHost` that leverages a virtual file system. | ||
*/ | ||
export class CompilerHost implements ts.CompilerHost { | ||
public readonly sys: System; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this one.. Seems like this should just use createCompilerHost API on system instead of having another abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except we need to customize the compiler host for certain operations:
- Handling lib resolution in getDefaultLibFileName
- SourceFile caching for test performance in getSourceFile
- Keep track of outputs in writeFile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, it'd be nice if fakes.CompilerHost
could inherit from fakes.System
except they differ in their definitions of useCaseSensitiveFileNames
.
I have a few more changes pending, as I've almost finished unifying the path logic between |
@mhegazy can you take one more look after the last set of changes. I've cleaned up our path handling logic and was able to unify most of the path handling features in |
To better support the lib reference PR (#15780) and the ES3 lib PR (#16077) we needed to make a number of changes to our test harness to improve and consolidate our various approaches to emulating a file system. To that end, this PR introduces a much more robust virtual file system implementation that supports additional features needed by our various test runners including:
File/Directory watchingAs of this PR, the Compiler/Conformance, Project, and FourSlash runners all now use the VFS.
In addition all existing unit tests that used "virtualFileSystemWithWatch" have been migrated over to the single VFS implementation.