Are Jest timer mocks broken in Stencil 1.0.2? - unit-testing

I'm using StencilJS v1.0.2 and it runs unit tests in Jest. I have the following code but it doesn't seem to behave as expected. Am I using the API correctly?
function ok( delay: number ) {
setTimeout(() => {
return 3;
}, delay);
}
test( 'timer', () => {
jest.useFakeTimers();
const result = ok( 1000 );
jest.advanceTimersByTime( 999 );
expect( result ).toBeUndefined();
jest.runAllTimers();
expect( result ).toBe( 3 );
} );
the test should pass but instead it fails on the last expect statement

This line:
const result = ok( 1000 );
...sets result to the return value of ok...
...but ok doesn't return anything so result is always undefined.
So the first expect passes:
expect( result ).toBeUndefined(); // Success!
...but the second expect fails since result will always be undefined:
expect( result ).toBe( 3 ); // <= FAILS since result is always undefined
The issue is that setTimeout just calls the function passed to it.
If the function returns a value then it just gets lost so this line:
return 3;
...doesn't actually do anything.
A simple way to fix the test is to have ok return an object...
...and have the function passed to setTimeout set a property on the object like this:
function ok(delay: number) {
const result: { val?: number } = {};
setTimeout(() => {
result.val = 3; // <= set a property on result
}, delay);
return result;
}
test('timer', () => {
jest.useFakeTimers();
const result = ok(1000);
jest.advanceTimersByTime(999);
expect(result.val).toBeUndefined(); // Success!
jest.runAllTimers();
expect(result.val).toBe(3); // Success!
});

Related

Clearing HasFailure flag in gtest

I have a Unit Test which is used to test if a function works well over a series of input:
TEST_F( something, something) {
std::vector<int> inputFileNumber = { 0, 1 , 2, 3 };
for(auto i : inputFileNumber ) {
res = testMethodOverFile(i);
EXPECT_NEAR(res, results[i], 0.01);
logIfHasFailure(i);
}
}
I would like to know which of the inputs are failing, so I could use ::testing::Test::HasFailure. Unfortunately, once the flag is set, I cannot clear it and all the following indexes are logged as well.
Any ideas?
You should probably use parametrized test instead:
TEST_P( something, something)
{
auto i{GetParam()};
res = testMethodOverFile(i);
EXPECT_NEAR(res, results[i], 0.01);
}
INSTANTIATE_TEST_CASE_P(Default, something, testing::Values(0, 1, 2,3 ));

Unit testing redux-saga task cancellation

I was wondering if anyone had any tips on how to unit-test the following redux-saga login/logout flow:
let pollingTask = null
function * handleLogin () {
try {
const token = yield call(loginHandler)
pollingTask = yield fork(handlePolls, token)
yield put('LOGIN_SUCCSES')
} catch (e) {
yield put('LOGIN_FAILURE')
}
}
function * handlePolls (token) {
while (true) {
try {
yield call(pollHandler, token)
yield put('POLL_SUCCESS')
} catch (e) {
yield put('POLL_FAILURE')
} finally {
if (yield cancelled()) {
yield call(pollCancelled)
}
}
}
}
function * handleLogout () {
try {
yield call(logoutHandler)
yield cancel(pollingTask)
yield put('LOGOUT_SUCCESS')
} catch (e) {
yield put('LOGOUT_FAILURE')
}
}
Since I need to cancel the pollingTask on logout, I tried using createMockTask() in my tests but I always get its value as undefined when I invoke the handleLogout() saga, although I know that my handleLogin() would always be started first and it would initialize the pollingTask.
Any help would be much appreciated!
To make the function go to yield cancelled() you call .return() on the iterator.
An example -
//assuming this saga
function* saga() {
try {
const resp = yield call(someApi)
yield put(action(resp))
} finally {
if(yield cancelled()) {
// handle logic specific to cancellation. For example
yield <some effect>
}
}
}
// test
const gen = saga()
expect(gen.next().value).toEqual(call(someApi))
// simulates cancellation
// gen asking for cancel status
expect(gen.return().value).toEqual( cancelled() )
// answer yes, we've been cancelled
expect(gen.next(true).value).toEqual(<some effect>)
Example taken from https://github.com/redux-saga/redux-saga/issues/266#issuecomment-216087030

