Files
prettier-plugin-openapi/test/plugin.test.ts
2025-09-25 01:36:23 +00:00

210 lines
7.9 KiB
TypeScript

import { describe, it, expect } from 'bun:test';
import plugin from '../src/index';
import * as fs from 'fs';
import * as path from 'path';
describe('Prettier OpenAPI Plugin', () => {
it('should have correct plugin structure', () => {
expect(plugin).toBeDefined();
expect(plugin.languages).toBeDefined();
expect(plugin.parsers).toBeDefined();
expect(plugin.printers).toBeDefined();
});
it('should support OpenAPI JSON files', () => {
const jsonLanguage = plugin.languages?.find(lang => lang.name === 'openapi-json');
expect(jsonLanguage).toBeDefined();
expect(jsonLanguage?.extensions).toContain('.openapi.json');
expect(jsonLanguage?.extensions).toContain('.swagger.json');
});
it('should support OpenAPI YAML files', () => {
const yamlLanguage = plugin.languages?.find(lang => lang.name === 'openapi-yaml');
expect(yamlLanguage).toBeDefined();
expect(yamlLanguage?.extensions).toContain('.openapi.yaml');
expect(yamlLanguage?.extensions).toContain('.openapi.yml');
expect(yamlLanguage?.extensions).toContain('.swagger.yaml');
expect(yamlLanguage?.extensions).toContain('.swagger.yml');
});
it('should parse JSON correctly', () => {
const jsonParser = plugin.parsers?.['openapi-json-parser'];
expect(jsonParser).toBeDefined();
const testJson = '{"openapi": "3.0.0", "info": {"title": "Test API", "version": "1.0.0"}}';
// @ts-ignore We are mocking things here
const result = jsonParser?.parse(testJson, {});
expect(result).toBeDefined();
expect(result?.type).toBe('openapi-json');
expect(result?.content).toBeDefined();
expect(result?.content.openapi).toBe('3.0.0');
});
it('should parse YAML correctly', () => {
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
expect(yamlParser).toBeDefined();
const testYaml = 'openapi: 3.0.0\ninfo:\n title: Test API\n version: 1.0.0';
// @ts-ignore We are mocking things here
const result = yamlParser?.parse(testYaml, {});
expect(result).toBeDefined();
expect(result?.type).toBe('openapi-yaml');
expect(result?.content).toBeDefined();
expect(result?.content.openapi).toBe('3.0.0');
});
it('should format JSON with proper sorting', () => {
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
expect(jsonPrinter).toBeDefined();
const testData = {
content: {
info: { title: 'Test', version: '1.0.0' },
openapi: '3.0.0',
paths: { '/test': { get: {} } }
}
};
// @ts-ignore We are mocking things here
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
expect(result).toBeDefined();
expect(result).toContain('"openapi"');
expect(result).toContain('"info"');
expect(result).toContain('"paths"');
});
it('should format YAML with proper sorting', () => {
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
expect(yamlPrinter).toBeDefined();
const testData = {
content: {
info: { title: 'Test', version: '1.0.0' },
openapi: '3.0.0',
paths: { '/test': { get: {} } }
}
};
// @ts-ignore We are mocking things here
const result = yamlPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
expect(result).toBeDefined();
expect(result).toContain('openapi:');
expect(result).toContain('info:');
expect(result).toContain('paths:');
});
});
describe('Key Ordering Tests', () => {
describe('Top-level key ordering', () => {
it('should sort OpenAPI 3.0+ keys correctly', () => {
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
expect(jsonPrinter).toBeDefined();
const testData = {
content: {
paths: { '/test': { get: {} } },
components: { schemas: {} },
info: { title: 'Test API', version: '1.0.0' },
openapi: '3.0.0',
security: [],
tags: [],
externalDocs: { url: 'https://example.com' }
}
};
// @ts-ignore We are mocking things here
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
expect(result).toBeDefined();
if (!result) {
throw new Error('Result is undefined');
}
// Check that keys appear in the correct order
const openapiIndex = result.toString().indexOf('"openapi"');
const infoIndex = result.toString().indexOf('"info"');
const pathsIndex = result.toString().indexOf('"paths"');
const componentsIndex = result.toString().indexOf('"components"');
const securityIndex = result.toString().indexOf('"security"');
const tagsIndex = result.toString().indexOf('"tags"');
const externalDocsIndex = result.toString().indexOf('"externalDocs"');
expect(openapiIndex).toBeLessThan(infoIndex);
expect(infoIndex).toBeLessThan(pathsIndex);
expect(pathsIndex).toBeLessThan(componentsIndex);
expect(componentsIndex).toBeLessThan(securityIndex);
expect(securityIndex).toBeLessThan(tagsIndex);
expect(tagsIndex).toBeLessThan(externalDocsIndex);
});
it('should sort Swagger 2.0 keys correctly', () => {
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
expect(jsonPrinter).toBeDefined();
const testData = {
content: {
paths: { '/test': { get: {} } },
definitions: { User: { type: 'object' } },
info: { title: 'Test API', version: '1.0.0' },
swagger: '2.0',
host: 'api.example.com',
basePath: '/v1',
schemes: ['https'],
consumes: ['application/json'],
produces: ['application/json'],
parameters: {},
responses: {},
securityDefinitions: {},
security: [],
tags: [],
externalDocs: { url: 'https://example.com' }
}
};
// @ts-ignore We are mocking things here
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
expect(result).toBeDefined();
if (!result) {
throw new Error('Result is undefined');
}
// Check that keys appear in the correct order
const swaggerIndex = result.toString().indexOf('"swagger"');
const infoIndex = result.toString().indexOf('"info"');
const hostIndex = result.toString().indexOf('"host"');
const basePathIndex = result.toString().indexOf('"basePath"');
const schemesIndex = result.toString().indexOf('"schemes"');
const consumesIndex = result.toString().indexOf('"consumes"');
const producesIndex = result.toString().indexOf('"produces"');
const pathsIndex = result.toString().indexOf('"paths"');
const definitionsIndex = result.toString().indexOf('"definitions"');
const parametersIndex = result.toString().indexOf('"parameters"');
const responsesIndex = result.toString().indexOf('"responses"');
const securityDefinitionsIndex = result.toString().indexOf('"securityDefinitions"');
const securityIndex = result.toString().indexOf('"security"');
const tagsIndex = result.toString().indexOf('"tags"');
const externalDocsIndex = result.toString().indexOf('"externalDocs"');
expect(swaggerIndex).toBeLessThan(infoIndex);
expect(infoIndex).toBeLessThan(hostIndex);
expect(hostIndex).toBeLessThan(basePathIndex);
expect(basePathIndex).toBeLessThan(schemesIndex);
expect(schemesIndex).toBeLessThan(consumesIndex);
expect(consumesIndex).toBeLessThan(producesIndex);
expect(producesIndex).toBeLessThan(pathsIndex);
expect(pathsIndex).toBeLessThan(definitionsIndex);
expect(definitionsIndex).toBeLessThan(parametersIndex);
expect(parametersIndex).toBeLessThan(responsesIndex);
expect(responsesIndex).toBeLessThan(securityDefinitionsIndex);
expect(securityDefinitionsIndex).toBeLessThan(securityIndex);
expect(securityIndex).toBeLessThan(tagsIndex);
expect(tagsIndex).toBeLessThan(externalDocsIndex);
});
});
});