yarn-spinner-loader/tests/plugins/esbuild.test.ts

151 lines
4.4 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { yarnSpinnerPlugin } from '../../src/plugins/esbuild';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
describe('yarnSpinnerPlugin (esbuild)', () => {
// Fixtures are in tests/fixtures/, not tests/plugins/fixtures/
const projectPath = resolve(__dirname, '../fixtures/simple/.yarnproject');
it('should return an esbuild plugin with correct name', () => {
const plugin = yarnSpinnerPlugin();
expect(plugin.name).toBe('yarn-spinner-loader');
});
it('should have a setup function', () => {
const plugin = yarnSpinnerPlugin();
expect(plugin.setup).toBeDefined();
expect(typeof plugin.setup).toBe('function');
});
it('should register onLoad handler for .yarnproject files', () => {
const plugin = yarnSpinnerPlugin();
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
// Store the callback for testing
(mockBuild as any)._onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
expect(mockBuild.onLoad).toHaveBeenCalledWith(
{ filter: /\.yarnproject$/ },
expect.any(Function),
);
});
it('should load .yarnproject files and return correct content', async () => {
const plugin = yarnSpinnerPlugin();
let onLoadCallback: Function | undefined;
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
// Ensure callback was registered
expect(onLoadCallback).toBeDefined();
// Simulate esbuild calling the callback
const args = { path: projectPath };
const result = await (onLoadCallback as any)(args);
expect(result).toBeDefined();
expect(result.contents).toContain('export default');
expect(result.contents).toContain('project');
expect(result.contents).toContain('program');
expect(result.loader).toBe('js');
});
it('should handle errors by returning error object', async () => {
const plugin = yarnSpinnerPlugin();
let onLoadCallback: Function | undefined;
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
// Simulate esbuild calling the callback with non-existent file
const args = { path: 'nonexistent/.yarnproject' };
const result = await (onLoadCallback as any)(args);
expect(result.errors).toBeDefined();
expect(result.errors.length).toBeGreaterThan(0);
expect(result.errors[0].text).toBeDefined();
expect(typeof result.errors[0].text).toBe('string');
});
it('should accept loadOptions and pass them to loadYarnProject', async () => {
const plugin = yarnSpinnerPlugin({
loadOptions: {
baseDir: resolve(__dirname, 'fixtures/simple'),
},
});
let onLoadCallback: Function | undefined;
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
const args = { path: projectPath };
const result = await (onLoadCallback as any)(args);
expect(result.contents).toContain('export default');
expect(result.loader).toBe('js');
});
it('should correctly serialize the result as JSON with proper formatting', async () => {
const plugin = yarnSpinnerPlugin();
let onLoadCallback: Function | undefined;
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
const args = { path: projectPath };
const result = await (onLoadCallback as any)(args);
// The contents should be properly formatted JavaScript code
expect(result.contents).toMatch(/export default {[\s\S]*};/);
expect(result.loader).toBe('js');
});
it('should handle non-Error objects in error handling', async () => {
const plugin = yarnSpinnerPlugin();
let onLoadCallback: Function | undefined;
const mockBuild = {
onLoad: vi.fn((_options, callback) => {
onLoadCallback = callback;
}),
};
plugin.setup(mockBuild as any);
const args = { path: 'nonexistent/.yarnproject' };
const result = await (onLoadCallback as any)(args);
expect(result.errors[0].text).toBeDefined();
expect(typeof result.errors[0].text).toBe('string');
});
});