Setup
Install testing dependencies:Copy
npm install --save-dev jest @types/jest ts-jest
Copy
// jest.config.js
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
testTimeout: 60000,
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1'
}
};
Unit Tests
Test SDK initialization and configuration:Copy
import { In10ntClient, Instance, In10ntError } from '@in10nt/sdk';
describe('In10nt SDK', () => {
test('should initialize client', () => {
const client = new In10ntClient({
apiKey: 'test-key'
});
expect(client).toBeDefined();
expect(client.instances).toBeDefined();
expect(client.templates).toBeDefined();
expect(client.savedTemplates).toBeDefined();
expect(client.usage).toBeDefined();
});
test('should throw without API key', () => {
const original = process.env.IN10NT_API_KEY;
delete process.env.IN10NT_API_KEY;
expect(() => new In10ntClient()).toThrow(In10ntError);
process.env.IN10NT_API_KEY = original;
});
});
Integration Tests
Test actual API interactions:Copy
import { Instance, In10ntClient } from '@in10nt/sdk';
describe('Instance Management', () => {
let instance: Instance | null = null;
afterEach(async () => {
if (instance) {
try {
await instance.destroy();
} catch {
// already destroyed
}
instance = null;
}
});
test('should create instance (static)', async () => {
instance = await Instance.create({
name: 'test-static',
description: 'Static factory test'
});
expect(instance.instanceId).toBeDefined();
expect(instance.status).toBeDefined();
expect(instance.name).toBe('test-static');
});
test('should create instance (client)', async () => {
const client = new In10ntClient();
instance = await client.instances.create({
name: 'test-client',
description: 'Client path test'
});
expect(instance.instanceId).toBeDefined();
});
test('should connect to instance', async () => {
instance = await Instance.create({
name: 'test-connect',
description: 'Connect test'
});
const same = await Instance.connect(instance.instanceId);
expect(same.instanceId).toBe(instance.instanceId);
});
test('should list instances', async () => {
const instances = await Instance.list();
expect(Array.isArray(instances)).toBe(true);
});
test('should run task', async () => {
instance = await Instance.create({
name: 'test-run',
description: 'Run test'
});
const result = await instance.run('Echo "Hello World"', {
timeout: 60_000
});
expect(result.response).toBeDefined();
expect(result.tokensUsed).toBeGreaterThan(0);
});
test('should use namespaced methods', async () => {
instance = await Instance.create({
name: 'test-namespaces',
description: 'Namespace test'
});
// Tasks namespace
const tasks = await instance.tasks.list();
expect(Array.isArray(tasks)).toBe(true);
// Ports namespace
const ports = await instance.ports.list();
expect(Array.isArray(ports)).toBe(true);
// Files namespace
const changes = await instance.files.getChanges();
expect(changes).toBeDefined();
// Proxy URL (sync)
const url = instance.getProxyUrl(3000);
expect(url).toContain(instance.instanceId);
expect(url).toContain('3000');
});
test('should destroy instance', async () => {
instance = await Instance.create({
name: 'test-destroy',
description: 'Destroy test'
});
await instance.destroy();
instance = null;
});
});
Template Tests
Test container template creation:Copy
import { In10ntClient } from '@in10nt/sdk';
describe('Container Templates', () => {
const client = new In10ntClient();
let template: Awaited<ReturnType<typeof client.templates.create>> | null = null;
afterEach(async () => {
if (template) {
try {
await template.delete();
} catch {
// already deleted
}
template = null;
}
});
test('should create template', async () => {
template = await client.templates.create({
name: 'test-template',
image: 'python:3.11-slim',
registryType: 'dockerhub'
});
expect(template.templateId).toBeDefined();
expect(template.name).toBe('test-template');
});
test('should wait until ready', async () => {
template = await client.templates.create({
name: 'test-ready-template',
image: 'python:3.11-slim',
registryType: 'dockerhub'
});
await template.waitUntilReady({ timeout: 300_000 });
expect(template.status).toBe('ready');
}, 310_000);
test('should use template with instance', async () => {
template = await client.templates.create({
name: 'test-use-template',
image: 'python:3.11-slim',
registryType: 'dockerhub'
});
await template.waitUntilReady();
const instance = await client.instances.create({
name: 'test-with-template',
description: 'Template test',
containerTemplateId: template.templateId
});
expect(instance.instanceId).toBeDefined();
await instance.destroy();
}, 310_000);
});
Error Handling Tests
Test error scenarios:Copy
import { Instance, In10ntClient, In10ntError, TimeoutError } from '@in10nt/sdk';
describe('Error Handling', () => {
test('should handle invalid instance ID', async () => {
await expect(
Instance.connect('invalid-id')
).rejects.toThrow(In10ntError);
});
test('should handle missing required fields', async () => {
await expect(
Instance.create({ name: '', description: '' } as any)
).rejects.toThrow();
});
test('should handle timeout', async () => {
const instance = await Instance.create({
name: 'timeout-test',
description: 'Timeout test'
});
try {
await expect(
instance.run('Long task', {
timeout: 1000,
waitForHealth: false
})
).rejects.toThrow();
} finally {
await instance.destroy();
}
});
});
Usage Tests
Test usage tracking:Copy
import { In10ntClient, Instance } from '@in10nt/sdk';
describe('Usage Tracking', () => {
const client = new In10ntClient();
test('should get token usage', async () => {
const usage = await client.usage.getTokenUsage();
expect(usage.monthlyTokens).toBeGreaterThanOrEqual(0);
expect(usage.totalTokens).toBeGreaterThanOrEqual(0);
expect(usage.monthlyCost).toBeGreaterThanOrEqual(0);
expect(usage.totalCost).toBeGreaterThanOrEqual(0);
});
test('should track task usage', async () => {
const instance = await Instance.create({
name: 'usage-test',
description: 'Usage test'
});
try {
const result = await instance.run('Simple task');
expect(result.tokensUsed).toBeGreaterThan(0);
} finally {
await instance.destroy();
}
});
});
Background Mode Tests
Copy
import { Instance } from '@in10nt/sdk';
describe('Background Mode', () => {
test('should return taskId in background mode', async () => {
const instance = await Instance.create({
name: 'bg-test',
description: 'Background test'
});
try {
const result = await instance.run('Build something', {
background: true
});
expect(result.taskId).toBeDefined();
expect(result.status).toBe('processing');
// Poll for completion
const final = await instance.tasks.poll(result.taskId!);
expect(final.response).toBeDefined();
} finally {
await instance.destroy();
}
});
});
Test Utilities
Create reusable test utilities:Copy
// test-utils.ts
import { Instance, In10ntClient } from '@in10nt/sdk';
import type { ContainerTemplate } from '@in10nt/sdk';
export class TestHelper {
private client: In10ntClient;
private instances: Instance[] = [];
private templates: ContainerTemplate[] = [];
constructor() {
this.client = new In10ntClient();
}
async createInstance(name: string, description: string): Promise<Instance> {
const instance = await this.client.instances.create({ name, description });
this.instances.push(instance);
return instance;
}
async createTemplate(name: string, image: string): Promise<ContainerTemplate> {
const template = await this.client.templates.create({
name,
image,
registryType: 'dockerhub'
});
this.templates.push(template);
return template;
}
async cleanup(): Promise<void> {
for (const instance of this.instances) {
try { await instance.destroy(); } catch {}
}
for (const template of this.templates) {
try { await template.delete(); } catch {}
}
this.instances = [];
this.templates = [];
}
}
// Usage in tests
describe('With Test Helper', () => {
const helper = new TestHelper();
afterEach(async () => {
await helper.cleanup();
});
test('should create and cleanup automatically', async () => {
const instance = await helper.createInstance('test', 'Test instance');
expect(instance.instanceId).toBeDefined();
// Cleanup happens automatically in afterEach
});
});
Run Tests
Copy
# Run all tests
npm test
# Run specific test file
npm test -- instances.test.ts
# Run with coverage
npm test -- --coverage
# Run in watch mode
npm test -- --watch
CI/CD Integration
Copy
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run tests
env:
IN10NT_API_KEY: ${{ secrets.TEST_API_KEY }}
run: npm test

