Skip to content

Commit ae40af0

Browse files
committed
feat: implement environment utilities tests for Node compatibility
1 parent 13e6a5d commit ae40af0

2 files changed

Lines changed: 64 additions & 1 deletion

File tree

packages/core/src/logger.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { LoggerConfig, LogLevel } from '@objectstack/spec/system';
22
import type { Logger } from '@objectstack/spec/contracts';
3+
import { isNode } from './utils/env.js';
34

45
/**
56
* Universal Logger Implementation
@@ -25,7 +26,7 @@ export class ObjectLogger implements Logger {
2526

2627
constructor(config: Partial<LoggerConfig> = {}) {
2728
// Detect runtime environment
28-
this.isNode = typeof process !== 'undefined' && process.versions?.node !== undefined;
29+
this.isNode = isNode;
2930

3031
// Set defaults
3132
this.config = {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { describe, it, expect, vi, afterEach } from 'vitest';
2+
import * as envUtils from './env';
3+
4+
describe('Environment Utilities', () => {
5+
6+
// Save original process
7+
const originalProcess = globalThis.process;
8+
9+
afterEach(() => {
10+
// Restore process after each test
11+
globalThis.process = originalProcess;
12+
vi.restoreAllMocks();
13+
});
14+
15+
describe('isNode', () => {
16+
it('should detect Node environment', () => {
17+
// Since we are running in Vitest (Node), this should be true
18+
expect(envUtils.isNode).toBe(true);
19+
});
20+
});
21+
22+
describe('getEnv', () => {
23+
it('should retrieve environment variable in Node', () => {
24+
process.env.TEST_VAR = 'test_value';
25+
expect(envUtils.getEnv('TEST_VAR')).toBe('test_value');
26+
delete process.env.TEST_VAR;
27+
});
28+
29+
it('should return default value if variable not found', () => {
30+
expect(envUtils.getEnv('NON_EXISTENT_VAR', 'default')).toBe('default');
31+
});
32+
33+
it('should access globalThis.process.env if process is not available directly', () => {
34+
// This is tricky to test in Node because 'process' is globally available.
35+
// We can't easily delete global.process in strict mode or without breaking tooling.
36+
// But we can verify it works via globalThis
37+
38+
// @ts-ignore
39+
globalThis.process.env.TEST_GLOBAL_VAR = 'global_value';
40+
expect(envUtils.getEnv('TEST_GLOBAL_VAR')).toBe('global_value');
41+
// @ts-ignore
42+
delete globalThis.process.env.TEST_GLOBAL_VAR;
43+
});
44+
});
45+
46+
describe('getMemoryUsage', () => {
47+
it('should return memory usage in Node', () => {
48+
const usage = envUtils.getMemoryUsage();
49+
expect(usage).toHaveProperty('heapUsed');
50+
expect(usage).toHaveProperty('heapTotal');
51+
expect(usage.heapUsed).toBeGreaterThan(0);
52+
});
53+
});
54+
55+
describe('safeExit', () => {
56+
it('should call process.exit in Node', () => {
57+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {}) as any);
58+
envUtils.safeExit(1);
59+
expect(exitSpy).toHaveBeenCalledWith(1);
60+
});
61+
});
62+
});

0 commit comments

Comments
 (0)