Files
cypress/scripts/unit/github-actions/semantic-pull-request/validate-pr-title-spec.js
2023-03-30 20:16:10 -05:00

173 lines
4.4 KiB
JavaScript

const { expect } = require('chai')
const sinon = require('sinon')
const { validatePrTitle, _validateTitle } = require('../../../github-actions/semantic-pull-request/validate-pr-title')
describe('semantic-pull-request/validate-pr-title', () => {
context('validatePrTitle', () => {
const restParameters = {
owner: 'cypress-io',
repo: 'cypress',
pull_number: 52,
}
describe('more than one commit', () => {
it('only validates pr title', async () => {
const commits = [
{ parents: ['dev'] },
{ parents: ['dev'] },
]
const myAsyncIterable = {
async *[Symbol.asyncIterator] () {
yield { data: commits }
},
}
const github = {
paginate: {
iterator: sinon.stub().returns(myAsyncIterable),
},
rest: {
pulls: {},
},
}
const prTitle = 'fix: issue with server'
const semanticResult = await validatePrTitle({
github,
prTitle,
restParameters,
})
expect(semanticResult.type).to.eq('fix')
})
})
describe('one commit', () => {
it('only validates pr title and commit message', async () => {
const commits = [
{ parents: ['dev'], commit: { message: 'fix: issue with server and add test' } },
]
const myAsyncIterable = {
async *[Symbol.asyncIterator] () {
yield { data: commits }
},
}
const github = {
paginate: {
iterator: sinon.stub().returns(myAsyncIterable),
},
rest: {
pulls: {},
},
}
const prTitle = 'fix: issue with server'
const semanticResult = await validatePrTitle({
github,
prTitle,
restParameters,
})
expect(semanticResult.type).to.eq('fix')
})
it('throws when commit message does not follow semantics', async () => {
const commits = [
{ parents: ['dev'], commit: { message: 'fix issue with server and add test' } },
]
const myAsyncIterable = {
async *[Symbol.asyncIterator] () {
yield { data: commits }
},
}
const github = {
paginate: {
iterator: sinon.stub().returns(myAsyncIterable),
},
rest: {
pulls: {},
},
}
const prTitle = 'fix: issue with server'
return validatePrTitle({
github,
prTitle,
restParameters,
}).catch((err) => {
expect(err.message).to.include('Pull request has only one commit and it\'s not semantic')
})
})
})
})
context('_validateTitle', () => {
it('allows valid PR titles', () => {
[
{
type: 'breaking',
title: 'breaking: change behavior',
},
{
type: 'fix',
title: 'fix: Fix bug',
},
{
type: 'perf',
title: 'perf: make things faster',
},
{
type: 'chore',
title: 'chore: do something',
},
{
type: 'refactor',
title: 'refactor: Internal cleanup',
},
].forEach(({ title, type }) => {
expect(_validateTitle(title)).to.contain({ type })
})
})
it('throws for PR titles without a type', () => {
expect(() => _validateTitle('Fix bug')).to.throw(
'No release type found in pull request title "Fix bug". Add a prefix to indicate what kind of release this pull request corresponds to.',
)
})
it('throws for PR titles with only a type', () => {
expect(() => _validateTitle('fix:')).to.throw(
'No release type found in pull request title "fix:".',
)
})
it('throws for PR titles without a subject', () => {
expect(() => _validateTitle('fix: ')).to.throw(
'No subject found in pull request title "fix: ".',
)
})
it('throws for PR titles with an unknown type', () => {
expect(() => _validateTitle('foo: Bar')).to.throw(
'Unknown release type "foo" found in pull request title "foo: Bar".',
)
})
describe('defined scopes', () => {
it('allows a missing scope by default', () => {
_validateTitle('fix: Bar')
})
it('allows all scopes by default', () => {
_validateTitle('fix(core): Bar')
})
})
})
})