javascript - the use of the RxJS delay operator within Ava tests -
i'm author of javascript program needs executed against number of tests. discovered each of these tests follow similar format , such it's appropriate generate tests using factory function.
the factory function called testfactory , shown in code below. invoked data array which, once application logic added, instruct factory on how build particular test. factory function responsible executing tests well.
i selected rxjs in order achieve 2 second delay if 'delay' string included in data passed factory. (my previous attempt @ implementation used promises, failed @ getting approach working.) can see, accomplished though use of rx delay operator.
ava selected because has reputation of working rxjs. can see, i'm making calls rx subject subscription observable.
in actual application code, subscription makes calls state machine implements application logic , data state machine fed subject through calls next method of subject in callback method on state machine. why i'm not able plug observable directly ava test method, instead have go through subject. subject chosen instead of observable ability of subject allow calls made next , complete methods outside definition.
i have removed application logic code below not confuse issue details. problem comes when 'delay' string removed data array. when code run data not contain delay, test not pass:
const data = [ { r: 'c' }, { l: 'c' }, { l: 'n' }, { l: 'c' } ]; it fails with: test finished without running assertions.
how passing when there no 'delay' in data array? why fail when there no 'delay' in data array? thank you.
const ava = require('ava'); const { test } = ava; const rx = require('rxjs/rx'); const { observable, subject } = rx; const data = [ { r: 'c' }, { l: 'c' }, { l: 'n' }, 'delay', { l: 'c' } ]; const testfactory = (data) => { let subject = new subject(); // code adds delay property each item passes through, adding // delay value based on cumulative delay value maintained scan // operator. items delays marked 'skip' property // in scan , skipped in flatmap. once delay has been performed // delay operator, added delay property deleted. if there // simpler way in rx achieve functionality, i'm open suggestions // on refactoring code. :-) const source = observable.from(data) .scan((acc, val) => { if (val === 'delay') { return { skip: true, delay: acc.delay + 2000 }; } return object.assign(val, { delay: acc.delay }); }, { delay: 0 }) .flatmap((e) => { if (e.skip) { return observable.empty(); } else { return observable.of(e) .delay(e.delay) .map(e => { delete e.delay; return e; }); } }); // subscribe block in application called state // machine. since state machine has been removed, subject called // directly, instead of calling callback tot state machine. // either way, same problem exists. source .subscribe({ next: e => { subject.next(e); }, complete: () => { subject.complete(); } }); // test passes. when 'delay' removed, failure // indicate me never called. test('', t => { // t.plan(1); return subject .map((n) => { t.true(true); }); }); }; testfactory(data); note: interestingly, when import of ava removed along line below imports ava's test function, , call test function replaced regular rxjs subscribe on subject, code works both , without 'delay' string in data structure:
// test('', t => { // // t.plan(1); // return subject // .map((n) => { // t.true(true); // }); // }); subject.subscribe((v) => { console.log(json.stringify(v)); }); does indicate problem use of ava?
i'm not terribly familiar rxjs, observables or subjects, there's clue in test finished without running assertions.
ava tests can synchronous, or asynchronous when return observable, promise, or use test.cb(t => t.end()). ava fails tests if no assertions run before test finishes.
in case, looks ava has determined test synchronous. should make sure it's asynchronous, , end when data consumed.
Comments
Post a Comment