stigmergy 1.2.0 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/LICENSE +18 -18
  2. package/README.md +28 -223
  3. package/STIGMERGY.md +61 -61
  4. package/docs/PROJECT_CONSTITUTION.md +433 -433
  5. package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
  6. package/examples/calculator-example.js +72 -72
  7. package/examples/cline_usage_examples.md +364 -364
  8. package/examples/encryption-example.js +67 -67
  9. package/examples/json-parser-example.js +120 -120
  10. package/examples/json-validation-example.js +64 -64
  11. package/examples/rest-client-example.js +52 -52
  12. package/examples/rest_client_example.js +54 -54
  13. package/package.json +36 -15
  14. package/scripts/build.js +74 -74
  15. package/scripts/post-deployment-config.js +296 -296
  16. package/scripts/preinstall-check.js +173 -173
  17. package/scripts/publish.js +58 -268
  18. package/scripts/run-layered-tests.js +247 -0
  19. package/scripts/safe-install.js +139 -139
  20. package/scripts/simple-publish.js +57 -59
  21. package/src/adapters/claude/install_claude_integration.js +292 -0
  22. package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
  23. package/src/adapters/codex/install_codex_integration.js +395 -0
  24. package/src/adapters/copilot/install_copilot_integration.js +716 -0
  25. package/src/adapters/gemini/install_gemini_integration.js +304 -0
  26. package/src/adapters/iflow/install_iflow_integration.js +304 -0
  27. package/src/adapters/qoder/install_qoder_integration.js +1090 -0
  28. package/src/adapters/qwen/install_qwen_integration.js +285 -0
  29. package/src/auth.js +173 -173
  30. package/src/auth_command.js +208 -208
  31. package/src/calculator.js +313 -313
  32. package/src/cli/router.js +417 -38
  33. package/src/core/cache_cleaner.js +767 -744
  34. package/src/core/cli_help_analyzer.js +680 -674
  35. package/src/core/cli_parameter_handler.js +132 -127
  36. package/src/core/cli_tools.js +89 -89
  37. package/src/core/coordination/index.js +16 -16
  38. package/src/core/coordination/nodejs/AdapterManager.js +102 -89
  39. package/src/core/coordination/nodejs/CLCommunication.js +132 -124
  40. package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -236
  41. package/src/core/coordination/nodejs/HealthChecker.js +76 -77
  42. package/src/core/coordination/nodejs/HookDeploymentManager.js +263 -190
  43. package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
  44. package/src/core/coordination/nodejs/index.js +90 -72
  45. package/src/core/coordination/nodejs/utils/Logger.js +29 -29
  46. package/src/core/enhanced_installer.js +479 -456
  47. package/src/core/enhanced_uninstaller.js +638 -618
  48. package/src/core/error_handler.js +406 -406
  49. package/src/core/installer.js +815 -294
  50. package/src/core/memory_manager.js +83 -83
  51. package/src/core/rest_client.js +160 -160
  52. package/src/core/smart_router.js +249 -146
  53. package/src/core/upgrade_manager.js +76 -59
  54. package/src/data_encryption.js +143 -143
  55. package/src/data_structures.js +440 -440
  56. package/src/deploy.js +55 -55
  57. package/src/index.js +30 -30
  58. package/src/test/cli-availability-checker.js +194 -0
  59. package/src/test/test-environment.js +289 -0
  60. package/src/utils/helpers.js +35 -35
  61. package/src/utils.js +921 -915
  62. package/src/weatherProcessor.js +228 -228
  63. package/test/cache-cleaner-implemented.test.js +0 -328
  64. package/test/cache-cleaner.test.js +0 -390
  65. package/test/calculator.test.js +0 -215
  66. package/test/collision-test.js +0 -26
  67. package/test/comprehensive-enhanced-features.test.js +0 -252
  68. package/test/comprehensive-execution-test.js +0 -428
  69. package/test/conflict-prevention-test.js +0 -95
  70. package/test/cross-cli-detection-test.js +0 -33
  71. package/test/csv-processing-test.js +0 -36
  72. package/test/deploy-hooks-test.js +0 -250
  73. package/test/e2e/claude-cli-test.js +0 -128
  74. package/test/e2e/collaboration-test.js +0 -75
  75. package/test/e2e/comprehensive-test.js +0 -431
  76. package/test/e2e/error-handling-test.js +0 -90
  77. package/test/e2e/individual-tool-test.js +0 -143
  78. package/test/e2e/other-cli-test.js +0 -130
  79. package/test/e2e/qoder-cli-test.js +0 -128
  80. package/test/e2e/run-e2e-tests.js +0 -73
  81. package/test/e2e/test-data.js +0 -88
  82. package/test/e2e/test-utils.js +0 -222
  83. package/test/encryption-simple-test.js +0 -110
  84. package/test/encryption.test.js +0 -129
  85. package/test/enhanced-main-alignment.test.js +0 -298
  86. package/test/enhanced-uninstaller-implemented.test.js +0 -271
  87. package/test/enhanced-uninstaller.test.js +0 -284
  88. package/test/error-handling-test.js +0 -341
  89. package/test/fibonacci.test.js +0 -178
  90. package/test/final-deploy-test.js +0 -221
  91. package/test/final-install-test.js +0 -226
  92. package/test/hash-table-demo.js +0 -33
  93. package/test/hash-table-test.js +0 -26
  94. package/test/hash_table_test.js +0 -114
  95. package/test/hook-system-integration-test.js +0 -307
  96. package/test/iflow-integration-test.js +0 -292
  97. package/test/improved-install-test.js +0 -362
  98. package/test/install-command-test.js +0 -370
  99. package/test/json-parser-test.js +0 -161
  100. package/test/json-validation-test.js +0 -164
  101. package/test/natural-language-skills-test.js +0 -320
  102. package/test/nl-integration-test.js +0 -179
  103. package/test/parameter-parsing-test.js +0 -143
  104. package/test/plugin-deployment-test.js +0 -316
  105. package/test/postinstall-test.js +0 -269
  106. package/test/python-plugins-test.js +0 -259
  107. package/test/real-test.js +0 -435
  108. package/test/remaining-adapters-test.js +0 -256
  109. package/test/rest-client-test.js +0 -56
  110. package/test/rest_client.test.js +0 -85
  111. package/test/safe-installation-cleaner.test.js +0 -343
  112. package/test/simple-iflow-hook-test.js +0 -137
  113. package/test/stigmergy-upgrade-test.js +0 -243
  114. package/test/system-compatibility-test.js +0 -467
  115. package/test/tdd-deploy-fix-test.js +0 -324
  116. package/test/tdd-fixes-test.js +0 -211
  117. package/test/third-party-skills-test.js +0 -321
  118. package/test/tool-selection-integration-test.js +0 -158
  119. package/test/unit/calculator-full.test.js +0 -191
  120. package/test/unit/calculator-simple.test.js +0 -96
  121. package/test/unit/calculator.test.js +0 -97
  122. package/test/unit/cli-scanner.test.js +0 -291
  123. package/test/unit/cli_parameter_handler.test.js +0 -116
  124. package/test/unit/cross-cli-executor.test.js +0 -399
  125. package/test/weather-processor.test.js +0 -104
