jbrumwell / mock-knex

A mock knex adapter for simulating a database during testing
MIT License
240 stars 71 forks source link

Add support for stream() interface #32

Closed mallocator closed 8 years ago

mallocator commented 8 years ago

Thanks for a great library. It has made life so much easier, unfortunately though the current implementation doesn't seem to support the stream interface available through knex:

var stream = knex.select('id').from('table').stream();
stream.on('data', entry => { 'do something with entry'; });
stream.on('error', error => { 'handle error'; });
stream.on('end', () => { 'handle end' });

Responding with a query.response([]) currently results in TypeError: expecting an array, a promise or a thenable.

jbrumwell commented 8 years ago

What version of knex? What version of mock-knex? There is a small unit test for streams https://github.com/colonyamerican/mock-knex/blob/develop/test/tracker.spec.js#L359

mallocator commented 8 years ago

Ah okay, what I'm missing is a way to send data to the mocked stream vie mock-knex. The error is thrown when a stream interface receives a response such as this:

tracker.on('query', query => {
    expect(query.method).to.equal('select');
    query.response([]);
});

knex: 0.11.4 mock-knex: 0.3.2

jbrumwell commented 8 years ago

@mallocator This has been implemented in 0.3.3, if you have time to test it using the branch release/0.3.3 that would be appreciated.

mallocator commented 8 years ago

I'm trying to validate the fix, but somehow the library throws an error that there's no mock function. Has something changed in regards to instantiation since the last version?

Test code:

var knex = require('knex');
var mockKnex = require('mock-knex');

var sql = knex({ 
        client: "sqlite3",
        connection: {
            filename: ":memory:"
        },
});

mockKnex.mock(sql);
jbrumwell commented 8 years ago

@mallocator my apologies if you can pull it again, it should work as expected now.

mallocator commented 8 years ago

I'm getting a lot further like this, but I'm still having issues as to how to emit data events. Can you add an example of how one would go about doing it? query.response doesn't seem to emit any stream events

jbrumwell commented 8 years ago

@mallocator I have expanded the stream test, the important part is to pass the stream option to the response in the query.

it('should support knex#stream method', function streamTest(done) {
        tracker.on('query', function checkResult(query) {
          expect(query.method).to.equal('select');
          query.response([
            {
              columnA : true,
              columnB : 'testing',
              columnC : 1,
            },
          ], {
            stream : true,
          });
        });

        var stream = db.select('columnA', 'columnB', 'columnC')
                       .from('field')
                       .where({
                         'columnA': true
                       })
                       .stream();

        stream.on('data', function(result) {
          expect(result).to.be.a('object');
          expect(result.columnC).to.equal(1);
          expect(result.columnB).to.equal('testing');
          expect(result.columnA).to.equal(true);
          done();
        });
      });
mallocator commented 8 years ago

I can confirm that this works. Thanks a lot for a great tool and great support!

jbrumwell commented 8 years ago

Thank you for taking the time to give it a run :)