UNPKG

4.32 kBPlain TextView Raw
1const Debug: any = require('debug');
2import * as portfinder from 'portfinder';
3import * as os from 'os';
4import * as path from 'path';
5import * as fs from 'fs-extra';
6import {MongodHelper} from 'mongodb-prebuilt';
7import {MockgooseHelper} from './mockgoose-helper';
8//const uuidV4 = require('uuid/v4');
9const uuidV4: any = require('uuid/v4');
10
11export class Mockgoose {
12
13 helper: MockgooseHelper;
14 mongodHelper: MongodHelper = new MongodHelper();
15 debug: any;
16 mongooseObj: any;
17
18 constructor(mongooseObj: any) {
19 this.debug = Debug('Mockgoose');
20 this.helper = new MockgooseHelper(mongooseObj, this);
21
22 this.mongooseObj = mongooseObj;
23 this.mongooseObj.mocked = true;
24 }
25
26 prepareStorage(): Promise<void> {
27 return new Promise<void>((resolve, reject) => {
28 let tempDBPathPromise: Promise<string> = this.getTempDBPath();
29 let openPortPromise: Promise<number> = this.getOpenPort();
30
31 Promise.all([tempDBPathPromise, openPortPromise]).then((promiseValues) => {
32 let dbPath: string = promiseValues[0];
33 let openPort: string = promiseValues[1].toString();
34 let storageEngine: string = this.getMemoryStorageName();
35 let mongodArgs: string[] = [
36 '--port', openPort,
37 '--storageEngine', storageEngine,
38 '--dbpath', dbPath
39 ];
40 this.debug(`@prepareStorage mongod args, ${mongodArgs}`);
41 this.mongodHelper.mongoBin.commandArguments = mongodArgs;
42 this.mongodHelper.run().then(() => {
43 let connectionString: string = this.getMockConnectionString(openPort);
44 this.mockConnectCalls(connectionString);
45 resolve();
46 }, (e: any) => {
47 reject(e);
48 // throw e;
49 // return this.prepareStorage();
50 });
51 });
52 });
53 }
54
55 shutdown(): Promise<number> {
56 return new Promise<number>((resolve, reject) => {
57 this.mongooseObj.disconnect();
58 let timer = setTimeout(()=> {
59 reject(new Error('Mockgoose timed out shutting down mongod'))
60 }, 10000);
61 this.mongodHelper.mongoBin.childProcess.on('exit', (code, signal) => {
62 this.debug('mongod has exited with %s on %s', code, signal)
63 clearTimeout(timer);
64 resolve(code);
65 });
66 this.mongodHelper.stop();
67 });
68 }
69
70 getMockConnectionString(port: string): string {
71 const dbName: string = 'mockgoose-temp-db-' + uuidV4();
72 const connectionString: string = `mongodb://localhost:${port}/${dbName}`;
73 return connectionString;
74 }
75
76 mockConnectCalls(connection: string) {
77 let createConnection: ConnectionWrapper = new ConnectionWrapper('createConnection', this.mongooseObj, connection);
78 this.mongooseObj.createConnection = function() { return createConnection.run(arguments) };
79 let connect: ConnectionWrapper = new ConnectionWrapper('connect', this.mongooseObj, connection);
80 this.mongooseObj.connect = function() { return connect.run(arguments) };
81 }
82
83 getOpenPort(): Promise<number> {
84 return new Promise<number>((resolve, reject) => {
85 portfinder.getPort({port: 27017}, function (err, port) {
86 if ( err ) {
87 reject(err)
88 } else {
89 resolve(port);
90 }
91 });
92 });
93 }
94
95 // todo: add support to mongodb-download or prebuilt to return version
96 getMemoryStorageName(): string {
97 return "ephemeralForTest";
98
99 }
100
101 getTempDBPath(): Promise<string> {
102 return new Promise<string>((resolve, reject) => {
103 let tempDir: string = path.resolve(os.tmpdir(), "mockgoose", Date.now().toString());
104 fs.ensureDir(tempDir, (err: any) => {
105 if (err) throw err;
106 resolve(tempDir);
107 });
108 });
109 }
110}
111
112export class ConnectionWrapper {
113
114 originalArguments: any;
115 functionName: string;
116 functionCode: any;
117 mongoose: any;
118 connectionString: string;
119
120 constructor(
121 functionName: string, mongoose: any, connectionString: string
122 ) {
123 this.functionName = functionName;
124 this.mongoose = mongoose;
125 this.functionCode = mongoose[functionName];
126 this.connectionString = connectionString;
127 }
128
129 run(args: any): void {
130 this.originalArguments = args;
131 let mockedArgs: any = args;
132 mockedArgs[0] = this.connectionString;
133 return this.functionCode.apply(this.mongoose, mockedArgs);
134 }
135
136}
137
138
139
140
\No newline at end of file