Comments (18)
@staltz Time.run() is asynchronous, just really fast!
My proposed solution to this is to return a promise from Time.run(), along with supporting callback style.
That would support Ava and a few other common frameworks.
We should also clearly document which testing frameworks are supported.
from time.
I just tested that approach and it works quite good for me:
it('should interact correctly', () => {
const property = forall(diagramArbitrary, diagramArbitrary, (addDiagram, subtractDiagram) => withTime(Time => {
const add$ : Stream<any> = Time.diagram(addDiagram);
const subtract$ : Stream<any> = Time.diagram(subtractDiagram);
const DOM = mockDOMSource({
'.add': { click: add$ },
'.subtract': { click: subtract$ }
});
const app = onionify(App)({ DOM } as any);
const html$ = app.DOM.map(toHtml);
const expected$ = xs.merge(add$.mapTo(+1), subtract$.mapTo(-1))
.fold((acc, curr) => acc + curr, 0)
.map(expectedHTML);
Time.assertEqual(html$, expected$, htmlLooksLike);
}));
return assert(property, testOptions);
});
(this is using the promise version)
from time.
I think Time.run()
is synchronous, so you could drop the async/await. Give it a try
from time.
Thanks guys. It worked for me as shown above. I also created a small DSL for using RxJS marble testing with Ava.
from time.
After having a crack at implementing this, my only concern is that the usage would look like:
Time.run().then(success, fail);
Currently Time.run()
will default to raising errors if no callback is passed. This is to prevent users forgetting to pass a callback and then having tests silently fail. In the above scenario, if the test fails, an error would be raised but fail
would never be called.
So for this to work, we would need to make a breaking change such that Time.run()
will no longer throw an error by default. This is probably fine for tests, as your test will timeout in this scenario anyway.
Another option is to make another run
method that returns a promise.
My current preference is to bite the bullet and make this breaking change, but if anyone has feedback or ideas I'd like to hear it.
from time.
I will have to wrap Time.run()
in a Promise anyway, so if for it
from time.
Regardless of what the API is or should be, why should this library have to support any testing framework specifically?
And AVA can work with callback-based APIs, as well.
from time.
No it should not, but having the choice about API type (callback or promise) is best, see #27
from time.
Regarding the API choice, what I see in the scene is promise-based APIs replacing callback-based APIs. With such small user base, why should we keep the callback API?
from time.
It does not hurt, because the Promise is just wrapping the callback anyway we don't have code duplication
from time.
I now realized Mocha
supports promise style tests as well, which is nice.
I'm generally in favor of dropping callbacks and replacing them with promises.
from time.
:(
Callbacks are supported everywhere.
Have you considered Tape users?
from time.
Is Tape allergic to promises?
from time.
@mightyiam tape-testing/tape#262 (comment)
from time.
Okay, I've been thinking about this a fair bit. My biggest concern with some of the proposed solutions are around providing APIs that allow users to write tests that silently fail or don't run.
For example, if we change Time.run()
to not blow up by default when a user does not pass a callback, there are two different cases where this could go wrong.
When using callback style, if the user forgets to take in the done
callback and pass it to Time.run
.
it('fails silently because the user forgot to take done and pass it in', () => {
const Time = mockTimeSource();
Time.assertEqual(
Time.diagram('---a----b---c---'),
Time.diagram('---x----y---z---')
);
Time.run();
});
Alternatively, if you are using the promise style, if you forget to return the promise the test will fail silently.
This also makes me think about another pattern I have been using. I dislike having to make a Time
instance and call run in every test, so I have been writing tests like this:
it('is fun to write tests with less boilerplate', withTime(Time => {
Time.assertEqual(
Time.diagram('---a----b---c---'),
Time.diagram('---x----y---z---')
);
}));
Where the withTime
helper is defined like this (for callback style tests):
function withTime (test) {
return function (done) {
const Time = mockTimeSource();
test(Time);
Time.run(done);
}
}
We could also make a promise style withTime
:
function withTime (test) {
return function () {
const Time = mockTimeSource();
test(Time);
return promisify(Time.run);
}
}
My proposal is that instead of adding direct promise support, we instead add these helpers, probably two different ones (one for callback style, one for promise style).
This cuts down on potential user error, and removes boilerplate from the tests.
What do y'all think? Any objections to this approach? Can anyone think of a better name than withTime
?
I would ensure that it supports:
- Mocha
- Jest
- Karma
- Tape
- Ava
from time.
Thinking about it more, we could perhaps only have one version that handles both styles automagically. I'll have a play and see if any of the above frameworks get upset if you both attempt to take a callback and return a promise.
from time.
@Widdershin thank you for investigating. Perhaps authors of said frameworks would be kind to advise if you mention them.
from time.
This issue was moved to cyclejs/cyclejs#765
from time.
Related Issues (20)
- README feedback HOT 6
- Export marble diagram images from tests HOT 6
- Expectation of delayed value with start-with value fails HOT 3
- Port xstream#tween to @cycle/time HOT 4
- Support Jasmine's done.fail() HOT 3
- Document behaviour of "simultaneous" value syntax HOT 11
- Export TimeSource type
- Support snapshot style testing with html-looks-like HOT 9
- Make Time.run() return a promise HOT 2
- Add throttleIdleCallback HOT 7
- Write a specification for the marble diagram DSL HOT 3
- Add support for loading extra operators HOT 13
- Allow events to run even when focus is lost HOT 9
- throttleAnimationFrame() HOT 5
- cjs bundle means lodash deps for mocking are pulled in on production apps HOT 4
- Delete code and add moved readme HOT 1
- Move issues and pull request to monorepo HOT 2
- Can you explain why the operators are useful... HOT 1
- Add support for most.js and rxjs HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from time.