node-tdd 3.3.1 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,8 +24,8 @@ Drop-in extension for mocha by simply importing `describe` as below.
24
24
 
25
25
  <!-- eslint-disable import/no-unresolved, import/no-extraneous-dependencies -->
26
26
  ```js
27
- const expect = require('chai').expect;
28
- const { describe } = require('node-tdd');
27
+ import { expect } from 'chai';
28
+ import { describe } from 'node-tdd';
29
29
 
30
30
  describe('Testing some stuff', /* { ...options }, */ () => {
31
31
  it('Testing a thing', () => {
@@ -36,6 +36,16 @@ describe('Testing some stuff', /* { ...options }, */ () => {
36
36
 
37
37
  Please see tests for further usage examples.
38
38
 
39
+ ### Custom Cassette Logic
40
+
41
+ ### delayConnection
42
+
43
+ Delay the connection by a certain number of ms.
44
+
45
+ ### delayBody
46
+
47
+ Delay the response body by a certain number of ms.
48
+
39
49
  ### Function Kwargs
40
50
 
41
51
  #### dir
package/lib/index.js CHANGED
@@ -1,8 +1,13 @@
1
- "use strict";
1
+ import describe_ from './util/desc.js';
2
+ import RequestRecorder_ from './modules/request-recorder.js';
3
+ import EnvManager_ from './modules/env-manager.js';
4
+ import TimeKeeper_ from './modules/time-keeper.js';
5
+ import LogRecorder_ from './modules/log-recorder.js';
6
+ import RandomSeeder_ from './modules/random-seeder.js';
2
7
 
3
- module.exports.describe = require('./util/desc');
4
- module.exports.RequestRecorder = require('./modules/request-recorder');
5
- module.exports.EnvManager = require('./modules/env-manager');
6
- module.exports.TimeKeeper = require('./modules/time-keeper');
7
- module.exports.LogRecorder = require('./modules/log-recorder');
8
- module.exports.RandomSeeder = require('./modules/random-seeder');
8
+ export const describe = describe_;
9
+ export const RequestRecorder = RequestRecorder_;
10
+ export const EnvManager = EnvManager_;
11
+ export const TimeKeeper = TimeKeeper_;
12
+ export const LogRecorder = LogRecorder_;
13
+ export const RandomSeeder = RandomSeeder_;
@@ -1,8 +1,5 @@
1
- "use strict";
2
-
3
- const assert = require('assert');
4
-
5
- const Joi = require('joi-strict');
1
+ import assert from 'assert';
2
+ import Joi from 'joi-strict';
6
3
 
7
4
  const setEnvVar = (key, value) => {
8
5
  if ([null, undefined].includes(value)) {
@@ -13,7 +10,7 @@ const setEnvVar = (key, value) => {
13
10
  }
14
11
  };
15
12
 
16
- module.exports = opts => {
13
+ export default (opts) => {
17
14
  Joi.assert(opts, Joi.object().keys({
18
15
  envVars: Joi.object().pattern(Joi.string(), Joi.string()),
19
16
  allowOverwrite: Joi.boolean()
@@ -24,22 +21,20 @@ module.exports = opts => {
24
21
  envVarsOverwritten.length = 0;
25
22
  Object.entries(opts.envVars).forEach(([key, value]) => {
26
23
  const envVar = key.replace(/^\^/, '');
27
-
28
24
  if (opts.allowOverwrite === true || key.startsWith('^')) {
29
25
  envVarsOverwritten[envVar] = process.env[envVar];
30
26
  } else {
31
27
  assert(process.env[envVar] === undefined, `Environment Variable Set: ${envVar}`);
32
28
  }
33
-
34
29
  setEnvVar(envVar, value);
35
30
  });
36
31
  },
37
32
  unapply: () => {
38
- Object.keys(opts.envVars).forEach(key => {
33
+ Object.keys(opts.envVars).forEach((key) => {
39
34
  const envVar = key.replace(/^\^/, '');
40
35
  assert(typeof process.env[envVar] === 'string', `Environment Variable Set: ${envVar}`);
41
36
  setEnvVar(envVar, envVarsOverwritten[envVar]);
42
37
  });
43
38
  }
44
39
  };
45
- };
40
+ };
@@ -1,10 +1,7 @@
1
- "use strict";
1
+ import assert from 'assert';
2
+ import Joi from 'joi-strict';
2
3
 
3
- const assert = require('assert');
4
-
5
- const Joi = require('joi-strict');
6
-
7
- module.exports = opts => {
4
+ export default (opts) => {
8
5
  Joi.assert(opts, Joi.object().keys({
9
6
  logger: Joi.any(),
10
7
  verbose: Joi.boolean()
@@ -12,13 +9,17 @@ module.exports = opts => {
12
9
  const logger = opts.logger;
13
10
  let verbose = opts.verbose;
14
11
  let loggerOriginal = null;
15
- const logLevels = Object.entries(logger).filter(([k, v]) => typeof v === 'function').map(([k]) => k);
12
+
13
+ const logLevels = Object
14
+ .entries(logger)
15
+ .filter(([k, v]) => typeof v === 'function')
16
+ .map(([k]) => k);
16
17
  assert(logLevels.length !== 0, 'Passed logger does not expose logging functionality');
17
- let logs;
18
18
 
19
+ let logs;
19
20
  const reset = () => {
20
21
  logs = [];
21
- logLevels.forEach(level => {
22
+ logLevels.forEach((level) => {
22
23
  logs[level] = [];
23
24
  });
24
25
  };
@@ -27,16 +28,14 @@ module.exports = opts => {
27
28
  inject: () => {
28
29
  assert(loggerOriginal === null);
29
30
  verbose = opts.verbose;
30
- loggerOriginal = logLevels.reduce((p, c) => Object.assign(p, {
31
- [c]: logger[c]
32
- }), {});
31
+ loggerOriginal = logLevels
32
+ .reduce((p, c) => Object.assign(p, { [c]: logger[c] }), {});
33
33
  reset();
34
- Object.keys(loggerOriginal).forEach(logLevel => {
34
+ Object.keys(loggerOriginal).forEach((logLevel) => {
35
35
  logger[logLevel] = (...args) => {
36
36
  if (verbose === true) {
37
37
  loggerOriginal[logLevel](...args);
38
38
  }
39
-
40
39
  logs.push(...args);
41
40
  logs[logLevel].push(...args);
42
41
  };
@@ -47,7 +46,7 @@ module.exports = opts => {
47
46
  Object.assign(logger, loggerOriginal);
48
47
  loggerOriginal = null;
49
48
  },
50
- verbose: state => {
49
+ verbose: (state) => {
51
50
  assert(typeof state === 'boolean');
52
51
  verbose = state;
53
52
  },
@@ -58,4 +57,4 @@ module.exports = opts => {
58
57
  },
59
58
  reset
60
59
  };
61
- };
60
+ };
@@ -1,27 +1,21 @@
1
- "use strict";
1
+ import assert from 'assert';
2
+ import crypto from 'crypto';
3
+ import get from 'lodash.get';
4
+ import Joi from 'joi-strict';
2
5
 
3
- const assert = require('assert');
6
+ const libs = { Math, crypto };
4
7
 
5
- const crypto = require('crypto');
6
-
7
- const get = require('lodash.get');
8
-
9
- const Joi = require('joi-strict');
10
-
11
- const libs = {
12
- Math,
13
- crypto
14
- };
15
-
16
- module.exports = opts => {
8
+ export default (opts) => {
17
9
  Joi.assert(opts, Joi.object().keys({
18
10
  seed: Joi.string(),
19
11
  reseed: Joi.boolean()
20
12
  }), 'Invalid Options Provided');
21
13
  let original = null;
14
+
22
15
  return {
23
16
  inject: () => {
24
17
  assert(original === null);
18
+
25
19
  original = {
26
20
  crypto: {
27
21
  randomBytes: crypto.randomBytes,
@@ -36,13 +30,18 @@ module.exports = opts => {
36
30
  crypto.randomBytes = (size, cb) => {
37
31
  // randomization is seeded "per key"
38
32
  const stack = new Error().stack.split('\n');
39
- const subStack = stack.slice(stack.findIndex(e => e.indexOf('/node_modules/') !== -1));
40
- const stackOrigin = get(subStack, [subStack.findIndex(e => e.indexOf('/node_modules/') === -1) - 1], '');
33
+ const subStack = stack.slice(stack.findIndex((e) => e.indexOf('/node_modules/') !== -1));
34
+ const stackOrigin = get(subStack, [subStack.findIndex((e) => e.indexOf('/node_modules/') === -1) - 1], '');
41
35
  const originFile = get(stackOrigin.match(/^.*?\([^)]+?\/node_modules\/([^)]+):\d+:\d+\)$/), [1], '');
42
36
  const key = `${originFile}@${size}`;
43
- executionCounts[key] = opts.reseed === true ? null : (executionCounts[key] || 0) + 1;
44
- let result = crypto.createHash('sha256').update(opts.seed).update(key).update(String(executionCounts[key])).digest();
45
37
 
38
+ executionCounts[key] = opts.reseed === true ? null : (executionCounts[key] || 0) + 1;
39
+ let result = crypto
40
+ .createHash('sha256')
41
+ .update(opts.seed)
42
+ .update(key)
43
+ .update(String(executionCounts[key]))
44
+ .digest();
46
45
  while (result.length < size) {
47
46
  result = Buffer.concat([result, crypto.createHash('sha256').update(result).digest()]);
48
47
  }
@@ -50,7 +49,6 @@ module.exports = opts => {
50
49
  result = result.slice(0, size);
51
50
  return cb ? cb(null, result) : result;
52
51
  };
53
-
54
52
  crypto.randomFillSync = (buffer, offset, size) => {
55
53
  const o = offset || 0;
56
54
  const s = size || buffer.byteLength;
@@ -59,7 +57,6 @@ module.exports = opts => {
59
57
  });
60
58
  return buffer;
61
59
  };
62
-
63
60
  Math.random = () => crypto.randomBytes(4).readUInt32LE() / 0xffffffff;
64
61
  },
65
62
  release: () => {
@@ -73,4 +70,4 @@ module.exports = opts => {
73
70
  },
74
71
  isInjected: () => original !== null
75
72
  };
76
- };
73
+ };
@@ -1,31 +1,24 @@
1
- "use strict";
1
+ import objectScan from 'object-scan';
2
2
 
3
- const objectScan = require('object-scan');
4
-
5
- module.exports = (input, modifiers) => {
3
+ export default (input, modifiers) => {
6
4
  objectScan(['**'], {
7
- filterFn: ({
8
- key,
9
- value,
10
- parent
11
- }) => {
5
+ filterFn: ({ key, value, parent }) => {
12
6
  const k = key[key.length - 1];
13
-
14
7
  if (typeof k === 'string' && k.includes('|')) {
15
8
  const [newKey, ...modifierNames] = k.split('|');
16
- const unknownModifiers = modifierNames.filter(n => typeof modifiers[n] !== 'function');
17
-
9
+ const unknownModifiers = modifierNames
10
+ .filter((n) => typeof modifiers[n] !== 'function');
18
11
  if (unknownModifiers.length !== 0) {
19
12
  // eslint-disable-next-line no-console
20
13
  console.warn(`Unknown Modifier(s) detected: ${unknownModifiers.join(', ')}`);
21
14
  return;
22
- } // eslint-disable-next-line no-param-reassign
23
-
24
-
25
- delete parent[k]; // eslint-disable-next-line no-param-reassign
26
-
27
- parent[newKey] = modifierNames.reduce((p, modifierName) => modifiers[modifierName](p), value);
15
+ }
16
+ // eslint-disable-next-line no-param-reassign
17
+ delete parent[k];
18
+ // eslint-disable-next-line no-param-reassign
19
+ parent[newKey] = modifierNames
20
+ .reduce((p, modifierName) => modifiers[modifierName](p), value);
28
21
  }
29
22
  }
30
23
  })(input);
31
- };
24
+ };
@@ -1,31 +1,24 @@
1
- "use strict";
1
+ import crypto from 'crypto';
2
+ import qs from 'querystring';
3
+ import get from 'lodash.get';
2
4
 
3
- const crypto = require('crypto');
5
+ import { v4 as uuid4 } from 'uuid';
6
+ import xml2js from 'xml2js';
4
7
 
5
- const qs = require('querystring');
8
+ const parseRequestBody = (body) => Object.values(Object
9
+ .entries(qs.parse(body))
10
+ .filter(([k, v]) => k.startsWith('SendMessageBatchRequestEntry.'))
11
+ .sort((a, b) => a[0].localeCompare(b[0]))
12
+ .map(([k, v]) => [k.split('.'), v])
13
+ .reduce((p, [k, v]) => {
14
+ if (p[k[1]] === undefined) {
15
+ Object.assign(p, { [k[1]]: {} });
16
+ }
17
+ Object.assign(p[k[1]], { [k[2]]: v });
18
+ return p;
19
+ }, {}));
6
20
 
7
- const get = require('lodash.get');
8
-
9
- const {
10
- v4: uuid4
11
- } = require('uuid');
12
-
13
- const xml2js = require('xml2js');
14
-
15
- const parseRequestBody = body => Object.values(Object.entries(qs.parse(body)).filter(([k, v]) => k.startsWith('SendMessageBatchRequestEntry.')).sort((a, b) => a[0].localeCompare(b[0])).map(([k, v]) => [k.split('.'), v]).reduce((p, [k, v]) => {
16
- if (p[k[1]] === undefined) {
17
- Object.assign(p, {
18
- [k[1]]: {}
19
- });
20
- }
21
-
22
- Object.assign(p[k[1]], {
23
- [k[2]]: v
24
- });
25
- return p;
26
- }, {}));
27
-
28
- const parseResponseBody = body => {
21
+ const parseResponseBody = (body) => {
29
22
  let parsed = null;
30
23
  xml2js.parseString(body, (err, result) => {
31
24
  parsed = result;
@@ -33,15 +26,51 @@ const parseResponseBody = body => {
33
26
  return parsed;
34
27
  };
35
28
 
36
- module.exports = (requestBody, responseBody, scope) => {
37
- if (!/^https:\/\/sqs\.[a-z0-9-]+\.amazonaws\.com:443$/.test(scope.basePath) || !responseBody.startsWith('<?xml version="1.0"?><SendMessageBatchResponse')) {
29
+ export default (requestBody, responseBody, scope) => {
30
+ if (
31
+ !/^https:\/\/sqs\.[a-z0-9-]+\.amazonaws\.com:443$/.test(scope.basePath)
32
+ || !responseBody.startsWith('<?xml version="1.0"?><SendMessageBatchResponse')) {
38
33
  return responseBody;
39
34
  }
40
35
 
41
36
  const responseBodyParsed = parseResponseBody(responseBody);
42
- const resultEntries = parseRequestBody(requestBody).map(({
43
- Id,
44
- MessageBody
45
- }, idx) => ['<SendMessageBatchResultEntry>', `<Id>${Id}</Id>`, `<MessageId>${get(responseBodyParsed, ['SendMessageBatchResponse', 'SendMessageBatchResult', 0, 'SendMessageBatchResultEntry', idx, 'MessageId'], uuid4())}</MessageId>`, `<MD5OfMessageBody>${crypto.createHash('md5').update(MessageBody).digest('hex')}</MD5OfMessageBody>`, '</SendMessageBatchResultEntry>'].join(''));
46
- return ['<?xml version="1.0"?>', '<SendMessageBatchResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">', '<SendMessageBatchResult>', ...resultEntries, '</SendMessageBatchResult>', '<ResponseMetadata>', `<RequestId>${get(responseBodyParsed, ['SendMessageBatchResponse', 'ResponseMetadata', 0, 'RequestId', 0], uuid4())}</RequestId>`, '</ResponseMetadata>', '</SendMessageBatchResponse>'].join('');
47
- };
37
+
38
+ const resultEntries = parseRequestBody(requestBody)
39
+ .map(({ Id, MessageBody }, idx) => [
40
+ '<SendMessageBatchResultEntry>',
41
+ `<Id>${Id}</Id>`,
42
+ `<MessageId>${
43
+ get(responseBodyParsed, [
44
+ 'SendMessageBatchResponse',
45
+ 'SendMessageBatchResult',
46
+ 0,
47
+ 'SendMessageBatchResultEntry',
48
+ idx,
49
+ 'MessageId'
50
+ ], uuid4())
51
+ }</MessageId>`,
52
+ `<MD5OfMessageBody>${
53
+ crypto.createHash('md5').update(MessageBody).digest('hex')
54
+ }</MD5OfMessageBody>`,
55
+ '</SendMessageBatchResultEntry>'
56
+ ].join(''));
57
+ return [
58
+ '<?xml version="1.0"?>',
59
+ '<SendMessageBatchResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">',
60
+ '<SendMessageBatchResult>',
61
+ ...resultEntries,
62
+ '</SendMessageBatchResult>',
63
+ '<ResponseMetadata>',
64
+ `<RequestId>${
65
+ get(responseBodyParsed, [
66
+ 'SendMessageBatchResponse',
67
+ 'ResponseMetadata',
68
+ 0,
69
+ 'RequestId',
70
+ 0
71
+ ], uuid4())
72
+ }</RequestId>`,
73
+ '</ResponseMetadata>',
74
+ '</SendMessageBatchResponse>'
75
+ ].join('');
76
+ };
@@ -1,20 +1,18 @@
1
- "use strict";
1
+ import nock from 'nock';
2
2
 
3
- const nock = require('nock');
4
-
5
- module.exports = (() => {
3
+ export default (() => {
6
4
  const fnLists = {
7
5
  'no match': []
8
6
  };
9
7
  Object.entries(fnLists).forEach(([event, fns]) => {
10
- nock.emitter.on(event, (...args) => fns.forEach(fn => fn(...args)));
8
+ nock.emitter.on(event, (...args) => fns.forEach((fn) => fn(...args)));
11
9
  });
12
10
  return {
13
11
  subscribe: (event, f) => {
14
12
  fnLists[event].push(f);
15
13
  },
16
- unsubscribeAll: event => {
14
+ unsubscribeAll: (event) => {
17
15
  fnLists[event].length = 0;
18
16
  }
19
17
  };
20
- })();
18
+ })();
@@ -1,30 +1,27 @@
1
- "use strict";
2
-
3
- const nockCommon = require('nock/lib/common');
1
+ import nockCommon from 'nock/lib/common.js';
4
2
 
5
3
  const fns = ['setInterval', 'setTimeout', 'deleteHeadersField'];
6
4
  const originals = fns.reduce((p, c) => Object.assign(p, {
7
5
  [c]: nockCommon[c]
8
6
  }), {});
9
- module.exports = {
7
+
8
+ export default {
10
9
  patch: () => {
11
- fns.forEach(fn => {
10
+ fns.forEach((fn) => {
12
11
  nockCommon[fn] = (...args) => {
13
12
  if (fn === 'deleteHeadersField') {
14
13
  return undefined;
15
14
  }
16
-
17
15
  if (args[1] === 0) {
18
16
  return args[0](...args.slice(2));
19
17
  }
20
-
21
18
  return originals[fn](...args);
22
19
  };
23
20
  });
24
21
  },
25
22
  unpatch: () => {
26
- fns.forEach(fn => {
23
+ fns.forEach((fn) => {
27
24
  nockCommon[fn] = originals[fn];
28
25
  });
29
26
  }
30
- };
27
+ };
@@ -1,23 +1,15 @@
1
- "use strict";
2
-
3
- const assert = require('assert');
4
-
5
- const http = require('http');
6
-
7
- const https = require('https');
8
-
9
- const nockCommon = require('nock/lib/common');
1
+ import assert from 'assert';
2
+ import http from 'http';
3
+ import https from 'https';
4
+ import nockCommon from 'nock/lib/common.js';
10
5
 
11
6
  let lastProtocol = null;
12
7
  let lastOptions = null;
13
8
  const lastBody = [];
14
9
 
15
- const wrapper = proto => {
10
+ const wrapper = (proto) => {
16
11
  let requestOriginal = null;
17
- const protocol = {
18
- http,
19
- https
20
- }[proto];
12
+ const protocol = { http, https }[proto];
21
13
 
22
14
  const requestWrapper = (...args) => {
23
15
  lastProtocol = proto;
@@ -25,12 +17,10 @@ const wrapper = proto => {
25
17
  lastBody.length = 0;
26
18
  const result = requestOriginal.call(protocol, ...args);
27
19
  const writeOriginal = result.write;
28
-
29
20
  result.write = (chunk, encoding, callback) => {
30
21
  lastBody.push(chunk.toString());
31
22
  return writeOriginal.call(result, chunk, encoding, callback);
32
23
  };
33
-
34
24
  return result;
35
25
  };
36
26
 
@@ -51,7 +41,7 @@ const wrapper = proto => {
51
41
  };
52
42
  };
53
43
 
54
- module.exports = (() => {
44
+ export default (() => {
55
45
  const httpWrapper = wrapper('http');
56
46
  const httpsWrapper = wrapper('https');
57
47
  return {
@@ -69,4 +59,4 @@ module.exports = (() => {
69
59
  body: lastBody.length === 0 ? undefined : lastBody.join('')
70
60
  })
71
61
  };
72
- })();
62
+ })();
@@ -1,12 +1,9 @@
1
- "use strict";
1
+ export const buildKey = (interceptor) => `${interceptor.method} ${interceptor.basePath}${interceptor.uri}`;
2
2
 
3
- module.exports.buildKey = interceptor => `${interceptor.method} ${interceptor.basePath}${interceptor.uri}`;
4
-
5
- module.exports.tryParseJson = value => {
3
+ export const tryParseJson = (value) => {
6
4
  if (typeof value !== 'string') {
7
5
  return value;
8
6
  }
9
-
10
7
  try {
11
8
  return JSON.parse(value);
12
9
  } catch (e) {
@@ -14,27 +11,28 @@ module.exports.tryParseJson = value => {
14
11
  }
15
12
  };
16
13
 
17
- module.exports.nullAsString = value => value === null ? 'null' : value;
14
+ export const nullAsString = (value) => (value === null ? 'null' : value);
18
15
 
19
- module.exports.convertHeaders = array => {
16
+ export const convertHeaders = (array) => {
20
17
  const obj = {};
21
-
22
18
  for (let idx = 0; idx < array.length; idx += 2) {
23
19
  obj[array[idx].toLowerCase()] = array[idx + 1];
24
20
  }
25
-
26
21
  return obj;
27
22
  };
28
23
 
29
- module.exports.rewriteHeaders = (headers, fn = (k, v) => v) => {
24
+ export const rewriteHeaders = (headers, fn = (k, v) => v) => {
30
25
  if (headers === undefined) {
31
26
  return {};
32
27
  }
33
-
34
- const headersLower = Object.fromEntries(Object.entries(headers).sort(([a], [b]) => a > b ? 1 : -1).map(([k, v]) => [k.toLowerCase(), v]));
28
+ const headersLower = Object.fromEntries(
29
+ Object.entries(headers)
30
+ .sort(([a], [b]) => (a > b ? 1 : -1))
31
+ .map(([k, v]) => [k.toLowerCase(), v])
32
+ );
35
33
  const result = {};
36
34
  Object.entries(headersLower).forEach(([k, v]) => {
37
35
  result[k] = fn(k, v, headersLower);
38
36
  });
39
37
  return result;
40
- };
38
+ };