UNPKG

branch-remover

Version:

A small application for quickly removing unnecessary branches from GitHub.

242 lines (190 loc) 6.27 kB
import { expect } from 'chai'; import faker from 'faker'; import streams from 'memory-streams'; import { Writable } from 'stream'; import util from 'util'; import winston from 'winston'; import { BranchRemover } from '../src/BranchRemover'; import { BranchListItem, BranchRemoverOptionsIgnoreArgs, IBranchesProvider, IBranchRemover, ILogger, Logger, } from '../src/Core'; import { FakeBranchesProvider } from './FakeBranchesProvider'; import { FakeCacheProvider } from './FakeCacheProvider'; const setTimeoutAsync = util.promisify( (interval: number, callback?: Function): void => { setTimeout(callback, interval); } ); describe('BranchRemover', (): void => { let provider: IBranchesProvider; let remover: IBranchRemover; let logger: ILogger; let writer: Writable; const getBranchNames = async(): Promise<Array<string>> => { return (await provider.getListBranches()).map( (x: BranchListItem): string => x.name ); }; const randomArrayElements = (source: Array<string>, max: number): Array<string> => { const result = new Array<string>(); let item = faker.random.arrayElement(source); while ( result.includes(item) || result.length < max ) { if (!result.includes(item)) { result.push(item); } item = faker.random.arrayElement(source); } return result; }; const escape = (value: string): string => { return value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); }; const initNewLogger = (): void => { logger = new Logger({ levels: Logger.defaultLevels, level: 'info', transports: [ new winston.transports.Stream({ stream: writer, }), ], }); }; beforeEach((): void => { writer = new streams.WritableStream(); provider = new FakeBranchesProvider(); remover = new BranchRemover(provider); initNewLogger(); }); it('provider should not be null', (): void => { expect(remover.provider).to.not.be.null; }); it('should use the default logger', async(): Promise<void> => { await remover.execute({ remove: (): Promise<boolean> => Promise.resolve(true), }, true); expect(writer.toString()).to.be.empty; }); it('should skip a branch for which detailed information is missing', async(): Promise<void> => { await getBranchNames(); (<FakeBranchesProvider>provider).details.splice(0, 10); await remover.execute({ logger, remove: (): Promise<boolean> => Promise.resolve(true), }); const log = writer.toString(); const result = await getBranchNames(); expect(result.length).to.be.equal(10); expect(log).to.be.contain('because no detailed information'); }); it('should not remove branches in test mode', async(): Promise<void> => { const branches = await getBranchNames(); await remover.execute({ logger, remove: (): Promise<boolean> => Promise.resolve(true), }, true); const log = writer.toString(); const result = await getBranchNames(); expect(result.length).to.be.equal(branches.length); expect(log).to.be.contain('Removing is not applicable in test mode.'); }); it('should only contain branches that were ignored by function results', async(): Promise<void> => { const max = 5; const branches = randomArrayElements( await getBranchNames(), max ); await remover.execute({ logger, ignore: ({ branchName }: BranchRemoverOptionsIgnoreArgs): Promise<boolean> => { return Promise.resolve( branches.includes(branchName) ); }, remove: (): Promise<boolean> => Promise.resolve(true), }); const result = await getBranchNames(); expect(result.length).to.be.equal(max); expect(result.sort()).to.deep.equal(branches.sort()); }); it('should only contain branches that were ignored by RegExp pattern', async(): Promise<void> => { const max = 5; const branches = randomArrayElements( await getBranchNames(), max ); await remover.execute({ logger, ignore: new RegExp(`^(${branches.map(escape).join('|')})$`), remove: (): Promise<boolean> => Promise.resolve(true), }); const result = await getBranchNames(); expect(result.length).to.be.equal(max); expect(result.sort()).to.deep.equal(branches.sort()); }); it('should only contain branches that were ignored by array', async(): Promise<void> => { const max = 5; const ignore = randomArrayElements( await getBranchNames(), max ); await remover.execute({ logger, ignore, remove: (): Promise<boolean> => Promise.resolve(true), }); const result = await getBranchNames(); expect(result.length).to.be.equal(max); expect(result.sort()).to.deep.equal(ignore.sort()); }); it('should only contain branches that were ignored by string value', async(): Promise<void> => { const ignore = randomArrayElements( await getBranchNames(), 1 )[0]; await remover.execute({ logger, ignore, remove: (): Promise<boolean> => Promise.resolve(true), }); const result = await getBranchNames(); expect(result.length).to.be.equal(1); expect(result).to.deep.equal([ignore]); }); it('should be removed all branches using remove function', async(): Promise<void> => { await remover.execute({ logger, remove: (): Promise<boolean> => Promise.resolve(true), }); const result = await getBranchNames(); expect(result.length).to.be.equal(0); }); it('should use cache', async(): Promise<void> => { const branches = await getBranchNames(); const keys = branches.map((x: string): string => `branch-${x}`); const cache = { timeout: 10, provider: new FakeCacheProvider(), }; await remover.execute({ cache, remove: (): Promise<boolean> => Promise.resolve(false), }, true); expect(cache.provider.keys()).to.be.deep.equal(keys); await remover.execute({ cache, logger, remove: (): Promise<boolean> => Promise.resolve(true), }, true); const log = writer.toString(); expect(log).to.be.contains('Skip cached branch'); }); });