diff --git a/protocol/src/common/protocol.diagnostic.ts b/protocol/src/common/protocol.diagnostic.ts index 8971b12c6..abb82d23d 100644 --- a/protocol/src/common/protocol.diagnostic.ts +++ b/protocol/src/common/protocol.diagnostic.ts @@ -109,7 +109,7 @@ export type DiagnosticServerCancellationData = { export namespace DiagnosticServerCancellationData { export function is(value: any): value is DiagnosticServerCancellationData { const candidate = value as DiagnosticServerCancellationData; - return candidate && Is.boolean(candidate.retriggerRequest); + return Is.objectLiteral(candidate) && Is.boolean(candidate.retriggerRequest); } } diff --git a/protocol/src/common/protocol.ts b/protocol/src/common/protocol.ts index 97e60d9fa..b5d0025f3 100644 --- a/protocol/src/common/protocol.ts +++ b/protocol/src/common/protocol.ts @@ -1188,7 +1188,7 @@ export namespace WorkDoneProgressOptions { } export function hasWorkDoneProgress(value: any): value is { workDoneProgress: boolean } { const candidate = value as WorkDoneProgressOptions; - return candidate && Is.boolean(candidate.workDoneProgress); + return Is.objectLiteral(candidate) && Is.boolean(candidate.workDoneProgress); } } diff --git a/protocol/src/node/test/documentFilter.test.ts b/protocol/src/node/test/documentFilter.test.ts index 51237e834..cd0375270 100644 --- a/protocol/src/node/test/documentFilter.test.ts +++ b/protocol/src/node/test/documentFilter.test.ts @@ -6,25 +6,15 @@ import * as assert from 'assert'; -import { DocumentSelector, NotebookCellTextDocumentFilter, NotebookDocumentFilter, RelativePattern, TextDocumentFilter, TextDocumentRegistrationOptions } from '../main'; +import { + DiagnosticServerCancellationData, DocumentSelector, NotebookCellTextDocumentFilter, NotebookDocumentFilter, + RelativePattern, TextDocumentFilter, TextDocumentRegistrationOptions, WorkDoneProgressOptions +} from '../main'; suite('Document filter type guards', () => { const relativePattern: RelativePattern = { baseUri: 'file:///workspace', pattern: '**/*.ipynb' }; - suite('TextDocumentFilter.is', () => { - test('valid filters', () => { - assert.strictEqual(TextDocumentFilter.is('typescript'), true); - assert.strictEqual(TextDocumentFilter.is({ language: 'typescript' }), true); - assert.strictEqual(TextDocumentFilter.is({ scheme: 'file' }), true); - assert.strictEqual(TextDocumentFilter.is({ pattern: '**/*.ts' }), true); - }); - test('null and undefined', () => { - assert.strictEqual(TextDocumentFilter.is(null), false); - assert.strictEqual(TextDocumentFilter.is(undefined), false); - }); - }); - suite('NotebookDocumentFilter.is', () => { test('string pattern', () => { assert.strictEqual(NotebookDocumentFilter.is({ pattern: '**/*.ipynb' }), true); @@ -54,20 +44,81 @@ suite('Document filter type guards', () => { }); }); - suite('DocumentSelector.is', () => { - test('null and undefined elements', () => { - assert.strictEqual(DocumentSelector.is([null as any]), false); - assert.strictEqual(DocumentSelector.is([undefined as any]), false); + suite('TextDocumentFilter.is', () => { + test('string filter', () => { + assert.strictEqual(TextDocumentFilter.is('typescript'), true); + }); + test('language filter', () => { + assert.strictEqual(TextDocumentFilter.is({ language: 'typescript' }), true); + }); + test('scheme filter', () => { + assert.strictEqual(TextDocumentFilter.is({ scheme: 'file' }), true); + }); + test('pattern filter with string pattern', () => { + assert.strictEqual(TextDocumentFilter.is({ pattern: '**/*.ts' }), true); + }); + test('pattern filter with relative pattern', () => { + assert.strictEqual(TextDocumentFilter.is({ pattern: relativePattern }), true); }); + test('null and undefined', () => { + assert.strictEqual(TextDocumentFilter.is(null), false); + assert.strictEqual(TextDocumentFilter.is(undefined), false); + }); + test('invalid values', () => { + assert.strictEqual(TextDocumentFilter.is({}), false); + assert.strictEqual(TextDocumentFilter.is(123), false); + assert.strictEqual(TextDocumentFilter.is(true), false); + assert.strictEqual(TextDocumentFilter.is({ pattern: 123 }), false); + }); + }); + + suite('DocumentSelector.is', () => { test('notebook cell filter with relative pattern', () => { const documentSelector = [{ notebook: { pattern: relativePattern } }]; assert.strictEqual(DocumentSelector.is(documentSelector), true); assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector }), true); }); - test('TextDocumentRegistrationOptions.is with null and undefined', () => { + test('null and undefined elements', () => { + assert.strictEqual(DocumentSelector.is([null as any]), false); + assert.strictEqual(DocumentSelector.is([undefined as any]), false); + assert.strictEqual(DocumentSelector.is(['typescript', null as any]), false); + }); + test('null and undefined selector', () => { + assert.strictEqual(DocumentSelector.is(null), false); + assert.strictEqual(DocumentSelector.is(undefined), false); + }); + }); + + suite('TextDocumentRegistrationOptions.is', () => { + test('valid registration options', () => { + assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector: ['typescript'] }), true); + assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector: null }), true); + }); + test('invalid registration options', () => { + assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector: [null] }), false); + assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector: [undefined] }), false); + }); + test('null and undefined', () => { assert.strictEqual(TextDocumentRegistrationOptions.is(null), false); assert.strictEqual(TextDocumentRegistrationOptions.is(undefined), false); - assert.strictEqual(TextDocumentRegistrationOptions.is({ documentSelector: [null] }), false); + assert.strictEqual(TextDocumentRegistrationOptions.is(123), false); + }); + }); + + suite('WorkDoneProgressOptions and DiagnosticServerCancellationData null handling', () => { + test('WorkDoneProgressOptions.hasWorkDoneProgress', () => { + assert.strictEqual(WorkDoneProgressOptions.hasWorkDoneProgress({ workDoneProgress: true }), true); + assert.strictEqual(WorkDoneProgressOptions.hasWorkDoneProgress({ workDoneProgress: false }), true); + assert.strictEqual(WorkDoneProgressOptions.hasWorkDoneProgress({}), false); + assert.strictEqual(WorkDoneProgressOptions.hasWorkDoneProgress(null), false); + assert.strictEqual(WorkDoneProgressOptions.hasWorkDoneProgress(undefined), false); + }); + test('DiagnosticServerCancellationData.is', () => { + assert.strictEqual(DiagnosticServerCancellationData.is({ retriggerRequest: true }), true); + assert.strictEqual(DiagnosticServerCancellationData.is({ retriggerRequest: false }), true); + assert.strictEqual(DiagnosticServerCancellationData.is({}), false); + assert.strictEqual(DiagnosticServerCancellationData.is(null), false); + assert.strictEqual(DiagnosticServerCancellationData.is(undefined), false); }); }); });