UNPKG

@kazupon/lerna-changelog

Version:

Generate a changelog for a lerna monorepo

418 lines (417 loc) 14.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); jest.mock('../../src/progress-bar'); jest.mock('../../src/changelog'); jest.mock('../../src/github-api'); jest.mock('../git'); jest.mock('../fetch'); const listOfCommits = [ { sha: 'a0000015', refName: '', summary: 'chore: making of episode viii', date: '2015-12-18' }, { sha: 'a0000014', refName: '', summary: 'feat: infiltration (#7)', date: '2015-12-18' }, { sha: 'a0000013', refName: 'HEAD -> master, tag: v6.0.0, origin/master, origin/HEAD', summary: 'chore(release): releasing component', date: '1983-05-25' }, { sha: 'a0000012', refName: '', summary: 'Merge pull request #6 from return-of-the-jedi', date: '1983-05-25' }, { sha: 'a0000011', refName: '', summary: 'feat: I am your father (#5)', date: '1983-05-25' }, { sha: 'a0000010', refName: '', summary: 'fix(han-solo): unfreezes (#4)', date: '1983-05-25' }, { sha: 'a0000009', refName: 'tag: v5.0.0', summary: 'chore(release): releasing component', date: '1980-05-17' }, { sha: 'a0000008', refName: '', summary: 'Merge pull request #3 from empire-strikes-back', date: '1980-05-17' }, { sha: 'a0000007', refName: '', summary: 'fix: destroy rebels base', date: '1980-05-17' }, { sha: 'a0000006', refName: '', summary: 'chore: the end of Alderaan (#2)', date: '1980-05-17' }, { sha: 'a0000005', refName: '', summary: 'refactor(death-star): add deflector shield', date: '1980-05-17' }, { sha: 'a0000004', refName: 'tag: v4.0.0', summary: 'chore(release): releasing component', date: '1977-05-25' }, { sha: 'a0000003', refName: '', summary: 'Merge pull request #1 from star-wars', date: '1977-05-25' }, { sha: 'a0000002', refName: 'tag: v0.1.0', summary: 'chore(release): releasing component', date: '1966-01-01' }, { sha: 'a0000001', refName: '', summary: 'fix: some random fix which will be ignored', date: '1966-01-01' } ]; const listOfTags = [ 'v6.0.0', 'v5.0.0', 'v4.0.0', 'v3.0.0', 'v2.0.0', 'v1.0.0', 'v0.1.0' ]; const listOfPackagesForEachCommit = { a0000001: ['packages/random/foo.js'], a0000002: ['packages/random/package.json'], a0000003: ['packages/a-new-hope/rebels.js'], a0000004: ['packages/a-new-hope/package.json'], a0000005: ['packages/empire-strikes-back/death-star.js'], a0000006: ['packages/empire-strikes-back/death-star.js'], a0000007: ['packages/empire-strikes-back/hoth.js'], a0000008: ['packages/empire-strikes-back/hoth.js'], a0000009: ['packages/empire-strikes-back/package.json'], a0000010: ['packages/return-of-the-jedi/jabba-the-hutt.js'], a0000011: ['packages/return-of-the-jedi/vader-luke.js'], a0000012: ['packages/return-of-the-jedi/leia.js'], a0000013: ['packages/return-of-the-jedi/package.json'], a0000014: [ 'packages/the-force-awakens/mission.js', 'packages/rogue-one/mission.js' ], a0000015: ['packages/untitled/script.md'] }; const listOfFileForEachCommit = { a0000001: ['random/foo.js'], a0000002: ['random/package.json'], a0000003: ['a-new-hope/rebels.js'], a0000004: ['a-new-hope/package.json'], a0000005: ['empire-strikes-back/death-star.js'], a0000006: ['empire-strikes-back/death-star.js'], a0000007: ['empire-strikes-back/hoth.js'], a0000008: ['empire-strikes-back/hoth.js'], a0000009: ['empire-strikes-back/package.json'], a0000010: ['return-of-the-jedi/jabba-the-hutt.js'], a0000011: ['return-of-the-jedi/vader-luke.js'], a0000012: ['return-of-the-jedi/leia.js'], a0000013: ['return-of-the-jedi/package.json'], a0000014: ['the-force-awakens/mission.js', 'rogue-one/mission.js'], a0000015: ['untitled/script.md'] }; const usersCache = { 'https://api.github.com/users/luke': { body: { login: 'luke', html_url: 'https://github.com/luke', name: 'Luke Skywalker' } }, 'https://api.github.com/users/princess-leia': { body: { login: 'princess-leia', html_url: 'https://github.com/princess-leia', name: 'Princess Leia Organa' } }, 'https://api.github.com/users/vader': { body: { login: 'vader', html_url: 'https://github.com/vader', name: 'Darth Vader' } }, 'https://api.github.com/users/gtarkin': { body: { login: 'gtarkin', html_url: 'https://github.com/gtarkin', name: 'Governor Tarkin' } }, 'https://api.github.com/users/han-solo': { body: { login: 'han-solo', html_url: 'https://github.com/han-solo', name: 'Han Solo' } }, 'https://api.github.com/users/chewbacca': { body: { login: 'chewbacca', html_url: 'https://github.com/chewbacca', name: 'Chwebacca' } }, 'https://api.github.com/users/rd-d2': { body: { login: 'rd-d2', html_url: 'https://github.com/rd-d2', name: 'R2-D2' } }, 'https://api.github.com/users/c-3po': { body: { login: 'c-3po', html_url: 'https://github.com/c-3po', name: 'C-3PO' } } }; const issuesCache = { 'https://api.github.com/repos/lerna/lerna-changelog/issues/1': { body: { number: 1, title: 'feat: May the force be with you', labels: [{ name: 'Type: New Feature' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/1' }, user: usersCache['https://api.github.com/users/luke'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/2': { body: { number: 2, title: 'chore: Terminate her... immediately!', labels: [{ name: 'Type: Breaking Change' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/2' }, user: usersCache['https://api.github.com/users/gtarkin'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/3': { body: { number: 3, title: 'fix: Get me the rebels base!', labels: [{ name: 'Type: Bug' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/3' }, user: usersCache['https://api.github.com/users/vader'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/4': { body: { number: 4, title: 'fix: RRRAARRWHHGWWR', labels: [{ name: 'Type: Bug' }, { name: 'Type: Maintenance' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/4' }, user: usersCache['https://api.github.com/users/chewbacca'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/5': { body: { number: 5, title: 'feat: I am your father', labels: [{ name: 'Type: New Feature' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/5' }, user: usersCache['https://api.github.com/users/vader'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/6': { body: { number: 6, title: 'refactor: he is my brother', labels: [{ name: 'Type: Enhancement' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/6' }, user: usersCache['https://api.github.com/users/princess-leia'].body } }, 'https://api.github.com/repos/lerna/lerna-changelog/issues/7': { body: { number: 7, title: 'feat: that is not how the Force works!', labels: [{ name: 'Type: New Feature' }, { name: 'Type: Enhancement' }], pull_request: { html_url: 'https://github.com/lerna/lerna-changelog/pull/7' }, user: usersCache['https://api.github.com/users/han-solo'].body } } }; describe('createMarkdown', () => { beforeEach(() => { require('../fetch').__resetMockResponses(); }); afterEach(() => { jest.resetAllMocks(); }); describe('single tags', () => { it('outputs correct changelog', async () => { require('../git').changedPaths.mockImplementation((sha) => listOfPackagesForEachCommit[sha]); require('../git').lastTag.mockImplementation(() => 'v8.0.0'); require('../git').listCommits.mockImplementation(() => listOfCommits); require('../git').listTagNames.mockImplementation(() => listOfTags); require('../fetch').__setMockResponses({ ...usersCache, ...issuesCache }); const MockedChangelog = require('../changelog').default; const changelog = new MockedChangelog(); const markdown = await changelog.createMarkdown(); expect(markdown).toMatchSnapshot(); }); }); describe('multiple tags', () => { it('outputs correct changelog', async () => { require('../git').changedPaths.mockImplementation((sha) => listOfPackagesForEachCommit[sha]); require('../git').lastTag.mockImplementation(() => 'v8.0.0'); require('../git').listCommits.mockImplementation(() => [ { sha: 'a0000004', refName: 'tag: a-new-hope@4.0.0, tag: empire-strikes-back@5.0.0, tag: return-of-the-jedi@6.0.0', summary: 'chore(release): releasing component', date: '1977-05-25' }, { sha: 'a0000003', refName: '', summary: 'Merge pull request #1 from star-wars', date: '1977-05-25' }, { sha: 'a0000002', refName: 'tag: v0.1.0', summary: 'chore(release): releasing component', date: '1966-01-01' }, { sha: 'a0000001', refName: '', summary: 'fix: some random fix which will be ignored', date: '1966-01-01' } ]); require('../git').listTagNames.mockImplementation(() => [ 'a-new-hope@4.0.0', 'attack-of-the-clones@3.1.0', 'empire-strikes-back@5.0.0', 'return-of-the-jedi@6.0.0', 'revenge-of-the-sith@3.0.0', 'the-force-awakens@7.0.0', 'the-phantom-menace@1.0.0' ]); require('../fetch').__setMockResponses({ ...usersCache, ...issuesCache }); const MockedChangelog = require('../changelog').default; const changelog = new MockedChangelog(); const markdown = await changelog.createMarkdown(); expect(markdown).toMatchSnapshot(); }); }); describe('single project', () => { it('outputs correct changelog', async () => { require('../git').changedPaths.mockImplementation((sha) => listOfFileForEachCommit[sha]); require('../git').lastTag.mockImplementation(() => 'v8.0.0'); require('../git').listCommits.mockImplementation(() => listOfCommits); require('../git').listTagNames.mockImplementation(() => listOfTags); require('../fetch').__setMockResponses({ ...usersCache, ...issuesCache }); const MockedChangelog = require('../changelog').default; const changelog = new MockedChangelog(); const markdown = await changelog.createMarkdown(); expect(markdown).toMatchSnapshot(); }); }); describe('authentication', () => { describe('when github token is not valid', () => { const badCredentials = { message: 'Bad credentials', documentation_url: 'https://developer.github.com/v3' }; beforeEach(() => { require('../git').changedPaths.mockImplementation((sha) => listOfFileForEachCommit[sha]); require('../git').lastTag.mockImplementation(() => 'v8.0.0'); require('../git').listCommits.mockImplementation(() => listOfCommits); require('../git').listTagNames.mockImplementation(() => listOfTags); const unauthorized = { status: 401, statusText: 'Unauthorized', ok: false, body: badCredentials }; require('../fetch').__setMockResponses({ ...usersCache, ...Object.keys(issuesCache).reduce((unauthorizedIssues, issue) => ({ ...unauthorizedIssues, [issue]: unauthorized }), {}) }); }); afterEach(() => { jest.resetAllMocks(); }); it('should abort with a proper error message', async () => { const MockedChangelog = require('../changelog').default; const changelog = new MockedChangelog(); expect.assertions(2); try { await changelog.createMarkdown(); } catch (error) { expect(error).toEqual(expect.objectContaining({ message: expect.stringContaining('Fetch error: Unauthorized') })); expect(error).toEqual(expect.objectContaining({ message: expect.stringContaining(JSON.stringify(badCredentials)) })); } }); }); }); });