# TOC
   - [db empty](#db-empty)
     - [#get](#db-empty-get)
     - [#put](#db-empty-put)
     - [#update](#db-empty-update)
     - [#push](#db-empty-push)
     - [#move](#db-empty-move)
     - [#del](#db-empty-del)
   - [db small](#db-small)
     - [#get](#db-small-get)
     - [#multiGet](#db-small-multiget)
     - [#get --cached](#db-small-get---cached)
     - [#put](#db-small-put)
     - [#update](#db-small-update)
       - [update requires its data to be an Object](#db-small-update-update-requires-its-data-to-be-an-object)
     - [#del](#db-small-del)
       - [deleting a nonexistent node does not throw an error](#db-small-del-deleting-a-nonexistent-node-does-not-throw-an-error)
     - [#multiDel](#db-small-multidel)
     - [#move](#db-small-move)
       - [move with transform function](#db-small-move-move-with-transform-function)
       - [moving a nonexistent node deletes the target location](#db-small-move-moving-a-nonexistent-node-deletes-the-target-location)
<a name=""></a>
 
<a name="db-empty"></a>
# db empty
<a name="db-empty-get"></a>
## #get
get("/") == null.

```js
db.get('/', function(err, data){
  assert.equal(err, null);
  assert.equal(data, null);
  done();
});
```

get("/xyz") == null.

```js
db.get('/xyz', function(err, data){
  assert.equal(err, null);
  assert.equal(data, null);
  done();
});
```

get("xyz") == null.

```js
db.get('xyz', function(err, data){
  assert.equal(err, null);
  assert.equal(data, null);
  done();
});
```

throws error with invalid parameters.

```js
assert.throws(function() {
  db.get();
});
assert.throws(function() {
  db.get('xyz');
});
assert.throws(function() {
  db.get('abc', 'xyz');
});
assert.throws(function() {
  db.get(function() {});
});
done();
```

<a name="db-empty-put"></a>
## #put
put("/", "value") successfully writes value to /.

```js
db.put('/', 'value', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.equal(data, 'value');
    done();
  });
});
```

put("/x", "value") successfully writes value to /x.

```js
db.put('/x', 'value', function(err){
  assert.equal(err, null);
  db.get('/x', function(err, data){
    assert.equal(err, null);
    assert.equal(data, 'value');
    done();
  });
});
```

put("x", "value") successfully writes value to /x.

```js
db.put('x', 'value', function(err){
  assert.equal(err, null);
  db.get('/x', function(err, data){
    assert.equal(err, null);
    assert.equal(data, 'value');
    done();
  });
});
```

throws error with invalid parameters.

```js
assert.throws(function() {
  db.put();
});
assert.throws(function() {
  db.put('xyz');
});
assert.throws(function() {
  db.put('abc', 'xyz');
});
assert.throws(function() {
  db.put('abc', function() {});
});
assert.throws(function() {
  db.put('abc', undefined, function() {});
});
done();
```

<a name="db-empty-update"></a>
## #update
throws error with invalid parameters.

```js
assert.throws(function() {
  db.update();
});
assert.throws(function() {
  db.update('xyz');
});
assert.throws(function() {
  db.update('abc', 'xyz');
});
assert.throws(function() {
  db.update('abc', function() {});
});
assert.throws(function() {
  db.update('abc', undefined, function() {});
});
done();
```

<a name="db-empty-push"></a>
## #push
push("/", "value") successfully pushes value to /.

```js
db.push('/', 'value', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    
    for (var key in data) {
      assert.equal(data[key], 'value');
    }
    done();
  });
});
```

can successfully push three values to /.

```js
db.push('/', 'value1', function(err){
  assert.equal(err, null);
  db.push('/', 'value2', function(err){
    assert.equal(err, null);
    db.push('/', 'value3', function(err){
      db.get('/', function(err, data){
        assert.equal(err, null);
        var keys = Object.keys(data);
        assert.equal(keys.length, 3);
        
        // Keys of pushed data are ordered chronologically.
        assert.equal(data[keys[0]], 'value1');
        assert.equal(data[keys[1]], 'value2');
        assert.equal(data[keys[2]], 'value3');
        
        done();
      });
    });
  });
});
```

throws error with invalid parameters.

```js
assert.throws(function() {
  db.push();
});
assert.throws(function() {
  db.push('xyz');
});
assert.throws(function() {
  db.push('abc', 'xyz');
});
assert.throws(function() {
  db.push('abc', function() {});
});
done();
```

<a name="db-empty-move"></a>
## #move
throws error with invalid parameters.

```js
assert.throws(function() {
  db.move();
});
assert.throws(function() {
  db.move('xyz');
});
assert.throws(function() {
  db.move('abc', 'xyz');
});
assert.throws(function() {
  db.move('abc', 'xyz', '123');
});
assert.throws(function() {
  db.move('abc', 'xyz', '123', '789');
});
assert.throws(function() {
  db.move(function() {});
});
assert.throws(function() {
  db.move(function() {}, function() {});
});
done();
```

<a name="db-empty-del"></a>
## #del
throws error with invalid parameters.

```js
assert.throws(function() {
  db.del();
});
assert.throws(function() {
  db.del('xyz');
});
assert.throws(function() {
  db.del('abc', 'xyz');
});
assert.throws(function() {
  db.del(function() {});
});
done();
```

<a name="db-small"></a>
# db small
<a name="db-small-get"></a>
## #get
get("/").

```js
db.get('/', function(err, data){
  assert.equal(err, null);
  assert.deepEqual(data, require('./small.json'));
  done();
});
```

get("/a").

```js
db.get('/a', function(err, data){
  assert.equal(err, null);
  assert.notEqual(data, null);
  assert.deepEqual(data, require('./small.json').a);
  done();
});
```

get("/a/ab").

```js
db.get('/a/ab', function(err, data){
  assert.equal(err, null);
  assert.notEqual(data, null);
  assert.deepEqual(data, require('./small.json').a.ab);
  done();
});
```

get("/a/b") == null.

```js
db.get('/a/b', function(err, data){
  assert.equal(err, null);
  assert.equal(data, null);
  done();
});
```

<a name="db-small-multiget"></a>
## #multiGet
multiGet(["/"]).

```js
db.multiGet(['/'], function(err, data){
  assert.equal(err, null);
  assert.deepEqual(data["/"], require('./small.json'));
  done();
});
```

multiGet(["/a","/b"]).

```js
db.multiGet(['/a', '/b'], function(err, data){
  var a = data['/a'];
  var b = data['/b'];
  assert.equal(err, null);
  assert.notEqual(data, null);
  assert.deepEqual(a, require('./small.json').a);
  assert.deepEqual(b, require('./small.json').b);
  done();
});
```

multiGet(["/a/ab","/b/ba", "/c"]).

```js
db.multiGet(['/a/ab', '/b/ba', '/c'], function(err, data){
  var a = data['/a/ab'];
  var b = data['/b/ba'];
  var c = data['/c'];
  assert.equal(err, null);
  assert.notEqual(data, null);
  assert.deepEqual(a, require('./small.json').a.ab);
  assert.deepEqual(b, require('./small.json').b.ba);
  assert.deepEqual(c, require('./small.json').c);
  done();
});
```

<a name="db-small-get---cached"></a>
## #get --cached
get("/").

```js
db.get('/', {cached:true}, function(err, data){
  assert.equal(err, null);
  assert.deepEqual(data, {new_val: "new_val"});
  done();
});
```

<a name="db-small-put"></a>
## #put
put("/", "value") successfully writes value to /.

```js
db.put('/', 'value', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.equal(data, 'value');
    done();
  });
});
```

put("/x", "value").

```js
db.put('/x', 'value', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    var small = _.clone(require('./small.json'));
    small.x = 'value';
    assert.deepEqual(data, small);
    done();
  });
});
```

put("/a", {ab: "value"}) .

```js
db.put('/a', {ab: 'value'}, function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    var small = _.clone(require('./small.json'));
    small.a = {ab: "value"};
    assert.deepEqual(data, small);
    done();
  });
});
```

<a name="db-small-update"></a>
## #update
update("/a", {ab: "value"}) .

```js
db.update('/a', {ab: 'value'}, function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    var small = _.clone(require('./small.json'));
    small.a.ab = "value";
    assert.deepEqual(data, small);
    done();
  });
});
```

<a name="db-small-update-update-requires-its-data-to-be-an-object"></a>
### update requires its data to be an Object
update("/", "just_a_string").

```js
(function(){
  db.update('/', 'value', function(err){});
}).should.throw();
done();
```

<a name="db-small-del"></a>
## #del
del("/").

```js
db.del('/', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.equal(data, null);
    done();
  });
});
```

del("/a") .

```js
db.del('/a', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    var small = _.clone(require('./small.json'));
    delete small.a;
    assert.deepEqual(data, small);
    done();
  });
});
```

<a name="db-small-del-deleting-a-nonexistent-node-does-not-throw-an-error"></a>
### deleting a nonexistent node does not throw an error
del("/a/b") .

```js
db.del('/a/b', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    assert.deepEqual(data, require('./small.json'));
    done();
  });
});
```

<a name="db-small-multidel"></a>
## #multiDel
del(["/"]).

```js
db.multiDel(['/'], function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.equal(data, null);
    done();
  });
});
```

del(["/a", "/b"]).

```js
db.multiDel(['/a', '/b'], function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    var small = _.clone(require('./small.json'));
    delete small.a;
    delete small.b;
    assert.deepEqual(data, small);
    done();
  });
});
```

del(["/a/bc", "/b"]).

```js
db.multiDel(['/a/bc', '/b'], function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    var small = _.clone(require('./small.json'));
    delete small.a.bc;
    delete small.b;
    assert.deepEqual(data, small);
    done();
  });
});
```

<a name="db-small-move"></a>
## #move
move("a", "d").

```js
db.move('a', 'd', function(err){
  assert.equal(err, null);
  db.get('/', function(err, data){
    assert.equal(err, null);
    assert.notEqual(data, null);
    var small = _.clone(require('./small.json'));
    small.d = small.a;
    delete small.a;
    assert.deepEqual(data, small);
    done();
  });
});
```

<a name="db-small-move-move-with-transform-function"></a>
### move with transform function
move("a", "d", transform).

```js
db.move('a', 'd', 
  function transform(data){
    data.aug = 'ment';
    return data;
  },
  function cb(err){
    assert.equal(err, null);
    db.get('/', function(err, data){
      assert.equal(err, null);
      assert.notEqual(data, null);
      var small = _.clone(require('./small.json'));
      small.d = small.a;
      delete small.a;
      small.d.aug = 'ment';
      assert.deepEqual(data, small);
      done();
    });
  }
);
```

<a name="db-small-move-moving-a-nonexistent-node-deletes-the-target-location"></a>
### moving a nonexistent node deletes the target location
move("xyz", "a").

```js
db.move('xyz', 'a', function(err){
  assert.equal(err, null);
  db.get('/a', function(err, data){
    assert.equal(err, null);
    assert.equal(data, null);
    done();
  });
});
```

