UNPKG

specmatic

Version:
177 lines (141 loc) 6.23 kB
import path from 'path'; import { ChildProcess, spawn } from 'child_process'; import { mock as jestMock, mockReset } from 'jest-mock-extended'; import { Readable } from 'stream'; import { copyFileSync, mkdirSync, existsSync } from 'fs'; import fs from 'fs'; import express from 'express'; import * as specmatic from '../..'; import { specmaticCoreJarName } from '../../config'; jest.mock('child_process'); const SPECMATIC_JAR_PATH = path.resolve(__dirname, '..', '..', '..', specmaticCoreJarName); const CONTRACT_FILE_PATH = './contracts'; const HOST = 'localhost'; const PORT = 8000; const javaProcessMock = jestMock<ChildProcess>(); const readableMock = jestMock<Readable>(); javaProcessMock.stdout = readableMock; javaProcessMock.stderr = readableMock; beforeEach(() => { jest.resetAllMocks(); }); test('runs the contract tests', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test(HOST, PORT, CONTRACT_FILE_PATH)).resolves.toBeTruthy(); expect(spawn.mock.calls[0][0]).toBe(`java`); expect(spawn.mock.calls[0][1]).toEqual([`-jar`, path.resolve(SPECMATIC_JAR_PATH), 'test', path.resolve(CONTRACT_FILE_PATH), '--junitReportDir=dist/test-report', `--host=${HOST}`, `--port=${PORT}`]); }); test('takes additional pass through arguments', async () => { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test(HOST, PORT, CONTRACT_FILE_PATH, ['P1', 'P2'])).resolves.toBeTruthy(); expect(spawn.mock.calls[0][0]).toBe(`java`); expect(spawn.mock.calls[0][1]).toEqual([`-jar`, path.resolve(SPECMATIC_JAR_PATH), 'test', path.resolve(CONTRACT_FILE_PATH), '--junitReportDir=dist/test-report', `--host=${HOST}`, `--port=${PORT}`, 'P1', 'P2']); }); test('additional pass through arguments can be string or number', async () => { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test(HOST, PORT, CONTRACT_FILE_PATH, ['P1', 123])).resolves.toBeTruthy(); expect(spawn.mock.calls[0][0]).toBe(`java`); expect(spawn.mock.calls[0][1]).toEqual([`-jar`, path.resolve(SPECMATIC_JAR_PATH), 'test', path.resolve(CONTRACT_FILE_PATH), '--junitReportDir=dist/test-report', `--host=${HOST}`, `--port=${PORT}`, 'P1', '123']); }); test('runs the contract tests with host and port optional', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test()).resolves.toBeTruthy(); expect(spawn.mock.calls[0][0]).toBe(`java`); expect(spawn.mock.calls[0][1]).toEqual([`-jar`, path.resolve(SPECMATIC_JAR_PATH), 'test', '--junitReportDir=dist/test-report']); }); test('runs the contract tests with contracts path optional', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test(HOST, PORT)).resolves.toBeTruthy(); expect(spawn.mock.calls[0][0]).toBe(`java`); expect(spawn.mock.calls[0][1]).toEqual([`-jar`, path.resolve(SPECMATIC_JAR_PATH), 'test', '--junitReportDir=dist/test-report', `--host=${HOST}`, `--port=${PORT}`]); }); test('runs the contract tests and returns a summary', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test()).resolves.toStrictEqual({ total: 5, success: 3, failure: 2, }); }); test('runs the contract tests and returns a summary with skipped tests count included', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFileWithName('sample-junit-result-skipped.xml'); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test()).resolves.toStrictEqual({ total: 3, success: 2, failure: 1, }); }); test('runs the contract tests and get summary when there is just one test', async function () { spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFileWithName('sample-junit-result-single.xml'); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.test()).resolves.toStrictEqual({ total: 1, success: 1, failure: 0, }); }); test('invocation makes sure previous junit report if any is deleted', async function () { const spy = jest.spyOn(fs, 'rmSync'); spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFileWithName('sample-junit-result-single.xml'); javaProcessMock.on.mock.calls[0][1]() }, 0); await specmatic.test(); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(path.resolve('dist/test-report'), { force: true, recursive: true }); }); test('passes an property indicating api endpoint based on host and port supplied when api coverage is enabled', async () => { var app = express(); app.get('/', () => {}); spawn.mockReturnValue(javaProcessMock); setTimeout(() => { copyReportFile(); javaProcessMock.on.mock.calls[0][1]() }, 0); await expect(specmatic.testWithApiCoverage(app, HOST, PORT)).resolves.toBeTruthy(); expect(spawn.mock.calls[0][1][0]).toMatch(/endpointsAPI="http:\/\/.+?:[0-9]+?"/); }); function copyReportFile() { copyReportFileWithName('sample-junit-result-multiple.xml'); } function copyReportFileWithName(fileName: string) { const destDir = path.resolve('dist/test-report'); if (!existsSync(destDir)) { mkdirSync(destDir, { recursive: true }); } const srcPath = path.resolve('test-resources', fileName); const destPath = path.resolve(destDir, 'TEST-junit-jupiter.xml'); copyFileSync(srcPath, destPath); }