Skip to content

Commit d7b31e8

Browse files
committed
add tests
1 parent e10370b commit d7b31e8

File tree

1 file changed

+189
-1
lines changed

1 file changed

+189
-1
lines changed

src/notebooks/controllers/vscodeNotebookController.unit.test.ts

Lines changed: 189 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ import { KernelConnector } from './kernelConnector';
3737
import { ITrustedKernelPaths } from '../../kernels/raw/finder/types';
3838
import { IInterpreterService } from '../../platform/interpreter/contracts';
3939
import { PythonEnvironment } from '../../platform/pythonEnvironments/info';
40-
import { IConnectionDisplayDataProvider } from './types';
40+
import { IConnectionDisplayData, IConnectionDisplayDataProvider } from './types';
4141
import { ConnectionDisplayDataProvider } from './connectionDisplayData.node';
4242
import { mockedVSCodeNamespaces, resetVSCodeMocks } from '../../test/vscode-mock';
4343
import { Environment, PythonExtension } from '@vscode/python-extension';
4444
import { crateMockedPythonApi, whenResolveEnvironment } from '../../kernels/helpers.unit.test';
45+
import { IJupyterVariablesProvider } from '../../kernels/variables/types';
4546

4647
suite(`Notebook Controller`, function () {
4748
let controller: NotebookController;
@@ -544,4 +545,191 @@ suite(`Notebook Controller`, function () {
544545
});
545546
});
546547
});
548+
549+
suite('VSCodeNotebookController.create', function () {
550+
let kernelConnection: KernelConnectionMetadata;
551+
let kernelProvider: IKernelProvider;
552+
let context: IExtensionContext;
553+
let languageService: NotebookCellLanguageService;
554+
let configService: IConfigurationService;
555+
let extensionChecker: IPythonExtensionChecker;
556+
let serviceContainer: IServiceContainer;
557+
let displayDataProvider: IConnectionDisplayDataProvider;
558+
let jupyterVariablesProvider: IJupyterVariablesProvider;
559+
let disposables: IDisposable[] = [];
560+
let controller: NotebookController;
561+
let onDidChangeSelectedNotebooks: EventEmitter<{
562+
readonly notebook: NotebookDocument;
563+
readonly selected: boolean;
564+
}>;
565+
566+
setup(function () {
567+
resetVSCodeMocks();
568+
disposables.push(new Disposable(() => resetVSCodeMocks()));
569+
kernelConnection = mock<KernelConnectionMetadata>();
570+
kernelProvider = mock<IKernelProvider>();
571+
context = mock<IExtensionContext>();
572+
languageService = mock<NotebookCellLanguageService>();
573+
configService = mock<IConfigurationService>();
574+
extensionChecker = mock<IPythonExtensionChecker>();
575+
serviceContainer = mock<IServiceContainer>();
576+
displayDataProvider = mock<IConnectionDisplayDataProvider>();
577+
jupyterVariablesProvider = mock<IJupyterVariablesProvider>();
578+
controller = mock<NotebookController>();
579+
onDidChangeSelectedNotebooks = new EventEmitter<{
580+
readonly notebook: NotebookDocument;
581+
readonly selected: boolean;
582+
}>();
583+
disposables.push(onDidChangeSelectedNotebooks);
584+
585+
when(context.extensionUri).thenReturn(Uri.file('extension'));
586+
when(controller.onDidChangeSelectedNotebooks).thenReturn(onDidChangeSelectedNotebooks.event);
587+
when(displayDataProvider.getDisplayData(anything())).thenReturn({
588+
label: 'Test Kernel',
589+
description: 'Test Description',
590+
detail: 'Test Detail',
591+
category: 'Test Category',
592+
serverDisplayName: 'Test Server',
593+
onDidChange: new EventEmitter<IConnectionDisplayData>().event,
594+
dispose: () => {
595+
/* noop */
596+
}
597+
});
598+
when(
599+
mockedVSCodeNamespaces.notebooks.createNotebookController(
600+
anything(),
601+
anything(),
602+
anything(),
603+
anything(),
604+
anything()
605+
)
606+
).thenReturn(instance(controller));
607+
});
608+
609+
teardown(() => (disposables = dispose(disposables)));
610+
611+
test('Should attach variable provider when API is available', function () {
612+
// Arrange: Mock controller with variableProvider property
613+
const controllerWithApi = mock<NotebookController>();
614+
when(controllerWithApi.onDidChangeSelectedNotebooks).thenReturn(onDidChangeSelectedNotebooks.event);
615+
(instance(controllerWithApi) as any).variableProvider = undefined;
616+
617+
when(
618+
mockedVSCodeNamespaces.notebooks.createNotebookController(
619+
anything(),
620+
anything(),
621+
anything(),
622+
anything(),
623+
anything()
624+
)
625+
).thenReturn(instance(controllerWithApi));
626+
627+
// Act
628+
const result = VSCodeNotebookController.create(
629+
instance(kernelConnection),
630+
'test-id',
631+
'jupyter-notebook',
632+
instance(kernelProvider),
633+
instance(context),
634+
disposables,
635+
instance(languageService),
636+
instance(configService),
637+
instance(extensionChecker),
638+
instance(serviceContainer),
639+
instance(displayDataProvider),
640+
instance(jupyterVariablesProvider)
641+
);
642+
643+
// Assert
644+
assert.isDefined(result);
645+
assert.strictEqual(
646+
(result.controller as any).variableProvider,
647+
instance(jupyterVariablesProvider),
648+
'Variable provider should be attached when API is available'
649+
);
650+
});
651+
652+
test('Should not attach variable provider when API is not available', function () {
653+
// Arrange: Mock controller without variableProvider property
654+
const controllerWithoutApi = mock<NotebookController>();
655+
when(controllerWithoutApi.onDidChangeSelectedNotebooks).thenReturn(onDidChangeSelectedNotebooks.event);
656+
// Don't add variableProvider property to simulate API not being available
657+
658+
when(
659+
mockedVSCodeNamespaces.notebooks.createNotebookController(
660+
anything(),
661+
anything(),
662+
anything(),
663+
anything(),
664+
anything()
665+
)
666+
).thenReturn(instance(controllerWithoutApi));
667+
668+
// Act
669+
const result = VSCodeNotebookController.create(
670+
instance(kernelConnection),
671+
'test-id',
672+
'jupyter-notebook',
673+
instance(kernelProvider),
674+
instance(context),
675+
disposables,
676+
instance(languageService),
677+
instance(configService),
678+
instance(extensionChecker),
679+
instance(serviceContainer),
680+
instance(displayDataProvider),
681+
instance(jupyterVariablesProvider)
682+
);
683+
684+
// Assert
685+
assert.isDefined(result);
686+
assert.isUndefined(
687+
(result.controller as any).variableProvider,
688+
'Variable provider should not be attached when API is not available'
689+
);
690+
});
691+
692+
test('Should handle errors when attaching variable provider', function () {
693+
// Arrange: Mock controller that throws when setting variableProvider
694+
const controllerWithError = mock<NotebookController>();
695+
when(controllerWithError.onDidChangeSelectedNotebooks).thenReturn(onDidChangeSelectedNotebooks.event);
696+
697+
const controllerInstance = instance(controllerWithError);
698+
Object.defineProperty(controllerInstance, 'variableProvider', {
699+
set: () => {
700+
throw new Error('API not supported');
701+
},
702+
configurable: true
703+
});
704+
705+
when(
706+
mockedVSCodeNamespaces.notebooks.createNotebookController(
707+
anything(),
708+
anything(),
709+
anything(),
710+
anything(),
711+
anything()
712+
)
713+
).thenReturn(controllerInstance);
714+
715+
// Act - should not throw
716+
const result = VSCodeNotebookController.create(
717+
instance(kernelConnection),
718+
'test-id',
719+
'jupyter-notebook',
720+
instance(kernelProvider),
721+
instance(context),
722+
disposables,
723+
instance(languageService),
724+
instance(configService),
725+
instance(extensionChecker),
726+
instance(serviceContainer),
727+
instance(displayDataProvider),
728+
instance(jupyterVariablesProvider)
729+
);
730+
731+
// Assert
732+
assert.isDefined(result);
733+
});
734+
});
547735
});

0 commit comments

Comments
 (0)