Skip to content

Commit 332d615

Browse files
test: Add test for DeepnoteRequirementsHelper (#178)
* test: Add test for DeepnoteRequirementsHelper Signed-off-by: Tomas Kislan <tomas@kislan.sk> * Fix test Signed-off-by: Tomas Kislan <tomas@kislan.sk> * fix: Add ENOENT code in mocked test error Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Signed-off-by: Tomas Kislan <tomas@kislan.sk> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent c80091e commit 332d615

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { assert } from 'chai';
2+
import * as sinon from 'sinon';
3+
import { instance, mock, when } from 'ts-mockito';
4+
import { CancellationToken, Uri, WorkspaceFolder } from 'vscode';
5+
import * as fs from 'fs';
6+
7+
import { DeepnoteRequirementsHelper } from './deepnoteRequirementsHelper.node';
8+
import type { DeepnoteProject } from '../../platform/deepnote/deepnoteTypes';
9+
import { ILogger } from '../../platform/logging/types';
10+
import { IPersistentStateFactory } from '../../platform/common/types';
11+
import { mockedVSCodeNamespaces, resetVSCodeMocks } from '../../test/vscode-mock';
12+
13+
suite('DeepnoteRequirementsHelper', () => {
14+
let helper: DeepnoteRequirementsHelper;
15+
let mockLogger: ILogger;
16+
let mockPersistentStateFactory: IPersistentStateFactory;
17+
let mockCancellationToken: CancellationToken;
18+
let sandbox: sinon.SinonSandbox;
19+
20+
setup(() => {
21+
resetVSCodeMocks();
22+
sandbox = sinon.createSandbox();
23+
24+
// Create mocks
25+
mockLogger = mock<ILogger>();
26+
mockPersistentStateFactory = mock<IPersistentStateFactory>();
27+
mockCancellationToken = mock<CancellationToken>();
28+
29+
// Setup default behavior for cancellation token
30+
when(mockCancellationToken.isCancellationRequested).thenReturn(false);
31+
32+
// Create the helper with mocked dependencies
33+
helper = new DeepnoteRequirementsHelper(instance(mockLogger), instance(mockPersistentStateFactory));
34+
});
35+
36+
teardown(() => {
37+
sandbox.restore();
38+
resetVSCodeMocks();
39+
});
40+
41+
test('should create requirements.txt file with valid requirements', async () => {
42+
// Arrange
43+
const workspaceUri = Uri.file('/test/workspace');
44+
const mockWorkspaceFolder: WorkspaceFolder = {
45+
uri: workspaceUri,
46+
name: 'test-workspace',
47+
index: 0
48+
};
49+
50+
when(mockedVSCodeNamespaces.workspace.workspaceFolders).thenReturn([mockWorkspaceFolder]);
51+
52+
const project: DeepnoteProject = {
53+
metadata: {
54+
createdAt: '2024-01-01T00:00:00Z'
55+
},
56+
version: '1',
57+
project: {
58+
id: 'test-project-id',
59+
name: 'Test Project',
60+
notebooks: [],
61+
settings: {
62+
requirements: ['numpy>=1.20.0', 'pandas==1.3.0', 'matplotlib']
63+
}
64+
}
65+
};
66+
67+
// Mock fs.promises to check file doesn't exist
68+
const fsAccessStub = sandbox.stub(fs.promises, 'access');
69+
const notFoundError = Object.assign(new Error('File not found'), { code: 'ENOENT' });
70+
fsAccessStub.rejects(notFoundError);
71+
72+
// Mock fs.promises.writeFile to capture what's written
73+
let writtenContent = '';
74+
let writtenPath = '';
75+
const fsWriteFileStub = sandbox.stub(fs.promises, 'writeFile');
76+
fsWriteFileStub.callsFake(async (path, content) => {
77+
writtenPath = path.toString();
78+
writtenContent = content.toString();
79+
});
80+
81+
// Act
82+
await helper.createRequirementsFile(project, instance(mockCancellationToken));
83+
84+
// Assert
85+
assert.isTrue(fsWriteFileStub.calledOnce, 'writeFile should be called once');
86+
assert.include(writtenPath, 'requirements.txt', 'Should write to requirements.txt');
87+
assert.include(writtenContent, 'numpy>=1.20.0', 'Should include numpy requirement');
88+
assert.include(writtenContent, 'pandas==1.3.0', 'Should include pandas requirement');
89+
assert.include(writtenContent, 'matplotlib', 'Should include matplotlib requirement');
90+
91+
// Verify content format (should have LF line endings)
92+
const expectedContent = 'numpy>=1.20.0\npandas==1.3.0\nmatplotlib\n';
93+
assert.strictEqual(writtenContent, expectedContent, 'Content should match expected format');
94+
});
95+
});

0 commit comments

Comments
 (0)