Skip to content

Commit 92466b0

Browse files
committed
wip package.json tests
1 parent 4c2db5c commit 92466b0

1 file changed

Lines changed: 126 additions & 6 deletions

File tree

Lines changed: 126 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,145 @@
11
import * as assert from 'assert';
22
import * as vscode from 'vscode';
3+
import { CONFIG, ACCESS, ACTIONS, CONNECTION } from '../../../config';
34

45
suite('Web Extension Tests', () => {
56
test('Sanity Check', () => {
67
assert.strictEqual(9 + 10, 19, '9 + 10 shouldn\'t be 21, it should be 19!');
78
});
89

9-
test('Extension activates', async () => {
10-
// `publisher.name` from package.json: VSC-NeuroPilot.neuropilot-base
10+
test('Extension exists', async () => {
1111
const extension = vscode.extensions.getExtension('VSC-NeuroPilot.neuropilot-base');
12-
assert.ok(extension, 'Extension should be installed');
13-
await extension!.activate();
14-
assert.ok(extension!.isActive, 'Extension should be active');
12+
assert.ok(extension, 'Extension vsc-neuropilot.neuropilot-base should be installed!');
13+
await extension.activate();
14+
assert.ok(extension!.isActive, 'Extension should be active!');
1515
});
1616

1717
test('Workspace folder is correct', () => {
1818
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
1919
assert.ok(workspaceFolder, 'Workspace folder should be defined!');
2020
const acceptable = new Set(['test-playground', 'mount']);
21-
assert.ok(acceptable.has(workspaceFolder.name), `Workspace name should be one of ${Array.from(acceptable).join(', ')}`);
21+
assert.ok(acceptable.has(workspaceFolder.name), `Workspace name should be one of ${Array.from(acceptable).join(', ')}!`);
22+
});
23+
24+
test('All package.json settings have corresponding config class entries', () => {
25+
const extension = vscode.extensions.getExtension('VSC-NeuroPilot.neuropilot-base');
26+
assert.ok(extension, 'Extension should exist');
27+
28+
const packageJSON = extension!.packageJSON;
29+
const configuration = packageJSON.contributes?.configuration?.[0];
30+
assert.ok(configuration, 'Configuration should exist in package.json');
31+
32+
const properties = configuration.properties;
33+
assert.ok(properties, 'Properties should exist in configuration');
34+
35+
// Get all setting keys from package.json (excluding permission settings)
36+
const settingKeys = Object.keys(properties).filter(key =>
37+
key.startsWith('neuropilot.') &&
38+
!key.startsWith('neuropilot.permission.'),
39+
);
40+
41+
// Automatically discover properties from config classes
42+
const configClasses = {
43+
CONFIG,
44+
ACCESS,
45+
CONNECTION,
46+
ACTIONS,
47+
};
48+
49+
const mappedSettings = new Set<string>();
50+
const classErrors: string[] = [];
51+
52+
// Test each config class and collect accessible properties
53+
for (const [className, classInstance] of Object.entries(configClasses)) {
54+
try {
55+
const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(classInstance))
56+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
57+
.filter(prop => prop !== 'constructor' && typeof (classInstance as any)[prop] !== 'function');
58+
59+
// Try to access each property to see what settings it corresponds to
60+
for (const prop of properties) {
61+
try {
62+
// Access the property to trigger the getter
63+
//const value = (classInstance as any)[prop];
64+
65+
// Map property names to potential setting names
66+
const potentialSettings = [
67+
`neuropilot.${prop}`,
68+
`neuropilot.${className.toLowerCase()}.${prop}`,
69+
// Handle camelCase to kebab-case conversion
70+
`neuropilot.${prop.replace(/([A-Z])/g, '-$1').toLowerCase()}`,
71+
`neuropilot.${className.toLowerCase()}.${prop.replace(/([A-Z])/g, '-$1').toLowerCase()}`,
72+
];
73+
74+
// Check if any of these potential settings exist in package.json
75+
for (const setting of potentialSettings) {
76+
if ((properties as unknown as Record<string, unknown>)[setting]) {
77+
mappedSettings.add(setting);
78+
}
79+
}
80+
81+
} catch {
82+
// Some getters might fail, that's ok
83+
}
84+
}
85+
} catch (erm) {
86+
classErrors.push(`${className}: ${erm}`);
87+
}
88+
}
89+
90+
// Filter out deprecated settings
91+
const deprecatedSettings = [
92+
'neuropilot.websocketUrl',
93+
'neuropilot.gameName',
94+
'neuropilot.initialContext',
95+
'neuropilot.includePattern',
96+
'neuropilot.excludePattern',
97+
'neuropilot.allowUnsafePaths',
98+
'neuropilot.disabledActions',
99+
'neuropilot.hideCopilotRequests',
100+
'neuropilot.allowRunningAllTasks',
101+
'neuropilot.enableCancelEvents',
102+
];
103+
104+
const activeSettings = settingKeys.filter(key => !deprecatedSettings.includes(key));
105+
106+
// Find unmapped settings
107+
const unmappedSettings = activeSettings.filter(setting => !mappedSettings.has(setting));
108+
109+
// Report any class access errors
110+
if (classErrors.length > 0) {
111+
console.warn('Config class access errors:', classErrors);
112+
}
113+
114+
// Main assertion
115+
assert.strictEqual(
116+
unmappedSettings.length,
117+
0,
118+
`The following settings from package.json are not accessible through config classes: ${unmappedSettings.join(', ')}\n` +
119+
`Mapped settings: ${Array.from(mappedSettings).sort().join(', ')}`,
120+
);
121+
122+
// Verify config classes are functional
123+
try {
124+
// Test that we can access at least some properties from each class
125+
assert.ok(Object.prototype.hasOwnProperty.call(CONFIG, 'beforeContext') || typeof CONFIG.beforeContext !== 'undefined', 'CONFIG should have accessible properties');
126+
assert.ok(Object.prototype.hasOwnProperty.call(ACCESS, 'includePattern') || typeof ACCESS.includePattern !== 'undefined', 'ACCESS should have accessible properties');
127+
assert.ok(Object.prototype.hasOwnProperty.call(CONNECTION, 'websocketUrl') || typeof CONNECTION.websocketUrl !== 'undefined', 'CONNECTION should have accessible properties');
128+
assert.ok(Object.prototype.hasOwnProperty.call(ACTIONS, 'disabledActions') || typeof ACTIONS.disabledActions !== 'undefined', 'ACTIONS should have accessible properties');
129+
} catch (erm) {
130+
assert.fail(`Config class verification failed: ${erm}`);
131+
}
22132
});
23133

24134
// We also need a test to ensure that polyfilled modules (i.e. assert) are successfully bundled.
135+
test('assert module is polyfilled and works', () => {
136+
// eslint-disable-next-line @typescript-eslint/no-require-imports
137+
const assert = require('assert');
138+
try {
139+
assert.strictEqual(1, 2, 'Should throw');
140+
assert.fail('assert did not throw as expected');
141+
} catch (erm: unknown) {
142+
assert.ok(erm instanceof assert.AssertionError, 'Error should be an AssertionError');
143+
}
144+
});
25145
});

0 commit comments

Comments
 (0)