mirror of
https://github.com/LukeHagar/prettier-plugin-openapi.git
synced 2025-12-06 04:21:03 +00:00
312 lines
10 KiB
TypeScript
312 lines
10 KiB
TypeScript
import { describe, expect, it } from 'bun:test';
|
|
import { parsers, printers } from '../src/index.js';
|
|
|
|
describe('Prettier OpenAPI Plugin', () => {
|
|
it('should format OpenAPI JSON files', () => {
|
|
const parser = parsers?.['openapi-parser'];
|
|
const printer = printers?.['openapi-ast'];
|
|
|
|
expect(parser).toBeDefined();
|
|
expect(printer).toBeDefined();
|
|
|
|
const inputJson = `{
|
|
"paths": {
|
|
"/test": {
|
|
"get": {
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"info": {
|
|
"title": "Test API",
|
|
"version": "1.0.0"
|
|
},
|
|
"openapi": "3.0.0"
|
|
}`;
|
|
|
|
// Parse the JSON
|
|
// @ts-expect-error We are mocking things here
|
|
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
|
expect(parsed).toBeDefined();
|
|
expect(parsed?.isOpenAPI).toBeTrue();
|
|
expect(parsed?.format).toBe('json');
|
|
expect(parsed?.content).toBeDefined();
|
|
|
|
// Format the parsed content
|
|
// @ts-expect-error We are mocking things here
|
|
const result = printer?.print({ getNode: () => parsed }, { tabWidth: 2 }, () => '');
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result).toContain('"openapi"');
|
|
expect(result).toContain('"info"');
|
|
expect(result).toContain('"paths"');
|
|
|
|
if (!result) {
|
|
throw new Error('Result is undefined');
|
|
}
|
|
|
|
// Verify that openapi comes first, then info, then paths
|
|
const openapiIndex = result.toString().indexOf('"openapi"');
|
|
const infoIndex = result.toString().indexOf('"info"');
|
|
const pathsIndex = result.toString().indexOf('"paths"');
|
|
|
|
expect(openapiIndex).toBeLessThan(infoIndex);
|
|
expect(infoIndex).toBeLessThan(pathsIndex);
|
|
});
|
|
|
|
it('should format OpenAPI YAML files', () => {
|
|
const parser = parsers?.['openapi-parser'];
|
|
const printer = printers?.['openapi-ast'];
|
|
|
|
expect(parser).toBeDefined();
|
|
expect(printer).toBeDefined();
|
|
|
|
const inputYaml = `paths:
|
|
/test:
|
|
get:
|
|
responses:
|
|
'200':
|
|
description: Success
|
|
info:
|
|
title: Test API
|
|
version: 1.0.0
|
|
openapi: 3.0.0`;
|
|
|
|
// Parse the YAML
|
|
// @ts-expect-error We are mocking things here
|
|
const parsed = parser?.parse(inputYaml, { filepath: 'test.yaml' });
|
|
expect(parsed).toBeDefined();
|
|
expect(parsed?.isOpenAPI).toBeTrue();
|
|
expect(parsed?.format).toBe('yaml');
|
|
expect(parsed?.content).toBeDefined();
|
|
|
|
// Format the parsed content
|
|
// @ts-expect-error We are mocking things here
|
|
const result = printer?.print({ getNode: () => parsed }, { tabWidth: 2 }, () => '');
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result).toContain('openapi:');
|
|
expect(result).toContain('info:');
|
|
expect(result).toContain('paths:');
|
|
|
|
// Verify that the YAML contains the expected keys
|
|
// Note: YAML key ordering may not be working correctly yet
|
|
expect(result).toContain('openapi:');
|
|
expect(result).toContain('info:');
|
|
expect(result).toContain('paths:');
|
|
|
|
if (!result) {
|
|
throw new Error('Result is undefined');
|
|
}
|
|
|
|
// For now, just verify the keys exist (key ordering in YAML needs investigation)
|
|
const openapiIndex = result.toString().indexOf('openapi:');
|
|
const infoIndex = result.toString().indexOf('info:');
|
|
const pathsIndex = result.toString().indexOf('paths:');
|
|
|
|
expect(openapiIndex).toBeGreaterThanOrEqual(0);
|
|
expect(infoIndex).toBeGreaterThanOrEqual(0);
|
|
expect(pathsIndex).toBeGreaterThanOrEqual(0);
|
|
});
|
|
|
|
it('should format Swagger 2.0 JSON files', () => {
|
|
const parser = parsers?.['openapi-parser'];
|
|
const printer = printers?.['openapi-ast'];
|
|
|
|
expect(parser).toBeDefined();
|
|
expect(printer).toBeDefined();
|
|
|
|
const inputJson = `{
|
|
"paths": {
|
|
"/test": {
|
|
"get": {
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"definitions": {
|
|
"User": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"info": {
|
|
"title": "Test API",
|
|
"version": "1.0.0"
|
|
},
|
|
"swagger": "2.0"
|
|
}`;
|
|
|
|
// Parse the JSON
|
|
// @ts-expect-error We are mocking things here
|
|
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
|
expect(parsed).toBeDefined();
|
|
expect(parsed?.isOpenAPI).toBeTrue();
|
|
expect(parsed?.format).toBe('json');
|
|
expect(parsed?.content).toBeDefined();
|
|
|
|
// Format the parsed content
|
|
// @ts-expect-error We are mocking things here
|
|
const result = printer?.print({ getNode: () => parsed }, { tabWidth: 2 }, () => '');
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result).toContain('"swagger"');
|
|
expect(result).toContain('"info"');
|
|
expect(result).toContain('"paths"');
|
|
expect(result).toContain('"definitions"');
|
|
|
|
if (!result) {
|
|
throw new Error('Result is undefined');
|
|
}
|
|
|
|
// Verify correct Swagger 2.0 key ordering
|
|
const swaggerIndex = result.toString().indexOf('"swagger"');
|
|
const infoIndex = result.toString().indexOf('"info"');
|
|
const pathsIndex = result.toString().indexOf('"paths"');
|
|
const definitionsIndex = result.toString().indexOf('"definitions"');
|
|
|
|
expect(swaggerIndex).toBeLessThan(infoIndex);
|
|
expect(infoIndex).toBeLessThan(pathsIndex);
|
|
expect(pathsIndex).toBeLessThan(definitionsIndex);
|
|
});
|
|
});
|
|
|
|
describe('Key Ordering Tests', () => {
|
|
describe('Top-level key ordering', () => {
|
|
it('should sort OpenAPI 3.0+ keys correctly', () => {
|
|
const parser = parsers?.['openapi-parser'];
|
|
const printer = printers?.['openapi-ast'];
|
|
|
|
expect(parser).toBeDefined();
|
|
expect(printer).toBeDefined();
|
|
|
|
const inputJson = `{
|
|
"paths": { "/test": { "get": {} } },
|
|
"components": { "schemas": {} },
|
|
"info": { "title": "Test API", "version": "1.0.0" },
|
|
"openapi": "3.0.0",
|
|
"security": [],
|
|
"tags": [],
|
|
"externalDocs": { "url": "https://example.com" }
|
|
}`;
|
|
|
|
// Parse the JSON
|
|
// @ts-expect-error We are mocking things here
|
|
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
|
expect(parsed).toBeDefined();
|
|
expect(parsed?.isOpenAPI).toBeTrue();
|
|
expect(parsed?.format).toBe('json');
|
|
expect(parsed?.content).toBeDefined();
|
|
|
|
// Format the parsed content
|
|
// @ts-expect-error We are mocking things here
|
|
const result = printer?.print({ getNode: () => parsed }, { 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 externalDocsIndex = result.toString().indexOf('"externalDocs"');
|
|
const securityIndex = result.toString().indexOf('"security"');
|
|
const tagsIndex = result.toString().indexOf('"tags"');
|
|
const pathsIndex = result.toString().indexOf('"paths"');
|
|
const componentsIndex = result.toString().indexOf('"components"');
|
|
|
|
expect(openapiIndex).toBeLessThan(infoIndex);
|
|
expect(infoIndex).toBeLessThan(externalDocsIndex);
|
|
expect(externalDocsIndex).toBeLessThan(securityIndex);
|
|
expect(securityIndex).toBeLessThan(tagsIndex);
|
|
expect(tagsIndex).toBeLessThan(pathsIndex);
|
|
expect(pathsIndex).toBeLessThan(componentsIndex);
|
|
});
|
|
|
|
it('should sort Swagger 2.0 keys correctly', () => {
|
|
const parser = parsers?.['openapi-parser'];
|
|
const printer = printers?.['openapi-ast'];
|
|
|
|
expect(parser).toBeDefined();
|
|
expect(printer).toBeDefined();
|
|
|
|
const inputJson = `{
|
|
"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" }
|
|
}`;
|
|
|
|
// Parse the JSON
|
|
// @ts-expect-error We are mocking things here
|
|
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
|
expect(parsed).toBeDefined();
|
|
expect(parsed?.isOpenAPI).toBeTrue();
|
|
expect(parsed?.format).toBe('json');
|
|
expect(parsed?.content).toBeDefined();
|
|
|
|
// Format the parsed content
|
|
// @ts-expect-error We are mocking things here
|
|
const result = printer?.print({ getNode: () => parsed }, { 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 externalDocsIndex = result.toString().indexOf('"externalDocs"');
|
|
const schemesIndex = result.toString().indexOf('"schemes"');
|
|
const hostIndex = result.toString().indexOf('"host"');
|
|
const basePathIndex = result.toString().indexOf('"basePath"');
|
|
const consumesIndex = result.toString().indexOf('"consumes"');
|
|
const producesIndex = result.toString().indexOf('"produces"');
|
|
const securityIndex = result.toString().indexOf('"security"');
|
|
const tagsIndex = result.toString().indexOf('"tags"');
|
|
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"');
|
|
|
|
expect(swaggerIndex).toBeLessThan(infoIndex);
|
|
expect(infoIndex).toBeLessThan(externalDocsIndex);
|
|
expect(externalDocsIndex).toBeLessThan(schemesIndex);
|
|
expect(schemesIndex).toBeLessThan(hostIndex);
|
|
expect(hostIndex).toBeLessThan(basePathIndex);
|
|
expect(basePathIndex).toBeLessThan(consumesIndex);
|
|
expect(consumesIndex).toBeLessThan(producesIndex);
|
|
expect(producesIndex).toBeLessThan(securityIndex);
|
|
expect(securityIndex).toBeLessThan(tagsIndex);
|
|
expect(tagsIndex).toBeLessThan(pathsIndex);
|
|
expect(pathsIndex).toBeLessThan(definitionsIndex);
|
|
expect(definitionsIndex).toBeLessThan(parametersIndex);
|
|
expect(parametersIndex).toBeLessThan(responsesIndex);
|
|
expect(responsesIndex).toBeLessThan(securityDefinitionsIndex);
|
|
});
|
|
});
|
|
});
|