Skip to content

Commit

Permalink
feat: Node File System Persister (#61)
Browse files Browse the repository at this point in the history
+ Node testing & ESLint + Ember testem integrations
  • Loading branch information
offirgolan authored Jul 11, 2018
1 parent 29ed8e1 commit 0a0eeca
Show file tree
Hide file tree
Showing 41 changed files with 1,796 additions and 60 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ install:
- yarn install --no-lockfile --non-interactive

before_script:
- lerna bootstrap
- yarn run bootstrap
- yarn run build

script:
- commitlint-travis
- yarn run lint
- yarn run test:ci
- lerna run test --scope=@pollyjs/ember
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Contributing

[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/)

## Getting Started

Install required global dependencies:
Expand All @@ -15,6 +17,13 @@ git clone https://github.com/netflix/pollyjs.git
cd pollyjs
```

Install the dependencies and bootstrap the monorepo:

```bash
yarn
yarn run bootstrap
```

The code for individual packages of this monorepo are in `packages/@pollyjs/*`.
Within any of the packages in this monorepo you'll generally use the npm
package scripts to manage the project, E.g. `yarn run test` or
Expand Down
6 changes: 3 additions & 3 deletions build-scripts/rollup.browser.test.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import multiEntry from 'rollup-plugin-multi-entry';
import createBrowserConfig from './rollup.browser.config';
import { pkg } from './rollup.utils';

export default function createClientTestConfig(options = {}) {
export default function createBrowserTestConfig(options = {}) {
return deepmerge(
createBrowserConfig(
{
input: 'tests/**/*-test.js',
input: 'tests/!(node)/**/*-test.js',
output: {
format: 'es',
name: `${pkg.name}-tests`,
file: `./build/tests/bundle-es.js`,
file: `./build/browser/test-bundle.es.js`,
intro: `
'use strict'
describe('${pkg.name}', function() {
Expand Down
22 changes: 22 additions & 0 deletions build-scripts/rollup.node.test.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import deepmerge from 'deepmerge';
import multiEntry from 'rollup-plugin-multi-entry';
import createNodeConfig from './rollup.node.config';
import { pkg } from './rollup.utils';

export default function createNodeTestConfig(options = {}) {
return deepmerge(
createNodeConfig({
input: 'tests/!(browser)/**/*-test.js',
output: {
format: 'cjs',
name: `${pkg.name}-tests`,
file: `./build/node/test-bundle.cjs.js`,
intro: `describe('${pkg.name}', function() {`,
outro: '});'
},
plugins: [multiEntry()],
external: ['chai']
}),
options
);
}
50 changes: 50 additions & 0 deletions docs/persisters/fs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# REST Persister

Read and write recordings to and from the file system.

## Installation

_Note that you must have node (and npm) installed._

```bash
npm install @pollyjs/persister-fs -D
```

If you want to install it with [yarn](https://yarnpkg.com):

```bash
yarn add @pollyjs/persister-fs -D
```

## Usage

```js
import { Polly } from '@pollyjs/core';
import FSPersister from '@pollyjs/persister-fs';

new Polly('<Recording Name>', {
persister: ['fs', FSPersister]
});
```

## Options

### recordingsDir

_Type_: `String`
_Default_: `'recordings'`

The root directory to store all recordings. Supports both relative and
absolute paths.

__Example__

```js
polly.configure({
persisterOptions: {
fs: {
recordingsDir: '__recordings__'
}
}
});
```
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
"docs:serve": "docsify serve ./docs",
"docs:publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'",
"lint": "lerna run lint",
"pretest": "npm-run-all bootstrap test:clean server:build",
"pretest": "npm-run-all test:clean server:build",
"test": "server-test server:start :4000 test:start",
"test:ci": "yarn pretest && server-test server:start :4000 test:start-ci ; yarn posttest",
"test:build": "lerna run test:build --ignore=@pollyjs/ember --parallel",
"test:build": "lerna run test:build --parallel",
"test:start": "testem",
"test:start-ci": "testem ci",
"test:clean": "lerna run test:clean --parallel",
"test:clean": "rimraf packages/@pollyjs/*/build",
"test:ember": "lerna run test --scope=@pollyjs/ember",
"posttest": "yarn test:clean",
"server:build": "lerna run build --scope=@pollyjs/node-server",
"server:start": "node ./test/server.js",
Expand Down
1 change: 0 additions & 1 deletion packages/@pollyjs/adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"scripts": {
"build": "npm-run-all clean rollup",
"test:build": "rollup -c rollup.config.test.js",
"test:clean": "rimraf build",
"clean": "rimraf dist",
"rollup": "rollup -c ../../../rollup.config.js",
"rollup:prod": "NODE_ENV=production yarn rollup",
Expand Down
5 changes: 3 additions & 2 deletions packages/@pollyjs/adapter/rollup.config.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import createClientTestConfig from '../../../build-scripts/rollup.browser.test.config';
import createNodeTestConfig from '../../../build-scripts/rollup.node.test.config';
import createBrowserTestConfig from '../../../build-scripts/rollup.browser.test.config';

export default createClientTestConfig();
export default [createNodeTestConfig(), createBrowserTestConfig()];
1 change: 0 additions & 1 deletion packages/@pollyjs/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"scripts": {
"build": "npm-run-all clean rollup",
"test:build": "rollup -c rollup.config.test.js",
"test:clean": "rimraf build",
"clean": "rimraf dist",
"rollup": "rollup -c ../../../rollup.config.js",
"rollup:prod": "NODE_ENV=production yarn rollup",
Expand Down
5 changes: 3 additions & 2 deletions packages/@pollyjs/core/rollup.config.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import createClientTestConfig from '../../../build-scripts/rollup.browser.test.config';
import createNodeTestConfig from '../../../build-scripts/rollup.node.test.config';
import createBrowserTestConfig from '../../../build-scripts/rollup.browser.test.config';

export default createClientTestConfig();
export default [createNodeTestConfig(), createBrowserTestConfig()];
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import serializeResponseHeaders from '../../src/adapters/xhr/utils/serialize-response-headers';
import serializeResponseHeaders from '../../../src/adapters/xhr/utils/serialize-response-headers';

export default function request(url, obj = {}) {
return new Promise(resolve => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'formdata-polyfill';

import { setupMocha as setupPolly } from '../../src';
import { setupMocha as setupPolly } from '../../../src';
import * as setupFetch from '../helpers/setup-fetch';
import File from '../helpers/file';
import Configs from './configs';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setupMocha as setupPolly, Polly } from '../../src';
import { setupMocha as setupPolly, Polly } from '../../../src';
import * as setupFetch from '../helpers/setup-fetch';
import Configs from './configs';
import * as validate from 'har-validator/lib/async';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setupMocha as setupPolly } from '../../src';
import { setupMocha as setupPolly } from '../../../src';

describe('Integration | Server', function() {
setupPolly();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import serializeRequestBody from '../../../src/utils/serialize-request-body';
import serializeRequestBody from '../../../../src/utils/serialize-request-body';
import File from '../../helpers/file';

describe('Unit | Utils | serializeRequestBody', function() {
Expand Down
56 changes: 38 additions & 18 deletions packages/@pollyjs/core/tests/unit/polly-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import Adapter from '@pollyjs/adapter';
import Persister from '@pollyjs/persister';
import { MODES } from '@pollyjs/utils';

const nativeFetch = global.fetch;

describe('Unit | Polly', function() {
it('should exist', function() {
expect(Polly).to.be.a('function');
});

it('should instantiate without throwing', async function() {
await expect(async function() {
const polly = new Polly('recording name');
const polly = new Polly('recording name', { adapters: [] });

await polly.stop();
}).to.not.throw();
Expand Down Expand Up @@ -119,6 +117,7 @@ describe('Unit | Polly', function() {
}

const polly = new Polly('recording name', {
adapters: [],
persister: ['local-storage', MockPersister]
});

Expand All @@ -132,12 +131,7 @@ describe('Unit | Polly', function() {
setupPolly({ adapters: [] });

it('should not be configurable once requests are handled', async function() {
const { server } = this.polly;

this.polly.configure({ adapters: ['fetch'] });
server.get('/ping').intercept((req, res) => res.status(200));

expect((await fetch('/ping')).status).to.equal(200);
this.polly._requests.push({});
expect(() => this.polly.configure()).to.throw(
Error,
'[Polly] Cannot call `configure` once requests have been handled.'
Expand Down Expand Up @@ -170,18 +164,39 @@ describe('Unit | Polly', function() {
});

it('should not deep merge adapter options', async function() {
this.polly.configure({ adapters: [] });
class MockAdapter extends Adapter {
static get name() {
return 'mock';
}

onConnect() {}
onDisconnect() {}
}

expect(this.polly.config.adapters.length).to.equal(0);

this.polly.configure({ adapters: ['fetch'] });
this.polly.configure({ adapters: ['xhr'] });
this.polly.configure({ adapters: [['a', MockAdapter]] });
this.polly.configure({ adapters: [['b', MockAdapter]] });
expect(this.polly.config.adapters.length).to.equal(1);
});

it('should connect to new adapters', async function() {
expect(nativeFetch).to.equal(global.fetch);
this.polly.configure({ adapters: ['fetch'] });
expect(nativeFetch).to.not.equal(global.fetch);
let connectCalled = false;

class MockAdapter extends Adapter {
static get name() {
return 'mock';
}

onConnect() {
connectCalled = true;
}
onDisconnect() {}
}

expect(connectCalled).to.be.false;
this.polly.configure({ adapters: [['a', MockAdapter]] });
expect(connectCalled).to.be.true;
});
});

Expand Down Expand Up @@ -327,7 +342,7 @@ describe('Unit | Polly', function() {
createCalled = true;
});

const polly = new Polly('Test');
const polly = new Polly('Test', { adapters: [] });

expect(createCalled).to.be.true;
await polly.stop();
Expand All @@ -342,13 +357,18 @@ describe('Unit | Polly', function() {

it('create - configuration order should be preserved', async function() {
Polly.once('create', polly => {
polly.configure({ logging: true, recordIfMissing: false });
polly.configure({
logging: true,
recordIfMissing: false,
adapters: []
});
});

const polly = new Polly('Test', { recordIfMissing: true });

expect(polly.config.logging).to.be.true;
expect(polly.config.recordIfMissing).to.be.true;
expect(polly.config.adapters).to.deep.equal([]);
await polly.stop();
});

Expand All @@ -361,7 +381,7 @@ describe('Unit | Polly', function() {
stopCalled = true;
});

const polly = new Polly('Test');
const polly = new Polly('Test', { adapters: [] });

await polly.stop();
expect(stopCalled).to.be.true;
Expand Down
6 changes: 3 additions & 3 deletions packages/@pollyjs/core/tests/unit/test-helpers/mocha-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('Unit | Test Helpers | mocha', function() {
it('should invoke beforeEach and afterEach', function() {
const stub = new Sandbox();

setupPolly({}, stub);
setupPolly({ adapters: [] }, stub);
expect(stub.beforeEachCalled.size).to.equal(1);
expect(stub.afterEachCalled.size).to.equal(1);
});
Expand All @@ -42,7 +42,7 @@ describe('Unit | Test Helpers | mocha', function() {

const stub = new Sandbox(ctx);

setupPolly({}, stub);
setupPolly({ adapters: [] }, stub);
expect(ctx.polly).to.be.a('object');
expect(ctx.polly.recordingName).to.equal('foo');
});
Expand All @@ -62,7 +62,7 @@ describe('Unit | Test Helpers | mocha', function() {

const stub = new Sandbox(ctx);

setupPolly({}, stub);
setupPolly({ adapters: [] }, stub);
expect(ctx.polly.recordingName).to.equal('baz/bar/foo');
});
});
6 changes: 4 additions & 2 deletions packages/@pollyjs/core/tests/unit/utils/build-url-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import buildUrl from '../../../src/utils/build-url';

const origin = (global.location && global.location.origin) || '';

describe('Unit | Utils | buildUrl', function() {
it('should exist', function() {
expect(buildUrl).to.be.a('function');
Expand All @@ -16,12 +18,12 @@ describe('Unit | Utils | buildUrl', function() {
});

it('should remove empty fragments of the url', function() {
expect(buildUrl('/foo/bar/baz')).to.equal(`${location.origin}/foo/bar/baz`);
expect(buildUrl('/foo/bar/baz')).to.equal(`${origin}/foo/bar/baz`);
});

it('should concat multiple paths together', function() {
expect(buildUrl('/foo', '/bar', null, undefined, false, '/baz')).to.equal(
`${location.origin}/foo/bar/baz`
`${origin}/foo/bar/baz`
);
});
});
4 changes: 2 additions & 2 deletions packages/@pollyjs/core/tests/unit/utils/timing-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function fixedTest(ms) {
if (ms) {
setTimeout(() => expect(resolved).to.be.false, ms / 2);
}
setTimeout(() => expect(resolved).to.be.true, ms);
setTimeout(() => expect(resolved).to.be.true, ms + 1);

await promise;
});
Expand All @@ -34,7 +34,7 @@ function relativeTest(ratio) {
if (timeout) {
setTimeout(() => expect(resolved).to.be.false, timeout / 2);
}
setTimeout(() => expect(resolved).to.be.true, timeout);
setTimeout(() => expect(resolved).to.be.true, timeout + 1);

await promise;
});
Expand Down
Loading

0 comments on commit 0a0eeca

Please sign in to comment.