test: switch to Deno native testing framework

- Remove tapbundle and @git.zone/tstest dependency
- Use Deno.test() and @std/assert for all tests
- Update test imports to use jsr:@std/assert
- All 10 logger tests passing with native Deno test runner
- Simplified test configuration in deno.json
- Tests are now completely dependency-free (only standard library)
This commit is contained in:
2025-10-18 16:01:38 +00:00
parent 968cbbd8fc
commit 1705ffe2be
3 changed files with 72 additions and 77 deletions

View File

@@ -6,7 +6,7 @@
"dev": "deno run --allow-all mod.ts", "dev": "deno run --allow-all mod.ts",
"compile": "deno task compile:all", "compile": "deno task compile:all",
"compile:all": "bash scripts/compile-all.sh", "compile:all": "bash scripts/compile-all.sh",
"test": "deno run --allow-all test/test.ts && deno run --allow-all test/test.logger.ts", "test": "deno test --allow-all test/",
"test:watch": "deno test --allow-all --watch test/", "test:watch": "deno test --allow-all --watch test/",
"check": "deno check mod.ts", "check": "deno check mod.ts",
"fmt": "deno fmt", "fmt": "deno fmt",

View File

@@ -1,14 +1,14 @@
import { tap, expect } from 'npm:@git.zone/tstest@^1.0.0/tapbundle'; import { assertEquals, assert } from "jsr:@std/assert@^1.0.0";
import { Logger } from '../ts/logger.ts'; import { Logger } from '../ts/logger.ts';
// Create a Logger instance for testing // Create a Logger instance for testing
const logger = new Logger(); const logger = new Logger();
tap.test('should create a logger instance', async () => { Deno.test('should create a logger instance', () => {
expect(logger instanceof Logger).toBeTruthy(); assert(logger instanceof Logger);
}); });
tap.test('should log messages with different log levels', async () => { Deno.test('should log messages with different log levels', () => {
// We're not testing console output directly, just ensuring no errors // We're not testing console output directly, just ensuring no errors
logger.log('Regular log message'); logger.log('Regular log message');
logger.error('Error message'); logger.error('Error message');
@@ -16,104 +16,104 @@ tap.test('should log messages with different log levels', async () => {
logger.success('Success message'); logger.success('Success message');
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('should create a logbox with title, content, and end', async () => { Deno.test('should create a logbox with title, content, and end', () => {
// Just ensuring no errors occur // Just ensuring no errors occur
logger.logBoxTitle('Test Box', 40); logger.logBoxTitle('Test Box', 40);
logger.logBoxLine('This is a test line'); logger.logBoxLine('This is a test line');
logger.logBoxEnd(); logger.logBoxEnd();
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('should handle width persistence between logbox calls', async () => { Deno.test('should handle width persistence between logbox calls', () => {
logger.logBoxTitle('Width Test', 45); logger.logBoxTitle('Width Test', 45);
// These should use the width from the title // These should use the width from the title
logger.logBoxLine('Line 1'); logger.logBoxLine('Line 1');
logger.logBoxLine('Line 2'); logger.logBoxLine('Line 2');
logger.logBoxEnd(); logger.logBoxEnd();
let errorThrown = false; let errorThrown = false;
try { try {
// This should work fine after the reset in logBoxEnd // This should work fine after the reset in logBoxEnd
logger.logBoxTitle('New Box', 30); logger.logBoxTitle('New Box', 30);
logger.logBoxLine('New line'); logger.logBoxLine('New line');
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (_error) {
errorThrown = true; errorThrown = true;
} }
expect(errorThrown).toBeFalsy(); assertEquals(errorThrown, false);
}); });
tap.test('should use default width when no width is specified', async () => { Deno.test('should use default width when no width is specified', () => {
// This should automatically use the default width instead of throwing // This should automatically use the default width instead of throwing
let errorThrown = false; let errorThrown = false;
try { try {
logger.logBoxLine('This should use default width'); logger.logBoxLine('This should use default width');
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (_error) {
errorThrown = true; errorThrown = true;
} }
// Verify no error was thrown // Verify no error was thrown
expect(errorThrown).toBeFalsy(); assertEquals(errorThrown, false);
}); });
tap.test('should create a complete logbox in one call', async () => { Deno.test('should create a complete logbox in one call', () => {
// Just ensuring no errors occur // Just ensuring no errors occur
logger.logBox('Complete Box', [ logger.logBox('Complete Box', [
'Line 1', 'Line 1',
'Line 2', 'Line 2',
'Line 3' 'Line 3'
], 40); ], 40);
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('should handle content that exceeds box width', async () => { Deno.test('should handle content that exceeds box width', () => {
// Just ensuring no errors occur when content is too long // Just ensuring no errors occur when content is too long
logger.logBox('Truncation Test', [ logger.logBox('Truncation Test', [
'This line is way too long and should be truncated because it exceeds the available space' 'This line is way too long and should be truncated because it exceeds the available space'
], 30); ], 30);
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('should create dividers with custom characters', async () => { Deno.test('should create dividers with custom characters', () => {
// Just ensuring no errors occur // Just ensuring no errors occur
logger.logDivider(30); logger.logDivider(30);
logger.logDivider(20, '*'); logger.logDivider(20, '*');
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('should create divider with default width', async () => { Deno.test('should create divider with default width', () => {
// This should use the default width // This should use the default width
logger.logDivider(undefined, '-'); logger.logDivider(undefined, '-');
// Just assert that the test runs without errors // Just assert that the test runs without errors
expect(true).toBeTruthy(); assert(true);
}); });
tap.test('Logger Demo', async () => { Deno.test('Logger Demo', () => {
console.log('\n=== LOGGER DEMO ===\n'); console.log('\n=== LOGGER DEMO ===\n');
// Basic logging // Basic logging
logger.log('Regular log message'); logger.log('Regular log message');
logger.error('Error message'); logger.error('Error message');
logger.warn('Warning message'); logger.warn('Warning message');
logger.success('Success message'); logger.success('Success message');
// Logbox with title, content lines, and end // Logbox with title, content lines, and end
logger.logBoxTitle('Configuration Loaded', 50); logger.logBoxTitle('Configuration Loaded', 50);
logger.logBoxLine('SNMP Settings:'); logger.logBoxLine('SNMP Settings:');
@@ -121,40 +121,37 @@ tap.test('Logger Demo', async () => {
logger.logBoxLine(' Port: 161'); logger.logBoxLine(' Port: 161');
logger.logBoxLine(' Version: 1'); logger.logBoxLine(' Version: 1');
logger.logBoxEnd(); logger.logBoxEnd();
// Complete logbox in one call // Complete logbox in one call
logger.logBox('UPS Status', [ logger.logBox('UPS Status', [
'Power Status: onBattery', 'Power Status: onBattery',
'Battery Capacity: 75%', 'Battery Capacity: 75%',
'Runtime Remaining: 30 minutes' 'Runtime Remaining: 30 minutes'
], 45); ], 45);
// Logbox with content that's too long for the width // Logbox with content that's too long for the width
logger.logBox('Truncation Example', [ logger.logBox('Truncation Example', [
'This line is short enough to fit within the box width', 'This line is short enough to fit within the box width',
'This line is way too long and will be truncated because it exceeds the available space for content within the logbox' 'This line is way too long and will be truncated because it exceeds the available space for content within the logbox'
], 40); ], 40);
// Demonstrating logbox width being remembered // Demonstrating logbox width being remembered
logger.logBoxTitle('Width Persistence Example', 60); logger.logBoxTitle('Width Persistence Example', 60);
logger.logBoxLine('These lines use the width from the title'); logger.logBoxLine('These lines use the width from the title');
logger.logBoxLine('No need to specify the width again'); logger.logBoxLine('No need to specify the width again');
logger.logBoxEnd(); logger.logBoxEnd();
// Demonstrating default width // Demonstrating default width
console.log('\nDefault Width Example:'); console.log('\nDefault Width Example:');
logger.logBoxLine('This line uses the default width'); logger.logBoxLine('This line uses the default width');
logger.logBoxLine('Still using default width'); logger.logBoxLine('Still using default width');
logger.logBoxEnd(); logger.logBoxEnd();
// Divider example // Divider example
logger.log('\nDivider example:'); logger.log('\nDivider example:');
logger.logDivider(30); logger.logDivider(30);
logger.logDivider(30, '*'); logger.logDivider(30, '*');
logger.logDivider(undefined, '='); logger.logDivider(undefined, '=');
expect(true).toBeTruthy();
});
// Export the default tap object assert(true);
export default tap.start(); });

View File

@@ -1,52 +1,53 @@
import { tap, expect } from 'npm:@git.zone/tstest@^1.0.0/tapbundle'; import { assert, assertEquals, assertExists } from "jsr:@std/assert@^1.0.0";
import { NupstSnmp } from '../ts/snmp/manager.ts'; import { NupstSnmp } from '../ts/snmp/manager.ts';
import type { ISnmpConfig, IUpsStatus } from '../ts/snmp/types.ts'; import type { ISnmpConfig } from '../ts/snmp/types.ts';
import * as qenv from 'npm:@push.rocks/qenv'; import * as qenv from 'npm:@push.rocks/qenv@^6.0.0';
const testQenv = new qenv.Qenv('./', '.nogit/'); const testQenv = new qenv.Qenv('./', '.nogit/');
// Create an SNMP instance with debug enabled // Create an SNMP instance with debug enabled
const snmp = new NupstSnmp(true); const snmp = new NupstSnmp(true);
// Load the test configuration from .nogit/env.json // Load the test configuration from .nogit/env.json
const testConfigV1 = await testQenv.getEnvVarOnDemandAsObject('testConfigV1'); const testConfigV1 = await testQenv.getEnvVarOnDemandAsObject('testConfigV1');
const testConfigV3 = await testQenv.getEnvVarOnDemandAsObject('testConfigV3'); const testConfigV3 = await testQenv.getEnvVarOnDemandAsObject('testConfigV3');
tap.test('should log config', async () => { Deno.test('should log config', () => {
console.log(testConfigV1); console.log(testConfigV1);
assert(true);
}); });
// Test with real UPS using the configuration from .nogit/env.json // Test with real UPS using the configuration from .nogit/env.json
tap.test('Real UPS test v1', async () => { Deno.test('Real UPS test v1', async () => {
try { try {
console.log('Testing with real UPS configuration...'); console.log('Testing with real UPS configuration...');
// Extract the correct SNMP config from the test configuration // Extract the correct SNMP config from the test configuration
const snmpConfig = testConfigV1.snmp; const snmpConfig = testConfigV1.snmp as ISnmpConfig;
console.log('SNMP Config:'); console.log('SNMP Config:');
console.log(` Host: ${snmpConfig.host}:${snmpConfig.port}`); console.log(` Host: ${snmpConfig.host}:${snmpConfig.port}`);
console.log(` Version: SNMPv${snmpConfig.version}`); console.log(` Version: SNMPv${snmpConfig.version}`);
console.log(` UPS Model: ${snmpConfig.upsModel}`); console.log(` UPS Model: ${snmpConfig.upsModel}`);
// Use a short timeout for testing // Use a short timeout for testing
const testSnmpConfig = { const testSnmpConfig = {
...snmpConfig, ...snmpConfig,
timeout: Math.min(snmpConfig.timeout, 10000) // Use at most 10 seconds for testing timeout: Math.min(snmpConfig.timeout, 10000) // Use at most 10 seconds for testing
}; };
// Try to get the UPS status // Try to get the UPS status
const status = await snmp.getUpsStatus(testSnmpConfig); const status = await snmp.getUpsStatus(testSnmpConfig);
console.log('UPS Status:'); console.log('UPS Status:');
console.log(` Power Status: ${status.powerStatus}`); console.log(` Power Status: ${status.powerStatus}`);
console.log(` Battery Capacity: ${status.batteryCapacity}%`); console.log(` Battery Capacity: ${status.batteryCapacity}%`);
console.log(` Runtime Remaining: ${status.batteryRuntime} minutes`); console.log(` Runtime Remaining: ${status.batteryRuntime} minutes`);
// Just make sure we got valid data types back // Just make sure we got valid data types back
expect(status).toBeTruthy(); assertExists(status);
expect(['online', 'onBattery', 'unknown']).toContain(status.powerStatus); assert(['online', 'onBattery', 'unknown'].includes(status.powerStatus));
expect(typeof status.batteryCapacity).toEqual('number'); assertEquals(typeof status.batteryCapacity, 'number');
expect(typeof status.batteryRuntime).toEqual('number'); assertEquals(typeof status.batteryRuntime, 'number');
} catch (error) { } catch (error) {
console.log('Real UPS test failed:', error); console.log('Real UPS test failed:', error);
// Skip the test if we can't connect to the real UPS // Skip the test if we can't connect to the real UPS
@@ -54,42 +55,39 @@ tap.test('Real UPS test v1', async () => {
} }
}); });
tap.test('Real UPS test v3', async () => { Deno.test('Real UPS test v3', async () => {
try { try {
console.log('Testing with real UPS configuration...'); console.log('Testing with real UPS configuration...');
// Extract the correct SNMP config from the test configuration // Extract the correct SNMP config from the test configuration
const snmpConfig = testConfigV3.snmp; const snmpConfig = testConfigV3.snmp as ISnmpConfig;
console.log('SNMP Config:'); console.log('SNMP Config:');
console.log(` Host: ${snmpConfig.host}:${snmpConfig.port}`); console.log(` Host: ${snmpConfig.host}:${snmpConfig.port}`);
console.log(` Version: SNMPv${snmpConfig.version}`); console.log(` Version: SNMPv${snmpConfig.version}`);
console.log(` UPS Model: ${snmpConfig.upsModel}`); console.log(` UPS Model: ${snmpConfig.upsModel}`);
// Use a short timeout for testing // Use a short timeout for testing
const testSnmpConfig = { const testSnmpConfig = {
...snmpConfig, ...snmpConfig,
timeout: Math.min(snmpConfig.timeout, 10000) // Use at most 10 seconds for testing timeout: Math.min(snmpConfig.timeout, 10000) // Use at most 10 seconds for testing
}; };
// Try to get the UPS status // Try to get the UPS status
const status = await snmp.getUpsStatus(testSnmpConfig); const status = await snmp.getUpsStatus(testSnmpConfig);
console.log('UPS Status:'); console.log('UPS Status:');
console.log(` Power Status: ${status.powerStatus}`); console.log(` Power Status: ${status.powerStatus}`);
console.log(` Battery Capacity: ${status.batteryCapacity}%`); console.log(` Battery Capacity: ${status.batteryCapacity}%`);
console.log(` Runtime Remaining: ${status.batteryRuntime} minutes`); console.log(` Runtime Remaining: ${status.batteryRuntime} minutes`);
// Just make sure we got valid data types back // Just make sure we got valid data types back
expect(status).toBeTruthy(); assertExists(status);
expect(['online', 'onBattery', 'unknown']).toContain(status.powerStatus); assert(['online', 'onBattery', 'unknown'].includes(status.powerStatus));
expect(typeof status.batteryCapacity).toEqual('number'); assertEquals(typeof status.batteryCapacity, 'number');
expect(typeof status.batteryRuntime).toEqual('number'); assertEquals(typeof status.batteryRuntime, 'number');
} catch (error) { } catch (error) {
console.log('Real UPS test failed:', error); console.log('Real UPS test failed:', error);
// Skip the test if we can't connect to the real UPS // Skip the test if we can't connect to the real UPS
console.log('Skipping this test since the UPS might not be available'); console.log('Skipping this test since the UPS might not be available');
} }
}); });
// Export the default tap object
export default tap.start();