-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(messagePact): Add messagePactWith so that the default options ar…
…e available for message pact users too
- Loading branch information
1 parent
540dc3c
commit a8c1943
Showing
10 changed files
with
326 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,3 @@ | ||
import * as pact from '@pact-foundation/pact'; | ||
import { LogLevel, PactOptions } from '@pact-foundation/pact/dsl/options'; | ||
import * as path from 'path'; | ||
|
||
export type JestPactOptions = PactOptions & { | ||
timeout?: number; | ||
logDir?: string; | ||
logFileName?: string; | ||
}; | ||
|
||
export type JestProvidedPactFn = (provider: pact.Pact) => void; | ||
|
||
const logHint = (options: JestPactOptions) => | ||
options.port ? `-port-${options.port}` : ''; | ||
|
||
const applyDefaults = (options: JestPactOptions) => ({ | ||
log: path.resolve( | ||
options.logDir ? options.logDir : path.join(process.cwd(), 'pact', 'logs'), | ||
options.logFileName | ||
? options.logFileName | ||
: `${options.consumer}-${ | ||
options.provider | ||
}-mockserver-interaction${logHint(options)}.log`, | ||
), | ||
dir: path.resolve(process.cwd(), 'pact/pacts'), | ||
spec: 2, | ||
logLevel: 'warn' as LogLevel, | ||
pactfileWriteMode: 'update' as pact.PactfileWriteMode, | ||
...options, | ||
}); | ||
|
||
const setupProvider = (options: JestPactOptions) => { | ||
const pactMock: pact.Pact = new pact.Pact(options); | ||
|
||
beforeAll(() => pactMock.setup()); | ||
afterAll(() => pactMock.finalize()); | ||
afterEach(() => pactMock.verify()); | ||
|
||
return pactMock; | ||
}; | ||
|
||
// This should be moved to pact-js, probably | ||
export const getProviderBaseUrl = (provider: pact.Pact) => | ||
provider.mockService | ||
? provider.mockService.baseUrl | ||
: `http://${provider.opts.host}:${provider.opts.port}`; | ||
|
||
const jestPactWrapper = ( | ||
options: JestPactOptions, | ||
tests: JestProvidedPactFn, | ||
): void => { | ||
const pactTestTimeout = options.timeout || 30000; | ||
|
||
describe(`with ${pactTestTimeout} ms timeout for Pact`, () => { | ||
let originalTimeout: number; | ||
|
||
beforeAll(() => { | ||
// Jest's default timeout is 5000, and jest doesn't provide a way of | ||
// asking what the current timeout is. In Jest 24 and 25, Jasmine was probably | ||
// the test runner, so we can ask Jasmine if it is there. In later versions of | ||
// Jest (eg 26 and up), Jasmine may not be defined. | ||
// See https://github.com/pact-foundation/jest-pact/issues/197 for discussion | ||
// | ||
// For now, we just assume that 5000 was the original timeout. | ||
// The impact is likely to be small, as `jest.setTimeout()` only works for the | ||
// current test file | ||
originalTimeout = global.jasmine | ||
? global.jasmine.DEFAULT_TIMEOUT_INTERVAL | ||
: 5000; | ||
jest.setTimeout(pactTestTimeout); | ||
}); | ||
|
||
afterAll(() => { | ||
jest.setTimeout(originalTimeout); | ||
}); | ||
|
||
tests(setupProvider(applyDefaults(options))); | ||
}); | ||
}; | ||
|
||
const describeString = (options: JestPactOptions) => | ||
`Pact between ${options.consumer} and ${options.provider}`; | ||
|
||
type PactWithFn = (options: JestPactOptions, tests: JestProvidedPactFn) => void; | ||
interface PactWith { | ||
(options: JestPactOptions, tests: JestProvidedPactFn): void; | ||
only: PactWithFn; | ||
skip: PactWithFn; | ||
} | ||
|
||
const describePactWith = (describeFn: jest.Describe): PactWithFn => ( | ||
options: JestPactOptions, | ||
tests: JestProvidedPactFn, | ||
) => describeFn(describeString(options), () => jestPactWrapper(options, tests)); | ||
|
||
const extend = (pactWithfn: PactWithFn) => { | ||
const ret = pactWithfn as PactWith; | ||
ret.only = describePactWith(describe.only); | ||
ret.skip = describePactWith(describe.skip); | ||
return ret; | ||
}; | ||
|
||
export const pactWith = extend(describePactWith(describe)); | ||
|
||
export const xpactWith = pactWith.skip; | ||
export const fpactWith = pactWith.only; | ||
export * from './messagePactWith'; | ||
export * from './types'; | ||
export * from './pactWith'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { PactfileWriteMode } from '@pact-foundation/pact'; | ||
import { LogLevel } from '@pact-foundation/pact/dsl/options'; | ||
import * as path from 'path'; | ||
import { JestMessageConsumerOptions, JestPactOptions } from '../types'; | ||
|
||
const logHint = (options: JestPactOptions) => | ||
options.port ? `-port-${options.port}` : ''; | ||
|
||
const applyCommonDefaults = ( | ||
options: JestPactOptions | JestMessageConsumerOptions, | ||
) => ({ | ||
log: path.resolve( | ||
options.logDir ? options.logDir : path.join(process.cwd(), 'pact', 'logs'), | ||
options.logFileName | ||
? options.logFileName | ||
: `${options.consumer}-${ | ||
options.provider | ||
}-mockserver-interaction${logHint(options)}.log`, | ||
), | ||
dir: path.resolve(process.cwd(), 'pact/pacts'), | ||
logLevel: 'warn' as LogLevel, | ||
pactfileWriteMode: 'update' as PactfileWriteMode, | ||
}); | ||
|
||
export const applyPactOptionDefaults = ( | ||
options: JestPactOptions, | ||
): JestPactOptions => ({ | ||
...applyCommonDefaults(options), | ||
spec: 2, | ||
...options, | ||
}); | ||
|
||
export const applyMessagePactOptionDefaults = ( | ||
options: JestMessageConsumerOptions, | ||
): JestMessageConsumerOptions => ({ | ||
...applyCommonDefaults(options), | ||
spec: 3, | ||
...options, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { | ||
MessageConsumerOptions, | ||
PactOptions, | ||
} from '@pact-foundation/pact/dsl/options'; | ||
import { ConsumerOptions, WrapperFn, WrapperWithOnlyAndSkip } from './types'; | ||
|
||
const describeString = (options: PactOptions | MessageConsumerOptions) => | ||
`Pact between ${options.consumer} and ${options.provider}`; | ||
|
||
const describePactWith = < | ||
O extends ConsumerOptions, | ||
P, | ||
W extends WrapperFn<O, P> | ||
>( | ||
describeFn: jest.Describe, | ||
wrapper: W, | ||
) => (options: O, tests: P) => | ||
describeFn(describeString(options), () => wrapper(options, tests)); | ||
|
||
export const extendPactWith = < | ||
O extends ConsumerOptions, | ||
P, | ||
W extends WrapperFn<O, P> | ||
>( | ||
wrapper: W, | ||
) => { | ||
const ret = describePactWith<O, P, W>( | ||
describe, | ||
wrapper, | ||
) as WrapperWithOnlyAndSkip<O, P>; | ||
ret.only = describePactWith<O, P, W>(describe.only, wrapper); | ||
ret.skip = describePactWith<O, P, W>(describe.skip, wrapper); | ||
return ret; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export interface ConsumerOptions { | ||
consumer: string; | ||
provider: string; | ||
} | ||
|
||
export type WrapperFn<O extends ConsumerOptions, P> = (o: O, p: P) => void; | ||
|
||
export interface WrapperWithOnlyAndSkip<O extends ConsumerOptions, P> | ||
extends WrapperFn<O, P> { | ||
only: WrapperFn<O, P>; | ||
skip: WrapperFn<O, P>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
interface TimeoutOption { | ||
timeout?: number; | ||
} | ||
|
||
export const withTimeout = ( | ||
options: TimeoutOption, | ||
tests: () => void, | ||
): void => { | ||
const pactTestTimeout = options.timeout || 30000; | ||
|
||
describe(`with ${pactTestTimeout} ms timeout for Pact`, () => { | ||
let originalTimeout: number; | ||
|
||
beforeAll(() => { | ||
// Jest's default timeout is 5000, and jest doesn't provide a way of | ||
// asking what the current timeout is. In Jest 24 and 25, Jasmine was probably | ||
// the test runner, so we can ask Jasmine if it is there. In later versions of | ||
// Jest (eg 26 and up), Jasmine may not be defined. | ||
// See https://github.com/pact-foundation/jest-pact/issues/197 for discussion | ||
// | ||
// For now, we just assume that 5000 was the original timeout. | ||
// The impact is likely to be small, as `jest.setTimeout()` only works for the | ||
// current test file | ||
originalTimeout = global.jasmine | ||
? global.jasmine.DEFAULT_TIMEOUT_INTERVAL | ||
: 5000; | ||
jest.setTimeout(pactTestTimeout); | ||
}); | ||
|
||
afterAll(() => { | ||
jest.setTimeout(originalTimeout); | ||
}); | ||
|
||
tests(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { MessageConsumerPact } from '@pact-foundation/pact'; | ||
|
||
import { applyMessagePactOptionDefaults } from './internal/config'; | ||
import { WrapperFn } from './internal/types'; | ||
import { withTimeout } from './internal/withTimeout'; | ||
|
||
import { extendPactWith } from './internal/scaffold'; | ||
import { JestMessageConsumerOptions, JestProvidedMessagePactFn } from './types'; | ||
|
||
const setupMessageProvider = ( | ||
options: JestMessageConsumerOptions, | ||
): MessageConsumerPact => new MessageConsumerPact(options); | ||
|
||
const jestMessagePactWrapper = ( | ||
options: JestMessageConsumerOptions, | ||
tests: JestProvidedMessagePactFn, | ||
): void => { | ||
withTimeout(options, () => { | ||
tests(setupMessageProvider(applyMessagePactOptionDefaults(options))); | ||
}); | ||
}; | ||
|
||
export const messagePactWith = extendPactWith< | ||
JestMessageConsumerOptions, | ||
JestProvidedMessagePactFn, | ||
WrapperFn<JestMessageConsumerOptions, JestProvidedMessagePactFn> | ||
>(jestMessagePactWrapper); | ||
|
||
export const xmessagePactWith = messagePactWith.skip; | ||
export const fmessagePactWith = messagePactWith.only; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { Pact } from '@pact-foundation/pact'; | ||
import { applyPactOptionDefaults } from './internal/config'; | ||
import { WrapperFn } from './internal/types'; | ||
import { withTimeout } from './internal/withTimeout'; | ||
|
||
import { extendPactWith } from './internal/scaffold'; | ||
import { JestPactOptions, JestProvidedPactFn } from './types'; | ||
|
||
const setupProvider = (options: JestPactOptions): Pact => { | ||
const pactMock: Pact = new Pact(options); | ||
|
||
beforeAll(() => pactMock.setup()); | ||
afterAll(() => pactMock.finalize()); | ||
afterEach(() => pactMock.verify()); | ||
|
||
return pactMock; | ||
}; | ||
|
||
// This should be moved to pact-js, probably | ||
export const getProviderBaseUrl = (provider: Pact) => | ||
provider.mockService | ||
? provider.mockService.baseUrl | ||
: `http://${provider.opts.host}:${provider.opts.port}`; | ||
|
||
const pactWithWrapper = ( | ||
options: JestPactOptions, | ||
tests: JestProvidedPactFn, | ||
): void => { | ||
withTimeout(options, () => { | ||
tests(setupProvider(applyPactOptionDefaults(options))); | ||
}); | ||
}; | ||
|
||
export const pactWith = extendPactWith< | ||
JestPactOptions, | ||
JestProvidedPactFn, | ||
WrapperFn<JestPactOptions, JestProvidedPactFn> | ||
>(pactWithWrapper); | ||
|
||
export const xpactWith = pactWith.skip; | ||
export const fpactWith = pactWith.only; |
Oops, something went wrong.