Fourslash is a specialized testing framework for validating TypeScript Language Service features such as code completions, navigation (go-to-definition, find-references), refactorings, diagnostics, and formatting. It uses a declarative markup syntax with special markers and directives embedded in test files to specify test scenarios and expected behavior.
Scope: This document covers the Fourslash test framework, its syntax, architecture, and how to write Fourslash tests. For information about baseline tests (compiler output validation), see Baseline Testing. For general test organization and execution, see Test Organization.
Fourslash tests are written in special .ts files located in tests/cases/fourslash/ that use a unique markup syntax. The name "Fourslash" comes from the four-slash comment marker (////) used to denote source code lines within test files. These tests simulate user interactions with the TypeScript Language Service in an editor environment.
Sources: tests/cases/fourslash/fourslash.ts1-50 src/harness/harnessLanguageService.ts1-100
Fourslash test files use special markup to define test scenarios. The core syntax elements are:
| Syntax Element | Purpose | Example |
|---|---|---|
//// | Denotes source code line | //// const x = 1; |
/*marker*/ | Named position marker | //// const /*start*/x/*end*/ = 1; |
| `[ | ... | ]` |
@Filename: path | Multi-file test directive | // @Filename: /a.ts |
goTo.*() | Navigation commands | goTo.marker("start") |
verify.*() | Assertion commands | verify.completions(...) |
Sources: tests/cases/fourslash/fourslash.ts1-200
Lines prefixed with four slashes (////) represent the actual TypeScript source code being tested:
Sources: tests/cases/fourslash/fourslash.ts3-7
Named Markers: /*markerName*/ creates a named position in the source:
Selection Markers: [|...|] defines a text span/selection:
Sources: tests/cases/fourslash/fourslash.ts50-100
The @Filename: directive creates multiple virtual files in a single test:
Sources: tests/cases/fourslash/fourslash.ts150-200
The Fourslash test harness infrastructure bridges the test markup syntax with the TypeScript Language Service implementation. It utilizes HarnessLanguageService to wrap the core LanguageService defined in src/services/services.ts.
Sources: src/harness/harnessLanguageService.ts1-500 src/services/services.ts212 src/harness/fourslashImpl.ts1-100
TestState: Defined in src/harness/fourslashImpl.ts, this is the central class managing test execution state, tracking markers, cursor position, and providing the goTo.*() and verify.*() API methods.
HarnessLanguageService: Found in src/harness/harnessLanguageService.ts, this class wraps the actual LanguageService implementation. It manages IScriptSnapshot objects and provides a testing interface for file updates.
Virtual File System: An in-memory file system implementation that allows tests to define multiple files and their contents using the @Filename: directive. This is supported by the LanguageServiceHost implementation within the harness.
Sources: src/harness/harnessLanguageService.ts1-100 src/harness/fourslashImpl.ts1-50 src/services/services.ts213
Fourslash tests cover a wide range of Language Service functionality:
Testing IntelliSense/auto-completion behavior using the logic in src/services/completions.ts:
Sources: src/services/completions.ts1-100 tests/cases/fourslash/fourslash.ts200-250
Testing go-to-definition and find-references using src/services/goToDefinition.ts and src/services/findAllReferences.ts:
Sources: src/services/findAllReferences.ts1-79 src/services/goToDefinition.ts1-127
Testing code refactoring operations implemented in the src/services/refactor directory:
Sources: src/services/services.ts268-271
Testing error and warning reporting from the TypeChecker in src/compiler/checker.ts:
Sources: src/compiler/checker.ts1-200 src/compiler/diagnosticMessages.json1-100
Sources: src/harness/harnessLanguageService.ts1-200
Parsing: The test file is parsed to extract source code lines (////), markers (/*name*/), spans ([|...|]), and directives (@Filename:, etc.)
File System Setup: Virtual files are created based on @Filename: directives, with content from subsequent //// lines.
Language Service Initialization: A HarnessLanguageService instance is created, wrapping the real LanguageService with the virtual file system.
Command Execution: Test commands (goTo.*(), edit.*()) are executed to simulate user actions like moving the cursor or editing text.
Verification: Assertion methods (verify.*()) check Language Service responses against expected values.
Result Reporting: Test passes if all assertions succeed, fails otherwise with diagnostic information.
Sources: src/harness/harnessLanguageService.ts100-300 src/harness/fourslashImpl.ts100-200
The verify.*() methods provide a rich assertion API for validating Language Service behavior:
| Method Category | Purpose | Example Methods |
|---|---|---|
| Completions | Validate completion lists | verify.completions(), verify.completionEntryDetailIs() |
| Navigation | Validate go-to features | verify.goToDefinition(), verify.goToType() |
| References | Validate find references | verify.referencesCountIs(), verify.rangesAreRenameLocations() |
| Refactorings | Validate refactoring availability | verify.refactorAvailable(), verify.applyRefactor() |
| Diagnostics | Validate errors/warnings | verify.diagnostics(), verify.noErrors() |
| Quick Info | Validate hover information | verify.quickInfoIs(), verify.quickInfoExists() |
| Signature Help | Validate parameter hints | verify.signatureHelp(), verify.currentSignatureHelpIs() |
Sources: tests/cases/fourslash/fourslash.ts250-500 src/harness/fourslashInterfaceImpl.ts1-100
Completion Verification:
Reference Verification:
Sources: tests/cases/fourslash/fourslash.ts300-400
A typical Fourslash test follows this pattern:
Sources: tests/cases/fourslash/fourslash.ts1-50
Sources: tests/cases/fourslash/fourslash.ts150-250
Sources: src/harness/harnessLanguageService.ts1-100 src/harness/fourslashImpl.ts1-100
The Fourslash framework integrates with the Mocha test runner through the test harness. The test loader discovers all .ts files in tests/cases/fourslash/, parses them to extract the test markup, creates the necessary virtual file system and Language Service instances, and executes the test commands and assertions.
| Advantage | Description |
|---|---|
| Declarative | Tests specify what to test, not how to set up the environment |
| Readable | Markup syntax makes test intent clear and easy to understand |
| Comprehensive | Single framework tests all Language Service features |
| Isolated | Virtual file system ensures tests don't depend on external files |
| Maintainable | Changes to Language Service behavior require minimal test updates |
| Fast | In-memory execution without disk I/O or external processes |
Sources: Based on Fourslash design and usage patterns in tests/cases/fourslash/
Refresh this wiki