import * as express from 'express'; import { createServer, Server } from 'http'; import { tmpdir } from 'os'; import { join } from 'path'; import { bindNodeCallback, concat, defer, forkJoin, Observable, UnaryFunction } from 'rxjs'; import { map, mapTo, mergeMap, shareReplay, toArray } from 'rxjs/operators'; import * as serveStatic from 'serve-static'; import { v4 } from 'uuid'; import { AddLibraryCommand } from '../src/commands/add.library.command'; import { Options } from '../src/options'; import { rxCopyDir } from '../src/utils/rx.copy'; import { rxDeleteDir } from '../src/utils/rx.delete'; import { expectFileExists } from './utils/expect.utils'; import { findFile, getAssetBaseDir } from './utils/test.utils'; describe('add.library.command', () => { it('should import the text module', () => { // ramp up dev server const app = express(); app.use(serveStatic(join(getAssetBaseDir(), 'test', 'npm-registry'), { index: 'index.json' })); const server = createServer(app); const startServer: UnaryFunction> = bindNodeCallback(server.listen.bind(server)); const rxServer: Observable = startServer(0).pipe( mapTo(server), shareReplay() ); const rxPort: Observable = rxServer.pipe( map(server => server.address().port) ); const rxCloseServer = defer(() => bindNodeCallback(server.close.bind(server))()); const dir = tmpdir(); const name = v4(); const dstBase = join(dir, name); const dstSrc = dstBase; const assetBase = getAssetBaseDir(); const srcSrc = join(assetBase, 'test', 'empty-project'); // copy the data const rxData = rxCopyDir(srcSrc, dstSrc); const rxDelete = rxDeleteDir(dstBase); // create layouts on the result const rxCmdOpt: Observable = rxPort.pipe( map(port => ({ command: AddLibraryCommand.COMMAND, commandType: AddLibraryCommand.TYPE, pkgDir: dstSrc, url: `http://localhost:${port}/`, name: '@dx-samples/text-and-image-component@^0.2.0', verbose: true, override: true, allArgs: [] }))); const rxLibCmd = rxCmdOpt.pipe(map(opt => new AddLibraryCommand(opt))); const rxCmd = rxLibCmd.pipe(mergeMap(cmd => cmd.process())); const rxPrepareData = concat(rxDelete, rxData); // setup teardown const rxSetup = forkJoin(rxServer, rxPrepareData).pipe( shareReplay()); const rxTeardown = forkJoin(rxCloseServer, rxDelete); // command const rxTest = rxCmd.pipe( mergeMap(expectFileExists), toArray(), map(files => { // make sure these files exist expect(findFile('package.json', files)).toBeDefined(); expect(findFile('app.module.ts', files)).toBeDefined(); })); // execute the command const rxTotal = concat(rxSetup, rxTest, rxTeardown); return rxTotal.toPromise(); }); });