UNPKG

@pact-foundation/pact

Version:
725 lines 29.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const MatchersV3 = __importStar(require("./matchers")); describe('V3 Matchers', () => { it('compiles with nested examples from issue 1054', () => { const f = { a: 'working example' }; MatchersV3.like(f); MatchersV3.like({ ...f }); MatchersV3.like(Object.freeze(f)); const r = { id: 'some guid', foo: { a: 'example' } }; MatchersV3.like(r); MatchersV3.like({ ...r }); MatchersV3.like(Object.freeze(f)); MatchersV3.reify(r); }); describe('#like', () => { it('returns a JSON representation of a like matcher', () => { const result = MatchersV3.like({ a: 'b', }); expect(result).toEqual({ 'pact:matcher:type': 'type', value: { a: 'b', }, }); }); }); describe('#eachKeylike', () => { it('returns a JSON representation of an eachKeyLike matcher', () => { const result = MatchersV3.eachKeyLike('004', { id: '004', }); expect(result).toEqual({ 'pact:matcher:type': 'values', value: { '004': { id: '004', }, }, }); }); }); describe('#eachLike', () => { describe('with no min', () => { it('returns a JSON representation of an eachLike matcher', () => { const result = MatchersV3.eachLike({ a: 'b', }); expect(result).toEqual({ min: 1, 'pact:matcher:type': 'type', value: [ { a: 'b', }, ], }); }); }); describe('with min', () => { it('returns a JSON representation of an eachLike matcher', () => { const result = MatchersV3.eachLike({ a: 'b', }, 3); expect(result).toEqual({ min: 3, 'pact:matcher:type': 'type', value: [ { a: 'b', }, { a: 'b', }, { a: 'b', }, ], }); }); }); }); describe('#atLeastOneLike', () => { describe('with no examples', () => { it('returns a JSON representation of an atLeastOneLike matcher', () => { const result = MatchersV3.atLeastOneLike({ a: 'b', }); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 1, value: [ { a: 'b', }, ], }); }); }); describe('when provided examples', () => { it('returns a JSON representation of an atLeastOneLike matcher with the correct number of examples', () => { const result = MatchersV3.atLeastOneLike({ a: 'b', }, 4); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 1, value: [{ a: 'b' }, { a: 'b' }, { a: 'b' }, { a: 'b' }], }); }); }); }); describe('#atLeastLike', () => { describe('with no examples', () => { it('returns a JSON representation of an atLeastLike matcher', () => { const result = MatchersV3.atLeastLike({ a: 'b', }, 2); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 2, value: [{ a: 'b' }, { a: 'b' }], }); }); }); describe('when provided examples', () => { it('returns a JSON representation of an atLeastLike matcher with the correct number of examples', () => { const result = MatchersV3.atLeastLike({ a: 'b', }, 2, 4); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 2, value: [{ a: 'b' }, { a: 'b' }, { a: 'b' }, { a: 'b' }], }); }); }); it('throws an error if the number of examples is less than the minimum', () => { expect(() => MatchersV3.atLeastLike({ a: 'b' }, 4, 2)).toThrow('atLeastLike has a minimum of 4 but 2 elements were requested. Make sure the count is greater than or equal to the min.'); }); }); describe('#atMostLike', () => { describe('with no examples', () => { it('returns a JSON representation of an atMostLike matcher', () => { const result = MatchersV3.atMostLike({ a: 'b', }, 2); expect(result).toEqual({ 'pact:matcher:type': 'type', max: 2, value: [{ a: 'b' }], }); }); }); describe('when provided examples', () => { it('returns a JSON representation of an atMostLike matcher with the correct number of examples', () => { const result = MatchersV3.atMostLike({ a: 'b', }, 4, 4); expect(result).toEqual({ 'pact:matcher:type': 'type', max: 4, value: [{ a: 'b' }, { a: 'b' }, { a: 'b' }, { a: 'b' }], }); }); }); it('throws an error if the number of examples is more than the maximum', () => { expect(() => MatchersV3.atMostLike({ a: 'b' }, 2, 4)).toThrow('atMostLike has a maximum of 2 but 4 elements where requested. Make sure the count is less than or equal to the max.'); }); }); describe('#constrainedArrayLike', () => { describe('with no examples', () => { it('returns a JSON representation of an constrainedArrayLike matcher', () => { const result = MatchersV3.constrainedArrayLike({ a: 'b', }, 2, 4); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 2, max: 4, value: [{ a: 'b' }, { a: 'b' }], }); }); }); describe('when provided examples', () => { it('returns a JSON representation of an constrainedArrayLike matcher with the correct number of examples', () => { const result = MatchersV3.constrainedArrayLike({ a: 'b', }, 2, 4, 3); expect(result).toEqual({ 'pact:matcher:type': 'type', min: 2, max: 4, value: [{ a: 'b' }, { a: 'b' }, { a: 'b' }], }); }); }); it('throws an error if the number of examples is less than the minimum', () => { expect(() => MatchersV3.constrainedArrayLike({ a: 'b' }, 4, 6, 2)).toThrow('constrainedArrayLike has a minimum of 4 but 2 elements where requested. Make sure the count is greater than or equal to the min.'); }); it('throws an error if the number of examples is more than the maximum', () => { expect(() => MatchersV3.constrainedArrayLike({ a: 'b' }, 4, 6, 8)).toThrow('constrainedArrayLike has a maximum of 6 but 8 elements where requested. Make sure the count is less than or equal to the max.'); }); }); describe('#integer', () => { it('returns a JSON representation of an integer matcher', () => { const result = MatchersV3.integer(100); expect(result).toEqual({ 'pact:matcher:type': 'integer', value: 100, }); }); describe('when the example is zero', () => { it('returns a JSON representation of an integer matcher', () => { const result = MatchersV3.integer(0); expect(result).toEqual({ 'pact:matcher:type': 'integer', value: 0, }); }); }); describe('when no example is given', () => { it('also includes a random integer generator', () => { const result = MatchersV3.integer(); expect(result).toEqual({ 'pact:matcher:type': 'integer', 'pact:generator:type': 'RandomInt', value: 101, }); }); }); }); describe('#decimal', () => { it('returns a JSON representation of an decimal matcher', () => { const result = MatchersV3.decimal(100.3); expect(result).toEqual({ 'pact:matcher:type': 'decimal', value: 100.3, }); }); describe('when the example is zero', () => { it('returns a JSON representation of an integer matcher', () => { const result = MatchersV3.decimal(0.0); expect(result).toEqual({ 'pact:matcher:type': 'decimal', value: 0.0, }); }); }); describe('when no example is given', () => { it('also includes a random decimal generator', () => { const result = MatchersV3.decimal(); expect(result).toEqual({ 'pact:matcher:type': 'decimal', 'pact:generator:type': 'RandomDecimal', value: 12.34, }); }); }); }); describe('#number', () => { it('returns a JSON representation of an number matcher', () => { const result = MatchersV3.number(100.3); expect(result).toEqual({ 'pact:matcher:type': 'number', value: 100.3, }); }); describe('when no example is given', () => { it('also includes a random integer generator', () => { const result = MatchersV3.number(); expect(result).toEqual({ 'pact:matcher:type': 'number', 'pact:generator:type': 'RandomInt', value: 1234, }); }); }); }); describe('#boolean', () => { it('returns a JSON representation of a like matcher', () => { const result = MatchersV3.boolean(true); expect(result).toEqual({ 'pact:matcher:type': 'type', value: true, }); }); }); describe('#string', () => { it('returns a JSON representation of a like matcher', () => { const result = MatchersV3.string('true'); expect(result).toEqual({ 'pact:matcher:type': 'type', value: 'true', }); }); }); describe('#regex', () => { it('returns a JSON representation of a regex matcher', () => { const result = MatchersV3.regex('\\d+', '1234'); expect(result).toEqual({ 'pact:matcher:type': 'regex', regex: '\\d+', value: '1234', }); }); describe('when given a regular expression', () => { it('returns a JSON representation of a regex matcher', () => { const result = MatchersV3.regex(/\d+/, '1234'); expect(result).toEqual({ 'pact:matcher:type': 'regex', regex: '\\d+', value: '1234', }); }); }); }); describe('#equal', () => { it('returns a JSON representation of an equality matcher', () => { const result = MatchersV3.equal('true'); expect(result).toEqual({ 'pact:matcher:type': 'equality', value: 'true', }); }); }); describe('#datetime', () => { describe('when an example is given', () => { it('returns a JSON representation of a datetime matcher', () => { const result = MatchersV3.datetime("yyyy-MM-dd'T'HH:mm:ss.SSSX", '2016-02-11T09:46:56.023Z'); expect(result).toEqual({ 'pact:matcher:type': 'timestamp', format: "yyyy-MM-dd'T'HH:mm:ss.SSSX", value: '2016-02-11T09:46:56.023Z', }); }); }); describe('when example is an empty string', () => { it('throws an error', () => { expect(() => MatchersV3.datetime("yyyy-MM-dd'T'HH:mm:ss.SSSX", '')).toThrow('you must provide an example datetime'); }); }); }); describe('#time', () => { describe('when an example is given', () => { it('returns a JSON representation of a time matcher', () => { const result = MatchersV3.time('HH:mm:ss', '09:46:56'); expect(result).toEqual({ 'pact:matcher:type': 'time', format: 'HH:mm:ss', value: '09:46:56', }); }); }); describe('when example is an empty string', () => { it('throws an error', () => { expect(() => MatchersV3.time('HH:mm:ss', '')).toThrow('you must provide an example time'); }); }); }); describe('#date', () => { describe('when an example is given', () => { it('returns a JSON representation of a date matcher', () => { const result = MatchersV3.date('yyyy-MM-dd', '2016-02-11'); expect(result).toEqual({ 'pact:matcher:type': 'date', format: 'yyyy-MM-dd', value: '2016-02-11', }); }); }); describe('when example is an empty string', () => { it('throws an error', () => { expect(() => MatchersV3.date('yyyy-MM-dd', '')).toThrow('you must provide an example date'); }); }); }); describe('#includes', () => { it('returns a JSON representation of an include matcher', () => { const result = MatchersV3.includes('true'); expect(result).toEqual({ 'pact:matcher:type': 'include', value: 'true', }); }); }); describe('#nullValue', () => { it('returns a JSON representation of an null matcher', () => { const result = MatchersV3.nullValue(); expect(result).toEqual({ 'pact:matcher:type': 'null', value: null, }); }); }); describe('#url', () => { it('returns a JSON representation of a regex matcher for the URL', () => { const result = MatchersV3.url2('http://localhost:8080', [ 'users', '1234', 'posts', 'latest', ]); expect(result).toEqual({ 'pact:matcher:type': 'regex', regex: '.*(\\/users\\/1234\\/posts\\/latest)$', value: 'http://localhost:8080/users/1234/posts/latest', }); }); describe('when provided with a regex matcher', () => { it('returns a JSON representation of a regex matcher for the URL', () => { const result = MatchersV3.url2('http://localhost:8080', [ 'users', MatchersV3.regex('\\d+', '1234'), 'posts', 'latest', ]); expect(result).toEqual({ 'pact:matcher:type': 'regex', regex: '.*(\\/users\\/\\d+\\/posts\\/latest)$', value: 'http://localhost:8080/users/1234/posts/latest', }); }); }); describe('when provided with a regular expression', () => { it('returns a JSON representation of a regex matcher for the URL', () => { const result = MatchersV3.url2('http://localhost:8080', [ 'users', /\d+/, 'posts', 'latest', ]); expect(result).toMatchObject({ 'pact:matcher:type': 'regex', regex: '.*(\\/users\\/\\d+\\/posts\\/latest)$', }); expect(result.value).toMatch(/\/users\/\d+\/posts\/latest$/); }); }); describe('when no base URL is provided', () => { it('returns regex matcher and a MockServerURL generator', () => { const result = MatchersV3.url([ 'users', MatchersV3.regex('\\d+', '1234'), 'posts', 'latest', ]); expect(result).toEqual({ 'pact:matcher:type': 'regex', 'pact:generator:type': 'MockServerURL', regex: '.*(\\/users\\/\\d+\\/posts\\/latest)$', value: 'http://localhost:8080/users/1234/posts/latest', example: 'http://localhost:8080/users/1234/posts/latest', }); }); }); }); describe('#uuid', () => { it('returns a JSON representation of an regex matcher for UUIDs', () => { const result = MatchersV3.uuid('ba4bd1bc-5556-11eb-9286-d71bc5b507be'); expect(result).toEqual({ 'pact:matcher:type': 'regex', regex: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', value: 'ba4bd1bc-5556-11eb-9286-d71bc5b507be', }); }); it('throws an exception if the example value does not match the UUID regex', () => { expect(() => MatchersV3.uuid('not a uuid')).toThrow(); expect(() => MatchersV3.uuid('ba4bd1bc-5556-11eb-9286')).toThrow(); expect(() => MatchersV3.uuid('ba4bd1bc-5556-11eb-9286-d71bc5b507be-1234')).toThrow(); }); it('if no example is provided, it sets up a generator', () => { const result = MatchersV3.uuid(); expect(result).toEqual({ 'pact:matcher:type': 'regex', 'pact:generator:type': 'Uuid', regex: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', value: 'e2490de5-5bd3-43d5-b7c4-526e33f71304', }); }); }); describe('#reify', () => { describe('when given an object with no matchers', () => { const object = { value: 'data', more: 'strings', an: ['array'], someObject: { withData: true, withNumber: 1, }, }; it('returns just that object', () => { expect(MatchersV3.reify(object)).toEqual(object); }); }); describe('when given an object with null values', () => { const object = { some: 'data', more: null, an: [null], someObject: { withData: true, withNumber: 1, andNull: null, }, }; it('returns just that object', () => { expect(MatchersV3.reify(object)).toEqual(object); }); }); describe('when given an object with some matchers', () => { const someMatchers = { some: MatchersV3.like('data'), more: 'strings', an: ['array'], another: MatchersV3.eachLike('this'), null: MatchersV3.nullValue(), someObject: { withData: MatchersV3.like(true), withTerm: MatchersV3.regex('this|that', 'this'), withNumber: 1, withAnotherNumber: MatchersV3.like(2), }, }; const expected = { some: 'data', more: 'strings', an: ['array'], another: ['this'], null: null, someObject: { withData: true, withTerm: 'this', withNumber: 1, withAnotherNumber: 2, }, }; it('returns without matching guff', () => { expect(MatchersV3.reify(someMatchers)).toEqual(expected); }); }); describe('when given a simple matcher', () => { it('removes all matching guff', () => { const expected = 'myawesomeword'; const matcher = MatchersV3.regex('\\w+', 'myawesomeword'); expect(MatchersV3.isMatcher(matcher)).toBe(true); expect(MatchersV3.reify(matcher)).toEqual(expected); }); }); describe('when given a complex nested object with matchers', () => { it('removes all matching guff', () => { const o = MatchersV3.like({ stringMatcher: { awesomeSetting: MatchersV3.like('a string'), }, anotherStringMatcher: { nestedSetting: { anotherStringMatcherSubSetting: MatchersV3.like(true), }, anotherSetting: MatchersV3.regex('this|that', 'this'), }, arrayMatcher: { lotsOfValueregex: MatchersV3.atLeastOneLike('useful', 3), }, arrayOfMatcherregex: { lotsOfValueregex: MatchersV3.atLeastOneLike({ foo: 'bar', baz: MatchersV3.like('bat'), }, 3), }, }); const expected = { stringMatcher: { awesomeSetting: 'a string', }, anotherStringMatcher: { nestedSetting: { anotherStringMatcherSubSetting: true, }, anotherSetting: 'this', }, arrayMatcher: { lotsOfValueregex: ['useful', 'useful', 'useful'], }, arrayOfMatcherregex: { lotsOfValueregex: [ { baz: 'bat', foo: 'bar', }, { baz: 'bat', foo: 'bar', }, { baz: 'bat', foo: 'bar', }, ], }, }; expect(MatchersV3.reify(o)).toEqual(expected); }); }); describe('when given a matcher and field named "value"', () => { it('should not be isMatcher"', () => { const resultMatcher = MatchersV3.like({ a: 'b', c: MatchersV3.atLeastOneLike({ value: '1', a: 'b', aa: 'bb' }), }); const result = MatchersV3.reify(resultMatcher); expect(result).toEqual({ a: 'b', c: [{ value: '1', a: 'b', aa: 'bb' }], }); }); }); }); describe('matchStatus', () => { it('creates a StatusCodeMatcher for an HTTPResponseStatusClass', () => { const matcher = MatchersV3.matchStatus(200, MatchersV3.HTTPResponseStatusClass.Success); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'success', value: 200, }); }); it('creates a StatusCodeMatcher for a list of status codes', () => { const matcher = MatchersV3.matchStatus(200, [200, 201]); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: [200, 201], value: 200, }); }); it('creates a StatusCodeMatcher for ClientError class', () => { const matcher = MatchersV3.matchStatus(400, MatchersV3.HTTPResponseStatusClass.ClientError); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'clientError', value: 400, }); }); it('creates a StatusCodeMatcher for ServerError class', () => { const matcher = MatchersV3.matchStatus(500, MatchersV3.HTTPResponseStatusClass.ServerError); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'serverError', value: 500, }); }); it('creates a StatusCodeMatcher for Redirect class', () => { const matcher = MatchersV3.matchStatus(301, MatchersV3.HTTPResponseStatusClass.Redirect); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'redirect', value: 301, }); }); it('creates a StatusCodeMatcher for Information class', () => { const matcher = MatchersV3.matchStatus(100, MatchersV3.HTTPResponseStatusClass.Information); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'information', value: 100, }); }); it('creates a StatusCodeMatcher for NonError class', () => { const matcher = MatchersV3.matchStatus(200, MatchersV3.HTTPResponseStatusClass.NonError); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'nonError', value: 200, }); }); it('creates a StatusCodeMatcher for Error class', () => { const matcher = MatchersV3.matchStatus(400, MatchersV3.HTTPResponseStatusClass.Error); expect(matcher).toEqual({ 'pact:matcher:type': 'statusCode', status: 'error', value: 400, }); }); it('reify returns the example value from a StatusCodeMatcher', () => { const matcher = MatchersV3.matchStatus(201, MatchersV3.HTTPResponseStatusClass.Success); expect(MatchersV3.reify(matcher)).toEqual(201); }); }); }); //# sourceMappingURL=matchers.spec.js.map