@@ -1,321 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Third-Party Skills Integration Test
5
- * Tests integration with external Claude Skills repositories
6
- */
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
-
11
- // Third-party skills repository configurations
12
- const THIRD_PARTY_SKILLS = {
13
- // Example: Claude Skills from community repositories
14
- 'claude-skills-community': {
15
- name: 'Claude Skills Community',
16
- repository: 'https://github.com/community/claude-skills',
17
- description: 'Community-maintained Claude CLI skills',
18
- skills: [
19
- {
20
- id: 'web-scraping',
21
- name: 'Web Scraping',
22
- description: 'Extract data from websites',
23
- category: 'data',
24
- tools: ['claude'],
25
- parameters: {
26
- url: { type: 'string', required: true, description: 'Target website URL' },
27
- format: { type: 'string', required: false, options: ['json', 'csv', 'xml'], description: 'Output format' }
28
- },
29
- template: 'Extract data from {url} and format as {format}'
30
- },
31
- {
32
- id: 'data-analysis',
33
- name: 'Data Analysis',
34
- description: 'Analyze datasets and generate insights',
35
- category: 'analysis',
36
- tools: ['claude', 'gemini'],
37
- parameters: {
38
- dataset: { type: 'string', required: true, description: 'Dataset path or description' },
39
- type: { type: 'string', required: true, options: ['statistical', 'predictive', 'descriptive'], description: 'Analysis type' }
40
- },
41
- template: 'Perform {type} analysis on {dataset}'
42
- }
43
- ]
44
- },
45
-
46
- // Example: Advanced Development Skills
47
- 'dev-skills-advanced': {
48
- name: 'Advanced Development Skills',
49
- repository: 'https://github.com/devtools/advanced-skills',
50
- description: 'Professional development utilities',
51
- skills: [
52
- {
53
- id: 'api-testing',
54
- name: 'API Testing',
55
- description: 'Test REST APIs and generate test cases',
56
- category: 'testing',
57
- tools: ['claude', 'codebuddy'],
58
- parameters: {
59
- endpoint: { type: 'string', required: true, description: 'API endpoint URL' },
60
- method: { type: 'string', required: false, options: ['GET', 'POST', 'PUT', 'DELETE'], description: 'HTTP method' },
61
- format: { type: 'string', required: false, options: ['javascript', 'python', 'curl'], description: 'Test format' }
62
- },
63
- template: 'Generate {method} tests for API endpoint {endpoint} in {format}'
64
- },
65
- {
66
- id: 'performance-profiling',
67
- name: 'Performance Profiling',
68
- description: 'Profile application performance',
69
- category: 'optimization',
70
- tools: ['claude', 'gemini', 'iflow'],
71
- parameters: {
72
- target: { type: 'string', required: true, description: 'Application or code to profile' },
73
- metrics: { type: 'array', required: false, description: 'Performance metrics to track' }
74
- },
75
- template: 'Profile performance of {target} focusing on {metrics}'
76
- }
77
- ]
78
- }
79
- };
80
-
81
- class ThirdPartySkillsTest {
82
- constructor() {
83
- this.testResults = [];
84
- }
85
-
86
- async runTests() {
87
- console.log('==============================================');
88
- console.log('THIRD-PARTY SKILLS INTEGRATION TEST');
89
- console.log('==============================================');
90
- console.log('');
91
-
92
- // Test 1: Load external skills
93
- await this.testLoadExternalSkills();
94
-
95
- // Test 2: Validate skill format compatibility
96
- await this.testSkillCompatibility();
97
-
98
- // Test 3: Test skill execution with external skills
99
- await this.testExternalSkillExecution();
100
-
101
- // Test 4: Test skill marketplace concept
102
- await this.testSkillMarketplace();
103
-
104
- this.printResults();
105
- }
106
-
107
- async testLoadExternalSkills() {
108
- console.log('TEST 1: Loading External Skills Repositories');
109
- console.log('---------------------------------------------');
110
-
111
- try {
112
- for (const [repoId, repoConfig] of Object.entries(THIRD_PARTY_SKILLS)) {
113
- console.log(`Loading skills from: ${repoConfig.name}`);
114
-
115
- // In a real implementation, this would fetch from remote repository
116
- // For testing, we use the local configuration
117
- console.log(` - Repository: ${repoConfig.repository}`);
118
- console.log(` - Skills found: ${repoConfig.skills.length}`);
119
-
120
- repoConfig.skills.forEach(skill => {
121
- console.log(` * ${skill.name} (${skill.id})`);
122
- });
123
- console.log('');
124
-
125
- this.addTestResult('External Skills Loading', true, `Successfully loaded ${repoConfig.skills.length} skills from ${repoConfig.name}`);
126
- }
127
- } catch (error) {
128
- this.addTestResult('External Skills Loading', false, `Error: ${error.message}`);
129
- }
130
- }
131
-
132
- async testSkillCompatibility() {
133
- console.log('TEST 2: Skill Format Compatibility');
134
- console.log('------------------------------------');
135
-
136
- try {
137
- // Check if external skills match our internal format
138
- let compatibilityIssues = 0;
139
- let totalSkills = 0;
140
-
141
- for (const [repoId, repoConfig] of Object.entries(THIRD_PARTY_SKILLS)) {
142
- for (const skill of repoConfig.skills) {
143
- totalSkills++;
144
-
145
- // Check required fields
146
- const requiredFields = ['id', 'name', 'description', 'category', 'tools', 'parameters', 'template'];
147
- const missingFields = requiredFields.filter(field => !skill[field]);
148
-
149
- if (missingFields.length > 0) {
150
- console.log(` ❌ Skill ${skill.id} missing fields: ${missingFields.join(', ')}`);
151
- compatibilityIssues++;
152
- } else {
153
- console.log(` ✅ Skill ${skill.id} format compatible`);
154
- }
155
-
156
- // Check parameter format
157
- if (skill.parameters) {
158
- for (const [paramName, paramConfig] of Object.entries(skill.parameters)) {
159
- if (!paramConfig.type || !paramConfig.description) {
160
- console.log(` ⚠️ Parameter ${paramName} missing type or description`);
161
- compatibilityIssues++;
162
- }
163
- }
164
- }
165
- }
166
- }
167
-
168
- if (compatibilityIssues === 0) {
169
- this.addTestResult('Skill Compatibility', true, `All ${totalSkills} external skills are compatible`);
170
- } else {
171
- this.addTestResult('Skill Compatibility', false, `Found ${compatibilityIssues} compatibility issues`);
172
- }
173
-
174
- } catch (error) {
175
- this.addTestResult('Skill Compatibility', false, `Error: ${error.message}`);
176
- }
177
- }
178
-
179
- async testExternalSkillExecution() {
180
- console.log('TEST 3: External Skill Execution');
181
- console.log('------------------------------');
182
-
183
- try {
184
- // Test with an external skill
185
- const externalSkill = THIRD_PARTY_SKILLS['claude-skills-community'].skills[0]; // web-scraping skill
186
-
187
- console.log(`Testing external skill: ${externalSkill.name}`);
188
-
189
- // Simulate loading external skill into our system
190
- const mockSkillsManager = {
191
- skills: {
192
- ...THIRD_PARTY_SKILLS['claude-skills-community'].skills.reduce((acc, skill) => {
193
- acc[skill.id] = skill;
194
- return acc;
195
- }, {})
196
- }
197
- };
198
-
199
- // Test skill execution
200
- const testParams = {
201
- url: 'https://example.com',
202
- format: 'json'
203
- };
204
-
205
- console.log(` - Executing ${externalSkill.id} with params:`, testParams);
206
- console.log(` - Template: ${externalSkill.template}`);
207
-
208
- // Simulate command building
209
- let command = externalSkill.template;
210
- for (const [key, value] of Object.entries(testParams)) {
211
- const placeholder = `{${key}}`;
212
- command = command.replace(new RegExp(placeholder, 'g'), value);
213
- }
214
-
215
- console.log(` - Generated command: ${command}`);
216
- console.log(` ✅ External skill execution simulation successful`);
217
-
218
- this.addTestResult('External Skill Execution', true, `Successfully simulated execution of ${externalSkill.name}`);
219
-
220
- } catch (error) {
221
- this.addTestResult('External Skill Execution', false, `Error: ${error.message}`);
222
- }
223
- }
224
-
225
- async testSkillMarketplace() {
226
- console.log('TEST 4: Skill Marketplace Concept');
227
- console.log('----------------------------------');
228
-
229
- try {
230
- // Simulate installing skills from marketplace
231
- const marketplaceSkills = [
232
- {
233
- id: 'sql-query-builder',
234
- name: 'SQL Query Builder',
235
- repository: 'https://github.com/database/sql-skills',
236
- description: 'Build SQL queries from natural language'
237
- },
238
- {
239
- id: 'docker-generator',
240
- name: 'Docker Generator',
241
- repository: 'https://github.com/devops/docker-skills',
242
- description: 'Generate Dockerfiles from project descriptions'
243
- },
244
- {
245
- id: 'kubernetes-yaml',
246
- name: 'Kubernetes YAML Generator',
247
- repository: 'https://github.com/k8s/yaml-skills',
248
- description: 'Generate Kubernetes manifests'
249
- }
250
- ];
251
-
252
- console.log('Available skills in marketplace:');
253
- marketplaceSkills.forEach(skill => {
254
- console.log(` * ${skill.name} (${skill.id}) - ${skill.description}`);
255
- console.log(` Repository: ${skill.repository}`);
256
- });
257
-
258
- console.log('');
259
- console.log('Marketplace integration capabilities:');
260
- console.log(' ✅ Remote skill loading');
261
- console.log(' ✅ Skill validation and security checking');
262
- console.log(' ✅ Version management');
263
- console.log(' ✅ Dependency resolution');
264
- console.log(' ✅ Community rating system');
265
-
266
- this.addTestResult('Skill Marketplace', true, 'Marketplace concept is fully implementable');
267
-
268
- } catch (error) {
269
- this.addTestResult('Skill Marketplace', false, `Error: ${error.message}`);
270
- }
271
- }
272
-
273
- addTestResult(testName, passed, message) {
274
- this.testResults.push({
275
- name: testName,
276
- passed,
277
- message
278
- });
279
- }
280
-
281
- printResults() {
282
- console.log('');
283
- console.log('==============================================');
284
- console.log('TEST RESULTS SUMMARY');
285
- console.log('==============================================');
286
-
287
- const totalTests = this.testResults.length;
288
- const passedTests = this.testResults.filter(r => r.passed).length;
289
- const failedTests = totalTests - passedTests;
290
-
291
- console.log(`Total tests: ${totalTests}`);
292
- console.log(`Passed: ${passedTests}`);
293
- console.log(`Failed: ${failedTests}`);
294
- console.log(`Success rate: ${((passedTests / totalTests) * 100).toFixed(1)}%`);
295
- console.log('');
296
-
297
- if (failedTests > 0) {
298
- console.log('FAILED TESTS:');
299
- this.testResults
300
- .filter(r => !r.passed)
301
- .forEach(r => console.log(` - ${r.name}: ${r.message}`));
302
- }
303
-
304
- console.log('');
305
- console.log('==============================================');
306
-
307
- if (passedTests === totalTests) {
308
- console.log('🎉 ALL TESTS PASSED! Third-party skills integration is working.');
309
- } else {
310
- console.log('⚠️ Some tests failed. Review issues before deployment.');
311
- }
312
- }
313
- }
314
-
315
- // Run tests
316
- if (require.main === module) {
317
- const test = new ThirdPartySkillsTest();
318
- test.runTests();
319
- }
320
-
321
- module.exports = ThirdPartySkillsTest;
@@ -1,158 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Integration Test for Tool Selection Fix
5
- * Tests the actual main.js handleSkillsCommand function
6
- */
7
-
8
- const { spawn } = require('child_process');
9
- const path = require('path');
10
-
11
- function runCommand(args) {
12
- return new Promise((resolve, reject) => {
13
- const mainPath = path.join(__dirname, '..', 'src', 'main.js');
14
- const child = spawn('node', [mainPath, ...args], {
15
- cwd: path.join(__dirname, '..'),
16
- stdio: ['pipe', 'pipe', 'pipe'],
17
- encoding: 'utf8'
18
- });
19
-
20
- let stdout = '';
21
- let stderr = '';
22
-
23
- child.stdout.on('data', (data) => {
24
- stdout += data;
25
- });
26
-
27
- child.stderr.on('data', (data) => {
28
- stderr += data;
29
- });
30
-
31
- child.on('close', (code) => {
32
- resolve({ code, stdout, stderr });
33
- });
34
-
35
- child.on('error', (error) => {
36
- reject(error);
37
- });
38
- });
39
- }
40
-
41
- async function testToolSelectionIntegration() {
42
- console.log('==============================================');
43
- console.log('TOOL SELECTION INTEGRATION TEST');
44
- console.log('==============================================');
45
- console.log('');
46
-
47
- const testCases = [
48
- {
49
- name: 'Test 1: Tool selection with --tool=claude',
50
- args: ['skills', 'execute', 'translation', '--text=hello', '--to=zh', '--tool=claude'],
51
- expectedTool: 'claude',
52
- shouldContain: ['Using tool: claude']
53
- },
54
- {
55
- name: 'Test 2: Tool selection with --tool gemini',
56
- args: ['skills', 'execute', 'translation', '--text=hello', '--to=zh', '--tool', 'gemini'],
57
- expectedTool: 'gemini',
58
- shouldContain: ['Using tool: gemini']
59
- },
60
- {
61
- name: 'Test 3: No tool specified (should use default)',
62
- args: ['skills', 'execute', 'translation', '--text=hello', '--to=zh'],
63
- expectedTool: null,
64
- shouldContain: ['Executing skill: translation'],
65
- shouldNotContain: ['Using tool:']
66
- },
67
- {
68
- name: 'Test 4: Complex parameters with tool selection',
69
- args: ['skills', 'execute', 'code-analysis', '--file=app.js', '--line=10', '--tool=qwen'],
70
- expectedTool: 'qwen',
71
- shouldContain: ['Using tool: qwen', 'Parameters: {"file":"app.js","line":"10"}']
72
- }
73
- ];
74
-
75
- let passed = 0;
76
- let total = testCases.length;
77
-
78
- for (const testCase of testCases) {
79
- console.log(`${testCase.name}`);
80
- console.log(`Command: node package/src/index.js ${testCase.args.join(' ')}`);
81
-
82
- try {
83
- const result = await runCommand(testCase.args);
84
-
85
- console.log(`Exit code: ${result.code}`);
86
- if (result.stdout) {
87
- console.log(`Output: ${result.stdout.trim()}`);
88
- }
89
- if (result.stderr) {
90
- console.log(`Error: ${result.stderr.trim()}`);
91
- }
92
-
93
- // Validate results
94
- let success = true;
95
-
96
- // Check for expected content
97
- if (testCase.shouldContain) {
98
- for (const expected of testCase.shouldContain) {
99
- if (!result.stdout.includes(expected)) {
100
- console.log(`❌ Missing expected output: "${expected}"`);
101
- success = false;
102
- }
103
- }
104
- }
105
-
106
- // Check for unexpected content
107
- if (testCase.shouldNotContain) {
108
- for (const unexpected of testCase.shouldNotContain) {
109
- if (result.stdout.includes(unexpected)) {
110
- console.log(`❌ Found unexpected output: "${unexpected}"`);
111
- success = false;
112
- }
113
- }
114
- }
115
-
116
- // Check exit code
117
- if (result.code !== 0) {
118
- console.log(`❌ Command failed with exit code ${result.code}`);
119
- success = false;
120
- }
121
-
122
- if (success) {
123
- console.log(`✅ PASSED`);
124
- passed++;
125
- } else {
126
- console.log(`❌ FAILED`);
127
- }
128
-
129
- } catch (error) {
130
- console.log(`❌ ERROR: ${error.message}`);
131
- }
132
-
133
- console.log('');
134
- }
135
-
136
- console.log('==============================================');
137
- console.log('TOOL SELECTION TEST SUMMARY');
138
- console.log('==============================================');
139
- console.log(`Tests passed: ${passed}/${total}`);
140
-
141
- if (passed === total) {
142
- console.log('🎉 All tool selection tests passed!');
143
- console.log('✅ Tool selection logic has been successfully fixed!');
144
- } else {
145
- console.log('⚠️ Some tests failed. Tool selection still needs work.');
146
- }
147
-
148
- return passed === total;
149
- }
150
-
151
- // Run tests if called directly
152
- if (require.main === module) {
153
- testToolSelectionIntegration().then(success => {
154
- process.exit(success ? 0 : 1);
155
- });
156
- }
157
-
158
- module.exports = { testToolSelectionIntegration };
@@ -1,191 +0,0 @@
1
- /**
2
- * Unit tests for Calculator class following project patterns
3
- */
4
-
5
- const assert = require('assert');
6
- const Calculator = require('../../src/calculator');
7
-
8
- describe('Calculator Unit Tests', () => {
9
- let calc;
10
-
11
- beforeEach(() => {
12
- calc = new Calculator();
13
- });
14
-
15
- describe('Basic Arithmetic Operations', () => {
16
- it('should add two numbers correctly', () => {
17
- assert.strictEqual(calc.add(5, 3), 8);
18
- assert.strictEqual(calc.add(-2, 7), 5);
19
- assert.strictEqual(calc.add(0, 0), 0);
20
- assert.strictEqual(calc.add(1.5, 2.5), 4);
21
- });
22
-
23
- it('should subtract two numbers correctly', () => {
24
- assert.strictEqual(calc.subtract(10, 4), 6);
25
- assert.strictEqual(calc.subtract(5, 8), -3);
26
- assert.strictEqual(calc.subtract(0, 0), 0);
27
- assert.strictEqual(calc.subtract(3.5, 1.5), 2);
28
- });
29
-
30
- it('should multiply two numbers correctly', () => {
31
- assert.strictEqual(calc.multiply(6, 7), 42);
32
- assert.strictEqual(calc.multiply(-3, 4), -12);
33
- assert.strictEqual(calc.multiply(0, 100), 0);
34
- assert.strictEqual(calc.multiply(2.5, 4), 10);
35
- });
36
-
37
- it('should divide two numbers correctly', () => {
38
- assert.strictEqual(calc.divide(15, 3), 5);
39
- assert.strictEqual(calc.divide(7, 2), 3.5);
40
- assert.strictEqual(calc.divide(-10, 2), -5);
41
- assert.strictEqual(calc.divide(1, 3), 1/3);
42
- });
43
-
44
- it('should throw error when dividing by zero', () => {
45
- assert.throws(() => calc.divide(10, 0), {
46
- name: 'Error',
47
- message: 'Cannot divide by zero'
48
- });
49
- });
50
- });
51
-
52
- describe('Advanced Mathematical Operations', () => {
53
- it('should calculate power correctly', () => {
54
- assert.strictEqual(calc.power(2, 3), 8);
55
- assert.strictEqual(calc.power(5, 0), 1);
56
- assert.strictEqual(calc.power(10, 2), 100);
57
- assert.strictEqual(calc.power(4, 0.5), 2);
58
- });
59
-
60
- it('should calculate square root correctly', () => {
61
- assert.strictEqual(calc.sqrt(16), 4);
62
- assert.strictEqual(calc.sqrt(0), 0);
63
- assert.strictEqual(calc.sqrt(1), 1);
64
- assert.strictEqual(calc.sqrt(2), Math.sqrt(2));
65
- });
66
-
67
- it('should throw error when calculating square root of negative number', () => {
68
- assert.throws(() => calc.sqrt(-4), {
69
- name: 'Error',
70
- message: 'Cannot calculate square root of negative number'
71
- });
72
- });
73
-
74
- it('should calculate factorial correctly', () => {
75
- assert.strictEqual(calc.factorial(5), 120);
76
- assert.strictEqual(calc.factorial(0), 1);
77
- assert.strictEqual(calc.factorial(1), 1);
78
- assert.strictEqual(calc.factorial(3), 6);
79
- });
80
-
81
- it('should throw error when calculating factorial of negative number', () => {
82
- assert.throws(() => calc.factorial(-5), {
83
- name: 'Error',
84
- message: 'Cannot calculate factorial of negative number'
85
- });
86
- });
87
-
88
- it('should calculate percentage correctly', () => {
89
- assert.strictEqual(calc.percentage(25, 100), 25);
90
- assert.strictEqual(calc.percentage(10, 50), 20);
91
- assert.strictEqual(calc.percentage(0, 100), 0);
92
- assert.strictEqual(calc.percentage(75, 150), 50);
93
- });
94
-
95
- it('should throw error when calculating percentage with zero as whole', () => {
96
- assert.throws(() => calc.percentage(50, 0), {
97
- name: 'Error',
98
- message: 'Cannot calculate percentage with zero as whole'
99
- });
100
- });
101
- });
102
-
103
- describe('Calculation Chain', () => {
104
- it('should chain calculations correctly', () => {
105
- const result = calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals();
106
- // ((10 + 5) * 2 - 4) / 2 = (30 - 4) / 2 = 26 / 2 = 13
107
- assert.strictEqual(result, 13);
108
- });
109
-
110
- it('should throw error when dividing by zero in chain', () => {
111
- assert.throws(() => calc.chain(10).divide(0), {
112
- name: 'Error',
113
- message: 'Cannot divide by zero'
114
- });
115
- });
116
-
117
- it('should return current value without ending chain', () => {
118
- const chain = calc.chain(5).add(3);
119
- assert.strictEqual(chain.value(), 8);
120
- });
121
-
122
- it('should support method chaining', () => {
123
- const chain = calc.chain(2);
124
- assert.strictEqual(chain.add(3), chain); // Should return itself for chaining
125
- assert.strictEqual(chain.subtract(1), chain);
126
- assert.strictEqual(chain.multiply(2), chain);
127
- assert.strictEqual(chain.divide(2), chain);
128
- assert.strictEqual(chain.power(2), chain);
129
- });
130
- });
131
- });
132
-
133
- // Run tests directly if this file is executed
134
- if (require.main === module) {
135
- console.log('Running Calculator Unit Tests...');
136
-
137
- const calc = new Calculator();
138
-
139
- // Test basic operations
140
- console.log('\n1. Testing basic arithmetic operations:');
141
- console.log('calc.add(5, 3) =', calc.add(5, 3));
142
- console.log('calc.subtract(10, 4) =', calc.subtract(10, 4));
143
- console.log('calc.multiply(6, 7) =', calc.multiply(6, 7));
144
- console.log('calc.divide(15, 3) =', calc.divide(15, 3));
145
-
146
- // Test advanced operations
147
- console.log('\n2. Testing advanced mathematical operations:');
148
- console.log('calc.power(2, 3) =', calc.power(2, 3));
149
- console.log('calc.sqrt(16) =', calc.sqrt(16));
150
- console.log('calc.factorial(5) =', calc.factorial(5));
151
- console.log('calc.percentage(25, 100) =', calc.percentage(25, 100) + '%');
152
-
153
- // Test calculation chain
154
- console.log('\n3. Testing calculation chain:');
155
- const chainResult = calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals();
156
- console.log('calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals() =', chainResult);
157
-
158
- // Test error cases
159
- console.log('\n4. Testing error handling:');
160
- try {
161
- calc.divide(10, 0);
162
- } catch (error) {
163
- console.log('Division by zero error:', error.message);
164
- }
165
-
166
- try {
167
- calc.sqrt(-4);
168
- } catch (error) {
169
- console.log('Square root of negative number error:', error.message);
170
- }
171
-
172
- try {
173
- calc.factorial(-5);
174
- } catch (error) {
175
- console.log('Factorial of negative number error:', error.message);
176
- }
177
-
178
- try {
179
- calc.percentage(50, 0);
180
- } catch (error) {
181
- console.log('Percentage with zero as whole error:', error.message);
182
- }
183
-
184
- try {
185
- calc.chain(10).divide(0);
186
- } catch (error) {
187
- console.log('Chain division by zero error:', error.message);
188
- }
189
-
190
- console.log('\n✅ All Calculator tests completed!');
191
- }