-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP - (pouchdb/express-pouchdb#232) - Modernize pouchdb-list
- Loading branch information
1 parent
d135c6f
commit 5bb5f98
Showing
8 changed files
with
304 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
dist | ||
node_modules | ||
dist | ||
coverage | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
sudo: false | ||
language: node_js | ||
|
||
cache: | ||
directories: | ||
- node_modules | ||
|
||
node_js: | ||
- "0.10" | ||
|
||
services: | ||
- couchdb | ||
|
||
before_install: | ||
- npm i -g npm@^2.0.0 | ||
|
||
before_script: | ||
- npm prune | ||
|
||
script: npm run $COMMAND | ||
|
||
env: | ||
matrix: | ||
- COMMAND='helper -- lint' | ||
- COMMAND='helper -- js-test' | ||
- COMMAND='build' | ||
|
||
#after_success: | ||
# - npm run helper -- semantic-release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,45 @@ | ||
pouchdb-list | ||
============ | ||
|
||
[![Build Status](https://travis-ci.org/pouchdb/pouchdb-list.svg?branch=master)](https://travis-ci.org/pouchdb/pouchdb-list) | ||
[![Dependency Status](https://david-dm.org/pouchdb/pouchdb-list.svg)](https://david-dm.org/pouchdb/pouchdb-list) | ||
[![devDependency Status](https://david-dm.org/pouchdb/pouchdb-list/dev-status.svg)](https://david-dm.org/pouchdb/pouchdb-list#info=devDependencies) | ||
|
||
A PouchDB plug-in that allows you to re-use your CouchDB list functions | ||
on the client side. A browser version is available. | ||
|
||
See also [pouchdb-list's documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-list-plug-in) | ||
TODO: integrate, update & make nice: | ||
```rst | ||
.. _pouchdb-list-plug-in: | ||
PouchDB List plug-in | ||
==================== | ||
+----------------------+-----------------+ | ||
| NodeJS package name: | `pouchdb-list`_ | | ||
+----------------------+-----------------+ | ||
| Browser object name: | ``window.List`` | | ||
+----------------------+-----------------+ | ||
First, make sure you understand how list functions work in CouchDB. A | ||
good start is `the CouchDB guide entry on lists`_. | ||
.. _pouchdb-list: https://www.npmjs.org/package/pouchdb-list | ||
.. _the CouchDB guide entry on lists: http://guide.couchdb.org/draft/transforming.html | ||
.. js:function:: List.list(listPath[, options[, callback]]) | ||
Runs a list function on a view. Both are specified via the | ||
``listPath`` parameter. | ||
:param string listPath: a url of the form | ||
``"designDocName/listFuncName/viewName"`` | ||
:param object options: this object is supplemented with defaults | ||
until a complete `CouchDB request object`_ has been formed, which | ||
is then passed into the list function. | ||
:returns: When succesful, the list function's result in the form of a | ||
`CouchDB response object`_. Otherwise, an error object with one | ||
of the following statuses: 400, 404, 406 or 500. | ||
[Website of this plug-in and a few others](http://python-pouchdb.marten-de-vries.nl/plugins.html) | ||
.. _CouchDB request object: http://docs.couchdb.org/en/latest/json-structure.html#request-object | ||
.. _CouchDB response object: http://docs.couchdb.org/en/latest/json-structure.html#response-object | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,37 @@ | ||
{ | ||
"name": "pouchdb-list", | ||
"version": "1.0.6", | ||
"main": "index.json", | ||
"description": "A PouchDB plug-in that allows you to re-use your CouchDB list functions on the client side.", | ||
"repository": "pouchdb/pouchdb-list", | ||
"homepage": "http://python-pouchdb.marten-de-vries.nl/plugins.html", | ||
"keywords": [ | ||
"pouch", | ||
"pouchdb", | ||
"couch", | ||
"couchdb", | ||
"list", | ||
"design" | ||
], | ||
"license": "Apache-2.0", | ||
"author": "Marten de Vries", | ||
"dependencies": { | ||
"extend": "^1.2.1", | ||
"couchdb-objects": "^1.0.0", | ||
"couchdb-render": "^1.0.0", | ||
"pouchdb-req-http-query": "^1.0.0", | ||
"promise-nodify": "^1.0.0", | ||
"pouchdb-promise": "^0.0.0", | ||
"pouchdb-plugin-error": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^4.1.8", | ||
"uglify-js": "^2.4.13", | ||
"es3ify": "^0.1.3" | ||
}, | ||
"scripts": { | ||
"build-js": "mkdir -p dist && browserify index.js -g es3ify -s List -o dist/pouchdb-list.js", | ||
"build": "npm run build-js; cd dist; uglifyjs pouchdb-list.js -mc > pouchdb-list.min.js" | ||
} | ||
"name": "pouchdb-list", | ||
"version": "1.0.6", | ||
"main": "index.json", | ||
"description": "A PouchDB plug-in that allows you to re-use your CouchDB list functions on the client side.", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/pouchdb/pouchdb-list.git" | ||
}, | ||
"keywords": [ | ||
"pouch", | ||
"pouchdb", | ||
"couch", | ||
"couchdb", | ||
"list", | ||
"design" | ||
], | ||
"license": "Apache-2.0", | ||
"author": "Marten de Vries", | ||
"dependencies": { | ||
"extend": "^1.2.1", | ||
"couchdb-objects": "^1.0.0", | ||
"couchdb-render": "^1.0.0", | ||
"pouchdb-req-http-query": "^1.0.0", | ||
"promise-nodify": "^1.0.0", | ||
"pouchdb-promise": "^0.0.0", | ||
"pouchdb-plugin-error": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"pouchdb-plugin-helper": "^2.0.0" | ||
}, | ||
"scripts": { | ||
"helper": "./node_modules/.bin/pouchdb-plugin-helper", | ||
"test": "npm run helper -- test", | ||
"build": "npm run helper -- build List" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import {setup, teardown, listDocument, shouldThrowError} from './utils'; | ||
|
||
let db; | ||
|
||
describe('Async list tests', () => { | ||
beforeEach(done => { | ||
db = setup(); | ||
function ddocCb() { | ||
db.put({_id: 'testdoc'}, done); | ||
} | ||
db.put(listDocument, ddocCb); | ||
}); | ||
afterEach(teardown); | ||
/* | ||
def testArgs(self): | ||
def cb(err, resp): | ||
head, req = json.loads(resp.body)["args"] | ||
self.assertEqual(head["offset"], 0) | ||
self.assertIsNone(req["id"]) | ||
self.assertEqual(req["query"]["a"], "b") | ||
self._db.list("test/args/ids", cb, query={"a": "b"}) | ||
self.waitUntilCalled(cb) | ||
*/ | ||
}); | ||
|
||
describe('Sync list tests with empty design docs', () => { | ||
beforeEach(async () => { | ||
db = setup(); | ||
await db.put({_id: '_design/test'}); | ||
}); | ||
afterEach(teardown); | ||
|
||
it('test', async () => { | ||
const err = await shouldThrowError(async () => { | ||
await db.list('test/test/test'); | ||
}); | ||
err.status.should.equal(404); | ||
err.name.should.equal('not_found'); | ||
}); | ||
}); | ||
|
||
describe('Sync list tests', () => { | ||
beforeEach(async () => { | ||
db = setup(); | ||
await db.put(listDocument); | ||
await db.put({_id: 'testdoc'}); | ||
}); | ||
afterEach(teardown); | ||
|
||
/* | ||
def testCouchEval(self): | ||
resp = self._db.list("test/test-coucheval/ids") | ||
self.assertEqual(resp["code"], 200) | ||
self.assertEqual(resp["body"], "6 - Hello World!") | ||
def testArgs(self): | ||
resp = self._db.list("test/args/ids", query={"a": "b"}) | ||
head, req = json.loads(resp.body)["args"] | ||
self.assertEqual(head["offset"], 0) | ||
self.assertEqual(head["total_rows"], 1) | ||
self.assertIsNone(req["id"]) | ||
self.assertEqual(req["raw_path"], "/test/_design/test/_list/args/ids?a=b") | ||
self.assertEqual(req["requested_path"], ["test", "_design", "test", "_list", "args", "ids?a=b"]) | ||
self.assertEqual(req["path"], ["test", "_design", "test", "_list", "args", "ids"]) | ||
#and one at random, to check if the rest (shared with show) is still ok. | ||
self.assertEqual(req["peer"], "127.0.0.1") | ||
def testUnexistingDesignDoc(self): | ||
with self.assertRaises(pouchdb.PouchDBError) as cm: | ||
self._db.list("unexisting/args/ids") | ||
self.assertEqual(cm.exception["name"], "not_found") | ||
def testUnexistingListFunc(self): | ||
with self.assertRaises(pouchdb.PouchDBError) as cm: | ||
self._db.list("test/unexisting/ids") | ||
self.assertTrue(str(cm.exception)) | ||
self.assertEqual(cm.exception["name"], "not_found") | ||
self.assertEqual(cm.exception["message"], "missing list function unexisting on design doc _design/test") | ||
def testUnexistingView(self): | ||
with self.assertRaises(pouchdb.PouchDBError) as cm: | ||
self._db.list("test/args/unexisting") | ||
self.assertEqual(cm.exception["name"], "not_found") | ||
def testListApi(self): | ||
resp = self._db.list("test/use-list-api/ids") | ||
self.assertEqual(resp["headers"]["Transfer-Encoding"], "chunked") | ||
self.assertEqual(resp["code"], 500) | ||
row1, row2 = resp.body.split("\n") | ||
self.assertEqual(json.loads(row1), {"id": "testdoc", "key": "testdoc", "value": "value"}) | ||
self.assertEqual(row2, "testHello World!") | ||
def testWrongContentType(self): | ||
"""CouchDB only supports application/json here. It's a CouchDB | ||
restriction: probably best to emulate it... | ||
""" | ||
with self.assertRaises(pouchdb.PouchDBError) as cm: | ||
self._db.list("test/args/ids", headers={"Content-Type": "application/x-www-form-urlencoded"}, body="hello=world") | ||
self.assertEqual(cm.exception["status"], 400) | ||
self.assertEqual(cm.exception["name"], "bad_request") | ||
self.assertEqual(cm.exception["message"], "invalid_json") | ||
*/ | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import {setupHTTP, teardown, listDocument, shouldThrowError, should} from './utils'; | ||
|
||
let db; | ||
|
||
describe('http', () => { | ||
beforeEach(async () => { | ||
db = setupHTTP(); | ||
await db.put(listDocument); | ||
}); | ||
afterEach(teardown); | ||
|
||
it('list basics', async () => { | ||
const resp = await db.list('test/args/ids', {query: {a: 'b'}}); | ||
|
||
const [head, req] = JSON.parse(resp.body).args; | ||
head.offset.should.equal(0); | ||
head.total_rows.should.equal(0); | ||
|
||
should.equal(req.id, null); | ||
req.raw_path.should.equal('/pouchdb-plugin-helper-db/_design/test/_list/args/ids?a=b'); | ||
req.requested_path.should.eql(['pouchdb-plugin-helper-db', '_design', 'test', '_list', 'args', 'ids?a=b']); | ||
req.path.should.eql(['pouchdb-plugin-helper-db', '_design', 'test', '_list', 'args', 'ids']); | ||
// and one at random, to check if the rest (shared with show) is still ok. | ||
req.peer.should.equal('127.0.0.1'); | ||
}); | ||
|
||
it('wrong list content type', async () => { | ||
// CouchDB only supports application/json here. It's a CouchDB restriction: | ||
// this check is here in case it ever changes. - then PouchDB-List's | ||
// simulation of it can stop. | ||
|
||
const err = await shouldThrowError(async () => { | ||
await db.list('test/args/ids', { | ||
headers: {'Content-Type': 'application/x-www-form-urlencoded'}, | ||
body:'value=hello' | ||
}); | ||
}); | ||
err.status.should.equal(400); | ||
err.name.should.equal('bad_request'); | ||
err.message.should.equal('invalid_json'); | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {setup, teardown} from './utils'; | ||
|
||
let db; | ||
|
||
describe('signatures', () => { | ||
beforeEach(() => { | ||
db = setup(); | ||
}); | ||
afterEach(teardown); | ||
it('list', () => { | ||
const promise = db.list('test/test/test', () => {}); | ||
promise.then.should.be.ok; | ||
promise.catch.should.be.ok; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import stuff from 'pouchdb-plugin-helper/testutils'; | ||
import List from '../'; | ||
|
||
stuff.PouchDB.plugin(List); | ||
|
||
stuff.listDocument = { | ||
_id: '_design/test', | ||
views: { | ||
ids: { | ||
map: `function (doc) { | ||
emit(doc._id, "value"); | ||
}` | ||
} | ||
}, | ||
lists: { | ||
args: `function (head, req) { | ||
return toJSON({args: [head, req]}); | ||
}`, | ||
'use-list-api': `function (head, req) { | ||
start({code: 500}); | ||
send(JSON.stringify(getRow())); | ||
send("\\n"); | ||
send("test"); | ||
return "Hello World!"; | ||
}`, | ||
'test-coucheval': `function (head, req) { | ||
var result = sum([1, 2, 3]); | ||
return result + " - " + require("lib/thingy").data; | ||
}` | ||
}, | ||
lib: { | ||
thingy: `exports.data = 'Hello World!';` | ||
} | ||
}; | ||
|
||
module.exports = stuff; |