From b8fbfa2d4eb7ba50149ebf1bb5756e56b3972eca Mon Sep 17 00:00:00 2001 From: armorbreak001 Date: Tue, 14 Apr 2026 07:15:31 +0800 Subject: [PATCH] test: improve test coverage for Context and SpecificationFile models --- test/unit/models/Context.test.ts | 59 +++++++++++ test/unit/models/SpecificationFile.test.ts | 110 +++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 test/unit/models/Context.test.ts create mode 100644 test/unit/models/SpecificationFile.test.ts diff --git a/test/unit/models/Context.test.ts b/test/unit/models/Context.test.ts new file mode 100644 index 000000000..1b3016960 --- /dev/null +++ b/test/unit/models/Context.test.ts @@ -0,0 +1,59 @@ +import { expect } from 'chai'; +import * as os from 'os'; + +import { isContextFileEmpty } from '../../../src/domains/models/Context'; +import { + ContextNotFoundError, + MissingCurrentContextError, + ContextAlreadyExistsError, + ContextFileEmptyError, +} from '../../../src/errors/context-error'; + +describe('Context', () => { + describe('isContextFileEmpty', () => { + it('should return true for empty store object', async () => { + const result = await isContextFileEmpty({ store: {} }); + expect(result).to.be.true; + }); + + it('should return false when store has entries', async () => { + const result = await isContextFileEmpty({ store: { home: '/path/to/file' } }); + expect(result).to.be.false; + }); + + it('should return false when current is set even with empty store', async () => { + const result = await isContextFileEmpty({ store: {}, current: 'home' } as any); + expect(result).to.be.false; + }); + + it('should return false for non-empty store with multiple entries', async () => { + const result = await isContextFileEmpty({ + store: { home: '/path', work: '/work' }, + }); + expect(result).to.be.false; + }); + }); + + describe('Error classes', () => { + it('ContextNotFoundError should contain context name in message', () => { + const err = new ContextNotFoundError('my-context'); + expect(err.message).to.contain('my-context'); + }); + + it('MissingCurrentContextError should have descriptive message', () => { + const err = new MissingCurrentContextError(); + expect(err.message).to.be.a('string'); + expect(err.message.length).to.be.greaterThan(0); + }); + + it('ContextAlreadyExistsError should contain context name', () => { + const err = new ContextAlreadyExistsError('dup-context', '/path/to/file'); + expect(err.message).to.contain('dup-context'); + }); + + it('ContextFileEmptyError should contain file path', () => { + const err = new ContextFileEmptyError('/path/to/.asyncapi-cli'); + expect(err.message).to.contain('.asyncapi-cli'); + }); + }); +}); diff --git a/test/unit/models/SpecificationFile.test.ts b/test/unit/models/SpecificationFile.test.ts new file mode 100644 index 000000000..75577f451 --- /dev/null +++ b/test/unit/models/SpecificationFile.test.ts @@ -0,0 +1,110 @@ +import { expect } from 'chai'; +import { Specification } from '../../../src/domains/models/SpecificationFile'; + +describe('Specification', () => { + describe('constructor and basic methods', () => { + it('should create specification from string', () => { + const spec = new Specification('{"asyncapi": "2.6.0"}'); + expect(spec.text()).to.equal('{"asyncapi": "2.6.0"}'); + }); + + it('should store file path when provided', () => { + const spec = new Specification('test', { filepath: '/path/to/file.yaml' }); + expect(spec.getFilePath()).to.equal('/path/to/file.yaml'); + expect(spec.getKind()).to.equal('file'); + }); + + it('should store URL when provided', () => { + const spec = new Specification('test', { fileURL: 'https://example.com/api.yaml' }); + expect(spec.getFileURL()).to.equal('https://example.com/api.yaml'); + expect(spec.getKind()).to.equal('url'); + }); + + it('should return undefined for file path when not set', () => { + const spec = new Specification('test'); + expect(spec.getFilePath()).to.be.undefined; + }); + + it('should return undefined for URL when not set', () => { + const spec = new Specification('test'); + expect(spec.getFileURL()).to.be.undefined; + }); + + it('should return undefined for kind when no options provided', () => { + const spec = new Specification('test'); + expect(spec.getKind()).to.be.undefined; + }); + }); + + describe('toJson', () => { + it('should parse JSON specification', () => { + const jsonSpec = JSON.stringify({ + asyncapi: '2.6.0', + info: { title: 'Test', version: '1.0.0' }, + channels: {}, + }); + const spec = new Specification(jsonSpec); + const result = spec.toJson(); + expect(result.asyncapi).to.equal('2.6.0'); + expect(result.info.title).to.equal('Test'); + }); + + it('should parse YAML specification', () => { + const yamlSpec = `asyncapi: 2.6.0 +info: + title: Test + version: "1.0.0" +channels: {}`; + const spec = new Specification(yamlSpec); + const result = spec.toJson(); + expect(result.asyncapi).to.equal('2.6.0'); + expect(result.info.title).to.equal('Test'); + }); + }); + + describe('isAsyncAPI3', () => { + it('should return true for AsyncAPI 3.x', () => { + const spec = new Specification('{"asyncapi": "3.0.0"}'); + expect(spec.isAsyncAPI3()).to.be.true; + }); + + it('should return true for AsyncAPI 3.1.0', () => { + const spec = new Specification('{"asyncapi": "3.1.0"}'); + expect(spec.isAsyncAPI3()).to.be.true; + }); + + it('should return false for AsyncAPI 2.x', () => { + const spec = new Specification('{"asyncapi": "2.6.0"}'); + expect(spec.isAsyncAPI3()).to.be.false; + }); + }); + + describe('getSource', () => { + it('should return file path for file kind', () => { + const spec = new Specification('test', { filepath: '/path/to/file.yaml' }); + expect(spec.getSource()).to.equal('/path/to/file.yaml'); + }); + + it('should return URL for url kind', () => { + const spec = new Specification('test', { fileURL: 'https://example.com/api.yaml' }); + expect(spec.getSource()).to.equal('https://example.com/api.yaml'); + }); + + it('should return undefined when neither is set', () => { + const spec = new Specification('test'); + expect(spec.getSource()).to.be.undefined; + }); + }); + + describe('toSourceString', () => { + it('should return File prefix for file kind', () => { + const spec = new Specification('test', { filepath: '/path/to/file.yaml' }); + expect(spec.toSourceString()).to.equal('File /path/to/file.yaml'); + }); + + it('should return URL prefix for url kind', () => { + const spec = new Specification('test', { fileURL: 'https://example.com/api.yaml' }); + expect(spec.toSourceString()).to.equal('URL https://example.com/api.yaml'); + }); + }); +});