Skip to content

Commit 66ec938

Browse files
Merge pull request #20429 from Microsoft/unchai
Remove dependency on chai
2 parents 37a4056 + 2c92901 commit 66ec938

33 files changed

+647
-575
lines changed

Diff for: Jakefile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ compileFile(
795795
/*prereqs*/[builtLocalDirectory, tscFile, tsserverLibraryFile].concat(libraryTargets).concat(servicesSources).concat(harnessSources),
796796
/*prefixes*/[],
797797
/*useBuiltCompiler:*/ true,
798-
/*opts*/ { types: ["node", "mocha", "chai"], lib: "es6" });
798+
/*opts*/ { types: ["node", "mocha"], lib: "es6" });
799799

800800
var internalTests = "internal/";
801801

Diff for: package-lock.json

+299-264
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
},
3131
"devDependencies": {
3232
"@types/browserify": "latest",
33-
"@types/chai": "latest",
3433
"@types/colors": "latest",
3534
"@types/convert-source-map": "latest",
3635
"@types/del": "latest",
@@ -53,7 +52,6 @@
5352
"xml2js": "^0.4.19",
5453
"browser-resolve": "^1.11.2",
5554
"browserify": "latest",
56-
"chai": "latest",
5755
"convert-source-map": "latest",
5856
"del": "latest",
5957
"gulp": "3.X",

Diff for: src/harness/fourslash.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ namespace FourSlash {
295295
const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles);
296296

297297
const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName));
298-
assert.isTrue(configJsonObj.config !== undefined);
298+
assert(configJsonObj.config !== undefined);
299299

300300
const { options, errors } = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir);
301301

