Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PouchDB for LevelDOWN authors

PouchDB for LevelDOWN authors

Introduction

Who are you? You're the author of a LevelDOWN-compatibile module, such as MemDOWN, FooDOWN, BarDOWN, whatever.

What do you want? A super-sweet module that passes the grueling 1,000+ tests in the PouchDB test suite. This guide will help get you there.

About PouchDB

PouchDB is a JavaScript database that syncs with CouchDB. In browsers, it uses IndexedDB or WebSQL, whereas in Node, it uses LevelDB via the LevelUP API. In Node, it can also talk to any *DOWN database.

PouchDB Server is a Node+Express app designed to mimic the CouchDB HTTP API. Since it uses PouchDB under the hood, it can also talk to any *DOWN database.

Goal

By the end of this guide, you should be able to set up your *DOWN module to automatically run tests against PouchDB and PouchDB Server from the command line. These tests should exit with a meaningful exit status so that you can trivially set it up to run in Travis, etc.

Note: currently the scripts are Bash-based, so they only work in *nix.

Setup

First:

npm install --save-dev pouchdb@pouchdb/pouchdb#fix-leveldown-args
npm install --save-dev pouchdb-server

Next, add the test-pouchdb.sh file (included below) into a bin/ directory or wherever you want to put it. For convenience, you should probably also add an npm script in package.json:

  "scripts": {
    ...
    "test-pouchdb": "./bin/test-pouchdb.sh"
  }

Running the tests

Sanity check

As a sanity check, try running the tests with LevelDOWN in the server and LevelDOWN in the client. This should always exit with 100% success:

npm run test-pouchdb

If it fails, then there's probably a bug in your local setup. (Ignore the "pending" tests; those are skipped.)

Testing your module

Let's assume your module's entry point is at ./index.js and is designed to be used with a simple:

var someDB = levelup('some_db_name', {db: require('./')});

The test-pouchdb.sh script below lets you to test any client/server combination. So you can test your module as a PouchDB Server backend, PouchDB client backend, or even the widowmaker: both at the same time.

Examples:

Your module in the client, LevelDOWN in the server:

LEVEL_ADAPTER=../../.. npm run test-pouchdb

LevelDOWN in the client, your module in the server:

SERVER=pouchdb-server SERVER_ADAPTER=../../.. npm run test-pouchdb

Your module in the client, your module in the server:

SERVER=pouchdb-server SERVER_ADAPTER=../../.. LEVEL_ADAPTER=../../.. npm run test-pouchdb

If the main entry point to your module is somewhere other than index.js, then change the ../../.. to point to it. (It's relative to node_modules/pouchdb/bin and node_modules/pouchdb-server/bin.)

DB name prefixes

If your *DOWN module takes a URL or filepath as input (e.g. riak:// or mysql:// or whatever), then you will also need to pass in a SERVER_PREFIX as well as a SERVER_ADAPTER:

SERVER_ADAPTER=../../.. SERVER_PREFIX=riak://localhost:8087/ SERVER=pouchdb-server npm run test-pouchdb

In this example, many different databases will be created at e.g. riak://localhost:8087/testdb1, riak://localhost:8087/testdb2, etc.

For the client side, use the LEVEL_PREFIX option instead:

LEVEL_ADAPTER=../../.. LEVEL_PREFIX=riak://localhost:8087/ npm run test-pouchdb

Debugging

Individual tests can be run using GREP:

GREP=somefailingtest LEVEL_ADAPTER=../../.. npm run test-pouchdb

And of course you can always sub in LevelDOWN to see what response the test is expecting, which should help give you a gold standard to code against.

Note that the tests automatically destroy and re-create databases before each individual test, so you don't need to worry about cleaning them up manually.

Browser-based tests

You can also test in the browser, which you might find more convenient for debugging. Keep in mind that this can also hide race conditions, though, since the browser is slower.

You can use either selenium:firefox or selenium:phantomjs.

LevelDOWN in the server, Firefox as the client (another sanity check)

CLIENT=selenium:firefox npm run test-pouchdb

Your module in the server, Firefox as the client:

CLIENT=selenium:firefox SERVER_ARGS='--level-backend ../../..' npm run test-pouchdb

Debugging browser-based tests

For debugging, the easiest way is to start a pouchdb-server running in one tab:

./node_modules/.bin/pouchdb-server -p 6984 --level-backend=../../..

Then run a dev server in PouchDB:

cd ./node_modules/pouchdb
COUCH_HOST=http://localhost:6984 npm run dev

Then open up http://localhost:8000/tests/integration/index.html in your favorite browser. Use ?grep=sometest to grep for a particular test.

More test instructions can be found in pouchdb/CONTRIBUTING.md and pouchdb-server/README.md.

#!/bin/sh
#
# run a single pouchdb test, using pouchdb-server
# in the server running on port 6984
#
./node_modules/.bin/pouchdb-server -p 6984 $SERVER_ARGS &
POUCHDB_SERVER_PID=$!
cd node_modules/pouchdb/
npm install
COUCH_HOST=http://localhost:6984 npm test
EXIT_STATUS=$?
if [[ ! -z $POUCHDB_SERVER_PID ]]; then
kill $POUCHDB_SERVER_PID
fi
exit $EXIT_STATUS
#!/bin/sh
#
# sample script showing all the different ways you can
# test your module against pouchdb
#
# leveldown in the client, leveldown in the server
npm run test-pouchdb
# your module in the client, leveldown in the server
LEVEL_ADAPTER=../../.. npm run test-pouchdb
# leveldown in the client, your module in the server
SERVER_ARGS='--level-backend ../../..' npm run test-pouchdb
# your module in the client, your module in the server
SERVER_ARGS='--level-backend ../../..' LEVEL_ADAPTER=../../.. npm run test-pouchdb
# leveldown in the server, firefox as the client (also available: phantomjs)
CLIENT=selenium:firefox npm run test-pouchdb
# your module in the server, firefox as the client (also available: phantomjs)
CLIENT=selenium:firefox SERVER_ARGS='--level-backend ../../..' npm run test-pouchdb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.