IF block inside render function ReactJS

Am newbie to ReactJS. I want to use a IF block inside the render function. While search for this I got result like "You should use ternary operator instead of IF statement". But if I want to use something like,
$.each(array, function(i, x) {
var flag = 0
if({x.a1} || !{x.a2}) {
flag = 1;
<p>true flag enabled</p>
}
<p>...</p>
});
How to convert this statement into JSX syntax or how to use it in React render fucntion.
Thanks in advance.
This link will help you
https://facebook.github.io/react/tips/if-else-in-JSX.html
But I'd use something like this, as its slightly easier to read (IMHO). Note, your array is a prop - passed into the component (or could be a state). I'd use lodash for mapping etc, cause its so useful all over the place (https://lodash.com/)
_renderElements: function(){
return _.map(this.props.array, function(el){
var flag = 0;
return el.a1 || el.a2 ? <p>{'true 1 enabled'}</p> : <p>...</p>;
})
},
render: function () {
return (
{this._renderElements()}
}
);
}
Hope that's helpful.
I do this in one of two ways, depending mostly on how big the if statement is.
one scenario, I don't know if I'm going to render an element or not:
Component = React.createClass({
render() {
var elem;
if (something) {
elem = (<SomeOtherComponent />);
}
return (
<div>{elem}</div>
);
}
});
This is basically a way to either show the element/component or not. If I'm going to map something I would use a separate method and call it:
Component = React.createClass({
mapIt() {
return this.props.items.map(item => {
... do your stuff ...
return (
<SomeOtherComponent prop1={item.value} ... />
);
});
},
render() {
return (
{this.mapIt()}
);
}
});
This to me is a nice clean way of handling.
You want to have your render function look something like this:
render: function () {
return (
{
array.map(function (el, i) {
var flag = 0;
if (el.a1 || el.a2) {
flag = 1;
return <p>true flag enabled</p>;
} else {
return <p>...</p>;
}
}
}
);
}
React allows you to return an array of React elements, so you can map your array and return a JSX element for every element of the array.

getting deprecation error, Do not use `.then` on an instance of Ember.Application.(using mocha-adapter and ember 1.7)

I recently upgraded my ember version from 1.5 to 1.7. Everything is working fine, expect for when I run my tests I get this annoying warning message :
DEPRECATION: Do not use `.then` on an instance of Ember.Application. Please use the `.ready` hook instead.
I am using mocha adapter, but I don't think its anyhow related to the adapter because when I created a simple jsbin using this adapter I did not get any messages. This message shows up when ever in my test I use andThen(function(){ .... }). The call that causes this warning message originates from this function:
//IN ember.js file
function wait(app, value) {
return Test.promise(function(resolve) {
// If this is the first async promise, kick off the async test
if (++countAsync === 1) {
Test.adapter.asyncStart();
}
// Every 10ms, poll for the async thing to have finished
var watcher = setInterval(function() {
// 1. If the router is loading, keep polling
var routerIsLoading = !!app.__container__.lookup('router:main').router.activeTransition;
if (routerIsLoading) { return; }
// 2. If there are pending Ajax requests, keep polling
if (Test.pendingAjaxRequests) { return; }
// 3. If there are scheduled timers or we are inside of a run loop, keep polling
if (run.hasScheduledTimers() || run.currentRunLoop) { return; }
if (Test.waiters && Test.waiters.any(function(waiter) {
var context = waiter[0];
var callback = waiter[1];
return !callback.call(context);
})) { return; }
// Stop polling
clearInterval(watcher);
// If this is the last async promise, end the async test
if (--countAsync === 0) {
Test.adapter.asyncEnd();
}
// Synchronously resolve the promise
run(null, resolve, value);//THIS CAUSES THE WARNING MESSAGE
}, 10);
});
}
and then ends up here which finally gives the warning:
//IN ember.js file
__exports__.inspect = inspect;// The following functions are intentionally minified to keep the functions
// below Chrome's function body size inlining limit of 600 chars.
function apply(t /* target */, m /* method */, a /* args */) {
var l = a && a.length;
if (!a || !l) { return m.call(t); }
switch (l) {
case 1: return m.call(t, a[0]);
case 2: return m.call(t, a[0], a[1]);//this is executed with a[0] as a function that seems like a promise
case 3: return m.call(t, a[0], a[1], a[2]);
case 4: return m.call(t, a[0], a[1], a[2], a[3]);
case 5: return m.call(t, a[0], a[1], a[2], a[3], a[4]);
default: return m.apply(t, a);
}
}
the function that is passed as an argument to case 2 is :
function (value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
resolve(promise, value);
} else {
fulfill(promise, value);
}
}
Any idea how I am avoid getting this warning message. thanks.
UPDATE :
I think I found atleast one of the reasons for this issue which was caused by the registerAsyncHelper. We have a helper written as :
Ember.Test.registerAsyncHelper('clickCheckbox', function(app, selector, context) {
var $el = findWithAssert(selector, context);
Ember.run($el, 'mousedown');
Ember.run($el, 'mouseup');
Ember.run($el, 'click');
// Workaround for IE8 because programmatically clicking a checkbox
// does not fire the "change" event
Ember.run($el, 'change');
return wait(app);
});
so if I don't use this helper, the issue seems to disappear! Also if I were to do return wait() instead of wait(app), things work.