@@ -437,7 +437,7 @@ namespace FourSlash {
437437

438438
public goToEachMarker(action: () => void) {
439439
const markers = this.getMarkers();
440-
assert(markers.length);
440+
assert(markers.length !== 0);
441441
for (const marker of markers) {
442442
this.goToMarker(marker);
443443
action();
@@ -446,7 +446,7 @@ namespace FourSlash {
446446

447447
public goToEachRange(action: () => void) {
448448
const ranges = this.getRanges();
449-
assert(ranges.length);
449+
assert(ranges.length !== 0);
450450
for (const range of ranges) {
451451
this.goToRangeStart(range);
452452
action();
@@ -793,7 +793,7 @@ namespace FourSlash {
793793
}
794794

795795
const entries = this.getCompletionListAtCaret().entries;
796-
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
796+
assert(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
797797
ts.zipWith(entries, items, (entry, item) => {
798798
assert.equal(entry.name, item, `Unexpected item in completion list`);
799799
});
@@ -947,7 +947,7 @@ namespace FourSlash {
947947
public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
948948
const details = this.getCompletionEntryDetails(entryName);
949949

950-
assert(details, "no completion entry available");
950+
assert.isDefined(details, "no completion entry available");
951951

952952
assert.equal(ts.displayPartsToString(details.displayParts), expectedText, this.assertionMessageAtLastKnownMarker("completion entry details text"));
953953

@@ -1082,7 +1082,7 @@ namespace FourSlash {
10821082

10831083
public verifyRangesReferenceEachOther(ranges?: Range[]) {
10841084
ranges = ranges || this.getRanges();
1085-
assert(ranges.length);
1085+
assert(ranges.length !== 0);
10861086
for (const range of ranges) {
10871087
this.verifyReferencesOf(range, ranges);
10881088
}
@@ -1368,7 +1368,6 @@ Actual: ${stringify(fullActual)}`);
13681368

13691369
public verifyCurrentParameterIsVariable(isVariable: boolean) {
13701370
const signature = this.getActiveSignatureHelpItem();
1371-
assert.isOk(signature);
13721371
assert.equal(isVariable, signature.isVariadic);
13731372
}
13741373

@@ -2019,7 +2018,7 @@ Actual: ${stringify(fullActual)}`);
20192018
const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition);
20202019

20212020
if (negative) {
2022-
assert.isTrue(implementations && implementations.length > 0, "Expected at least one implementation but got 0");
2021+
assert(implementations && implementations.length > 0, "Expected at least one implementation but got 0");
20232022
}
20242023
else {
20252024
assert.isUndefined(implementations, "Expected implementation list to be empty but implementations returned");
@@ -3110,7 +3109,7 @@ Actual: ${stringify(fullActual)}`);
31103109

31113110
if (spanIndex !== undefined) {
31123111
const span = this.getTextSpanForRangeAtIndex(spanIndex);
3113-
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
3112+
assert(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
31143113
}
31153114

31163115
assert.equal(item.hasAction, hasAction);

Diff for: src/harness/harness.ts

+58-16
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,60 @@
2323
/// <reference path="virtualFileSystem.ts" />
2424
/// <reference types="node" />
2525
/// <reference types="mocha" />
26-
/// <reference types="chai" />
27-
2826

2927
// Block scoped definitions work poorly for global variables, temporarily enable var
3028
/* tslint:disable:no-var-keyword */
3129

32-
// this will work in the browser via browserify
33-
var _chai: typeof chai = require("chai");
34-
var assert: typeof _chai.assert = _chai.assert;
35-
// chai's builtin `assert.isFalse` is featureful but slow - we don't use those features,
36-
// so we'll just overwrite it as an alterative to migrating a bunch of code off of chai
37-
assert.isFalse = (expr, msg) => { if (expr as any as boolean !== false) throw new Error(msg); };
30+
function assert(expr: boolean, msg?: string | (() => string)): void {
31+
if (!expr) {
32+
throw new Error(typeof msg === "string" ? msg : msg());
33+
}
34+
}
35+
namespace assert {
36+
export function isFalse(expr: boolean, msg = "Expected value to be false."): void {
37+
assert(!expr, msg);
38+
}
39+
export function equal<T>(a: T, b: T, msg = "Expected values to be equal."): void {
40+
assert(a === b, msg);
41+
}
42+
export function notEqual<T>(a: T, b: T, msg = "Expected values to not be equal."): void {
43+
assert(a !== b, msg);
44+
}
45+
export function isDefined(x: {} | null | undefined, msg = "Expected value to be defined."): void {
46+
assert(x !== undefined && x !== null, msg);
47+
}
48+
export function isUndefined(x: {} | null | undefined, msg = "Expected value to be undefined."): void {
49+
assert(x === undefined, msg);
50+
}
51+
export function deepEqual<T>(a: T, b: T, msg?: string): void {
52+
assert(isDeepEqual(a, b), msg || (() => `Expected values to be deeply equal:\nExpected:\n${JSON.stringify(a, undefined, 4)}\nActual:\n${JSON.stringify(b, undefined, 4)}`));
53+
}
54+
export function lengthOf(a: ReadonlyArray<{}>, length: number, msg = "Expected length to match."): void {
55+
assert(a.length === length, msg);
56+
}
57+
export function throws(cb: () => void, msg = "Expected callback to throw"): void {
58+
let threw = false;
59+
try {
60+
cb();
61+
}
62+
catch {
63+
threw = true;
64+
}
65+
assert(threw, msg);
66+
}
67+
68+
function isDeepEqual<T>(a: T, b: T): boolean {
69+
if (a === b) {
70+
return true;
71+
}
72+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
73+
return false;
74+
}
75+
const aKeys = Object.keys(a).sort();
76+
const bKeys = Object.keys(b).sort();
77+
return aKeys.length === bKeys.length && aKeys.every((key, i) => bKeys[i] === key && isDeepEqual((a as any)[key], (b as any)[key]));
78+
}
79+
}
3880
declare var __dirname: string; // Node-specific
3981
var global: NodeJS.Global = <any>Function("return this").call(undefined);
4082

@@ -347,8 +389,8 @@ namespace Utils {
347389
return;
348390
}
349391

350-
assert(array1, "array1");
351-
assert(array2, "array2");
392+
assert(!!array1, "array1");
393+
assert(!!array2, "array2");
352394

353395
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
354396

@@ -371,8 +413,8 @@ namespace Utils {
371413
return;
372414
}
373415

374-
assert(node1, "node1");
375-
assert(node2, "node2");
416+
assert(!!node1, "node1");
417+
assert(!!node2, "node2");
376418
assert.equal(node1.pos, node2.pos, "node1.pos !== node2.pos");
377419
assert.equal(node1.end, node2.end, "node1.end !== node2.end");
378420
assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind");
@@ -402,8 +444,8 @@ namespace Utils {
402444
return;
403445
}
404446

405-
assert(array1, "array1");
406-
assert(array2, "array2");
447+
assert(!!array1, "array1");
448+
assert(!!array2, "array2");
407449
assert.equal(array1.pos, array2.pos, "array1.pos !== array2.pos");
408450
assert.equal(array1.end, array2.end, "array1.end !== array2.end");
409451
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
@@ -1259,7 +1301,7 @@ namespace Harness {
12591301

12601302
function findResultCodeFile(fileName: string) {
12611303
const sourceFile = result.program.getSourceFile(fileName);
1262-
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
1304+
assert.isDefined(sourceFile, "Program has no source file with name '" + fileName + "'");
12631305
// Is this file going to be emitted separately
12641306
let sourceFileName: string;
12651307
const outFile = options.outFile || options.out;
@@ -1942,7 +1984,7 @@ namespace Harness {
19421984
const data = testUnitData[i];
19431985
if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") {
19441986
const configJson = ts.parseJsonText(data.name, data.content);
1945-
assert.isTrue(configJson.endOfFileToken !== undefined);
1987+
assert(configJson.endOfFileToken !== undefined);
19461988
let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name));
19471989
if (rootDir) {
19481990
baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir);

Diff for: src/harness/harnessLanguageService.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,7 @@ namespace Harness.LanguageService {
174174
*/
175175
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
176176
const script: ScriptInfo = this.getScriptInfo(fileName);
177-
assert.isOk(script);
178-
177+
assert(!!script);
179178
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
180179
}
181180
}
@@ -360,7 +359,7 @@ namespace Harness.LanguageService {
360359
classification: parseInt(result[i + 1])
361360
};
362361

363-
assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length);
362+
assert(t.length > 0, "Result length should be greater than 0, got :" + t.length);
364363
position += t.length;
365364
}
366365
const finalLexState = parseInt(result[result.length - 1]);

Diff for: src/harness/sourceMapRecorder.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,10 @@ namespace Harness.SourceMapRecorder {
285285
}
286286

287287
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
288-
assert.isTrue(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
288+
assert(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
289289
recordSourceMapSpan(sourceMapSpan);
290290

291-
assert.isTrue(spansOnSingleLine.length === 1);
291+
assert(spansOnSingleLine.length === 1);
292292
sourceMapRecorder.WriteLine("-------------------------------------------------------------------");
293293
sourceMapRecorder.WriteLine("emittedFile:" + jsFile.fileName);
294294
sourceMapRecorder.WriteLine("sourceFile:" + sourceMapSources[spansOnSingleLine[0].sourceMapSpan.sourceIndex]);
@@ -331,7 +331,7 @@ namespace Harness.SourceMapRecorder {
331331
function getMarkerId(markerIndex: number) {
332332
let markerId = "";
333333
if (spanMarkerContinues) {
334-
assert.isTrue(markerIndex === 0);
334+
assert(markerIndex === 0);
335335
markerId = "1->";
336336
}
337337
else {

Diff for: src/harness/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"outFile": "../../built/local/run.js",
66
"declaration": false,
77
"types": [
8-
"node", "mocha", "chai"
8+
"node", "mocha"
99
],
1010
"lib": [
1111
"es6",

Diff for: src/harness/unittests/commandLineParsing.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ts {
1212

1313
const parsedErrors = parsed.errors;
1414
const expectedErrors = expectedParsedCommandLine.errors;
15-
assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
15+
assert(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
1616
for (let i = 0; i < parsedErrors.length; i++) {
1717
const parsedError = parsedErrors[i];
1818
const expectedError = expectedErrors[i];
@@ -23,7 +23,7 @@ namespace ts {
2323

2424
const parsedFileNames = parsed.fileNames;
2525
const expectedFileNames = expectedParsedCommandLine.fileNames;
26-
assert.isTrue(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
26+
assert(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
2727
for (let i = 0; i < parsedFileNames.length; i++) {
2828
const parsedFileName = parsedFileNames[i];
2929
const expectedFileName = expectedFileNames[i];

Diff for: src/harness/unittests/compileOnSave.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace ts.projectSystem {
2525

2626
const actualResultSingleProjectFileNameList = actualResultSingleProject.fileNames.sort();
2727
const expectedResultSingleProjectFileNameList = map(expectedResultSingleProject.files, f => f.path).sort();
28-
assert.isTrue(
28+
assert(
2929
arrayIsEqualTo(actualResultSingleProjectFileNameList, expectedResultSingleProjectFileNameList),
3030
`For project ${actualResultSingleProject.projectFileName}, the actual result is ${actualResultSingleProjectFileNameList}, while expected ${expectedResultSingleProjectFileNameList}`);
3131
}
@@ -563,7 +563,7 @@ namespace ts.projectSystem {
563563
session.executeCommand(compileFileRequest);
564564

565565
const expectedEmittedFileName = "/a/b/f1.js";
566-
assert.isTrue(host.fileExists(expectedEmittedFileName));
566+
assert(host.fileExists(expectedEmittedFileName));
567567
assert.equal(host.readFile(expectedEmittedFileName), `"use strict";\r\nexports.__esModule = true;\r\nfunction Foo() { return 10; }\r\nexports.Foo = Foo;\r\n`);
568568
});
569569

@@ -600,11 +600,11 @@ namespace ts.projectSystem {
600600
session.executeCommand(emitRequest);
601601

602602
const expectedOutFileName = "/a/b/dist.js";
603-
assert.isTrue(host.fileExists(expectedOutFileName));
603+
assert(host.fileExists(expectedOutFileName));
604604
const outFileContent = host.readFile(expectedOutFileName);
605-
assert.isTrue(outFileContent.indexOf(file1.content) !== -1);
606-
assert.isTrue(outFileContent.indexOf(file2.content) === -1);
607-
assert.isTrue(outFileContent.indexOf(file3.content) === -1);
605+
assert(outFileContent.indexOf(file1.content) !== -1);
606+
assert(outFileContent.indexOf(file2.content) === -1);
607+
assert(outFileContent.indexOf(file3.content) === -1);
608608
});
609609

610610
it("should use project root as current directory so that compile on save results in correct file mapping", () => {
@@ -634,19 +634,19 @@ namespace ts.projectSystem {
634634

635635
// Verify js file
636636
const expectedOutFileName = "/root/TypeScriptProject3/TypeScriptProject3/" + outFileName;
637-
assert.isTrue(host.fileExists(expectedOutFileName));
637+
assert(host.fileExists(expectedOutFileName));
638638
const outFileContent = host.readFile(expectedOutFileName);
639639
verifyContentHasString(outFileContent, file1.content);
640640
verifyContentHasString(outFileContent, `//# ${"sourceMappingURL"}=${outFileName}.map`); // Sometimes tools can sometimes see this line as a source mapping url comment, so we obfuscate it a little
641641

642642
// Verify map file
643643
const expectedMapFileName = expectedOutFileName + ".map";
644-
assert.isTrue(host.fileExists(expectedMapFileName));
644+
assert(host.fileExists(expectedMapFileName));
645645
const mapFileContent = host.readFile(expectedMapFileName);
646646
verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`);
647647

648648
function verifyContentHasString(content: string, str: string) {
649-
assert.isTrue(stringContains(content, str), `Expected "${content}" to have "${str}"`);
649+
assert(stringContains(content, str), `Expected "${content}" to have "${str}"`);
650650
}
651651
});
652652
});

Diff for: src/harness/unittests/configurationExtension.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ namespace ts {
113113
const caseSensitiveHost = new Utils.MockParseConfigHost(caseSensitiveBasePath, /*useCaseSensitiveFileNames*/ true, testContents);
114114

115115
function verifyDiagnostics(actual: Diagnostic[], expected: {code: number, category: DiagnosticCategory, messageText: string}[]) {
116-
assert.isTrue(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
116+
assert(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
117117
for (let i = 0; i < actual.length; i++) {
118118
const actualError = actual[i];
119119
const expectedError = expected[i];

0 commit comments

Comments
 (0)