Unit test, Rhino, The art of unit testing

I've started to read "The art of unit testing" and I'm trying to implement this piece of code:
[Test]
public void ReturnResultsFromMock()
{
MockRepository mocks = new MockRepository();
IGetResults resultGetter = mocks.DynamicMock<IGetResults>();
using(mocks.Record())
{
resultGetter.GetSomeNumber("a");//#1
LastCall.Return(1);
resultGetter.GetSomeNumber("a");//#2 how it should work?
LastCall.Return(2);
resultGetter.GetSomeNumber("b");
LastCall.Return(3);
}
int result = resultGetter.GetSomeNumber("b");
Assert.AreEqual(3, result);
int result2 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(1, result2);
int result3 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result3);
}
I get this error message after running my test
AOUT.Loga.Tests.LogAnalyzerTest.ReturnResultsFromMock:
Expected: 2
But was: 1
Looks like you try to implement ordered sequence of calls (see details here):
First you call GetSomeNumber("a") should returns 1
Then call GetSomeNumber("a") again, result will be 2
And only then GetSomeNumber("b"), result will be 3
Is so, try to replace using(mocks.Record()) with using(mocks.Ordered()). But, this will work only in this sequence of calls
At your example, you are using using(mocks.Record()), so every call to GetSomeNumber("a") will return 2 acording to your configuration. You're override first GetSomeNumber("a") by second one. Here are correct assumptions:
int result = resultGetter.GetSomeNumber("b");
Assert.AreEqual(3, result);
int result2 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result2); // every call to GetSomeNumber("a") will returns 2
int result3 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result3);
You may try using the simpler Rhino Mocks AAA syntax, your code will look something like this (take a look also at this question):
// Arrange
var resultGetter = MockRepository.GenerateMock<IGetResults>;
resultGetter.Expect(x => x.GetSomeNumber("b")).Return(3);
resultGetter.Expect(x => x.GetSomeNumber("a")).Return(1).Repeat.Once();
resultGetter.Expect(x => x.GetSomeNumber("b")).Return(2).Repeat.Once();
// Act
int result = resultGetter.GetSomeNumber("b");
// Assert
Assert.AreEqual(3, result);
// Act
int result2 = resultGetter.GetSomeNumber("a");
// Assert
Assert.AreEqual(1, result2);
// Act
int result3 = resultGetter.GetSomeNumber("a");
// Assert
Assert.AreEqual(2, result3);