It it possible to define a state that transitions to itself in xstate? - state

Consider the following FSM:
{
id: 'my_machine',
initial: 'foo',
states: {
foo: {
on: {
TRIGGER_BAR: 'bar'
}
},
bar: {
on: {
TRIGGER_BAR: 'bar'
TRIGGER_FOO: 'foo'
}
}
}
});
Is it possible for bar to transition to bar again via the TRIGGER_BAR event?

Absolutely! These are called self transitions.
A self-transition is when a state transitions to itself, in which it may exit and then reenter itself. Self-transitions can either be an internal or external transition.
By default all self-transitions are external, so they will exit and re-enter again. Read the docs to see how to change this.
In the example above, you probably wouldn't want to transition to bar again, since there is no context value update. But you could very well have an action created with assign that mutates the context.

Related

Ember Observers getting broken

I have a complex app and we do write test cases for testing.
While writing a test case for one case, we came to know about this issue.
I'm having a file in which two acceptance tests are written, something like this:
module() {
test('acceptance 1', function() {
...logic
}
test('acceptance 2', function() {
...logic
}
}
As we all know, whenever a property changes both beginPropertyChanges and endPropertyChanges function will be called. What happens in my case is, when the acceptance 1 test is running it increments the deferred variable in beginPropertyChanges and due to some error endPropertyChanges haven't triggered. Due to this all observers are getting broken. (As deferred variable will be 1 and not zero)
function beginPropertyChanges() {
deferred++;
suspendedObserverDeactivation();
}
function endPropertyChanges() {
deferred--;
if (deferred <= 0) {
flushSyncObservers();
resumeObserverDeactivation();
}
}
So when acceptance 2 test run, it fails due to observers brokage.
How I can fix this (how to make deferred as zero when test 2 is running) so that test 2 will get passed?

Redux Saga: Throw and stop generator

I'm writing a generator. I'm testing it with RITEway. It checks if window.ethereum is defined. If its not, it should throw and stop. Basically it should satisfy the following tests:
describe('handle initialize Web3 saga', async assert => {
global.window = {}
assert({
given: 'nothing, the window object',
should: 'have no property called Web3',
actual: window.web3,
expected: undefined
})
const gen = cloneableGenerator(handleInitializeWeb3)()
{
// The important parts are in this block scope
const clone = gen.clone()
assert({
given: 'window.ethereum undefined',
should: 'throw',
actual: clone.next().value.message,
expected: '[WARNING]: window.ethereum has no provider!'
})
assert({
given: 'nothing',
should: 'be done',
actual: clone.next().done,
expected: true
})
}
class Provider {}
window.ethereum = new Provider()
// ... more tests
})
Here is how I tried implementing it.
function* handleInitializeWeb3() {
if (!window.ethereum) {
yield new Error('[WARNING]: window.ethereum has no provider!')
}
// ... more yields
}
but this saga doesn't stop. The test where it should: 'be done' fails and the saga gives back the values from the yields outside of the if statement. How can I have these tests pass and the saga stop when the error is thrown?
yielding an error instance acts the same as yielding any other value (i.e. the generator keeps running). If you want to stop the generator you should throw new Error(... like in a normal function.
If for some reason you don't want to throw and do in fact want to yield an error instance and then stop, simply return; after you've yielded the error.

How to unit test Kotlin suspending functions

I follow the MVP pattern + UseCases to interact with a Model layer. This is a method in a Presenter I want to test:
fun loadPreviews() {
launch(UI) {
val items = previewsUseCase.getPreviews() // a suspending function
println("[method] UseCase items: $items")
println("[method] View call")
view.showPreviews(items)
}
}
My simple BDD test:
fun <T> givenSuspended(block: suspend () -> T) = BDDMockito.given(runBlocking { block() })
infix fun <T> BDDMockito.BDDMyOngoingStubbing<T>.willReturn(block: () -> T) = willReturn(block())
#Test
fun `load previews`() {
// UseCase and View are mocked in a `setUp` method
val items = listOf<PreviewItem>()
givenSuspended { previewsUseCase.getPreviews() } willReturn { items }
println("[test] before Presenter call")
runBlocking { presenter.loadPreviews() }
println("[test] after Presenter call")
println("[test] verify the View")
verify(view).showPreviews(items)
}
The test passes successfully but there's something weird in the log. I expect it to be:
"[test] before Presenter call"
"[method] UseCase items: []"
"[method] View call"
"[test] after Presenter call"
"[test] verify the View"
But it turns out to be:
[test] before Presenter call
[test] after Presenter call
[test] verify the View
[method] UseCase items: []
[method] View call
What's the reason of this behaviour and how should I fix it?
I've found out that it's because of a CoroutineDispatcher. I used to mock UI context with EmptyCoroutineContext. Switching to Unconfined has solved the problem
Update 02.04.20
The name of the question suggests that there'll be an exhaustive explanation how to unit test a suspending function. So let me explain a bit more.
The main problem with testing a suspending function is threading. Let's say we want to test this simple function that updates a property's value in a different thread:
class ItemUpdater(val item: Item) {
fun updateItemValue() {
launch(Dispatchers.Default) { item.value = 42 }
}
}
We need to somehow replace Dispatchers.Default with an another dispatcher only for testing purposes. There're two ways how we can do that. Each has its pros and cons, and which one to choose depends on your project & style of coding:
1. Inject a Dispatcher.
class ItemUpdater(
val item: Item,
val dispatcher: CoroutineDispatcher // can be a wrapper that provides multiple dispatchers but let's keep it simple
) {
fun updateItemValue() {
launch(dispatcher) { item.value = 42 }
}
}
// later in a test class
#Test
fun `item value is updated`() = runBlocking {
val item = Item()
val testDispatcher = Dispatchers.Unconfined // can be a TestCoroutineDispatcher but we still keep it simple
val updater = ItemUpdater(item, testDispatcher)
updater.updateItemValue()
assertEquals(42, item.value)
}
2. Substitute a Dispatcher.
class ItemUpdater(val item: Item) {
fun updateItemValue() {
launch(DispatchersProvider.Default) { item.value = 42 } // DispatchersProvider is our own global wrapper
}
}
// later in a test class
// -----------------------------------------------------------------------------------
// --- This block can be extracted into a JUnit Rule and replaced by a single line ---
// -----------------------------------------------------------------------------------
#Before
fun setUp() {
DispatchersProvider.Default = Dispatchers.Unconfined
}
#After
fun cleanUp() {
DispatchersProvider.Default = Dispatchers.Default
}
// -----------------------------------------------------------------------------------
#Test
fun `item value is updated`() = runBlocking {
val item = Item()
val updater = ItemUpdater(item)
updater.updateItemValue()
assertEquals(42, item.value)
}
Both of them are doing the same thing - they replace the original Dispatchers.Default in test classes. The only difference is how they do that. It's really really up to you which of them to choose so don't get biased by my own thoughts below.
IMHO: The first approach is a little too much cumbersome. Injecting dispatchers everywhere will result into polluting most of the classes' constructors with an extra DispatchersWrapper only for a testing purpose. However Google recommends this way at least for now. The second style keeps things simple and it doesn't complicate the production classes. It's like an RxJava's way of testing where you have to substitute schedulers via RxJavaPlugins. By the way, kotlinx-coroutines-test will bring the exact same functionality someday in future.
I see you found out on you own, but I'd like to explain a bit more for the people that might run into the same problem
When you do launch(UI) {}, a new coroutine is created and dispatched to the "UI" Dispatcher, that means that your coroutine now runs on a different thread.
Your runBlocking{} call create a new coroutine, but runBlocking{} will wait for this coroutine to end before continuing, your loadPreviews() function creates a coroutine, start it and then return immediately, so runBlocking() just wait for it and return.
So while runBlocking{} has returned, the coroutine that you created with launch(UI){} is still running in a different thread, that's why the order of your log is messed up
The Unconfined context is a special CoroutineContext that simply create a dispatcher that execute the coroutine right there on the current thread, so now when you execute runBlocking{}, it has to wait for the coroutine created by launch{} to end because it is running on the same thread thus blocking that thread.
I hope my explanation was clear, have a good day

how to write unit test case for both normal callback and q and promise callback?

I have one function in which i have written code to handle callback like this
exports.CallbackExample=function(req,res)
{
return callfunction().then(function(data)
{
saveData(data).save(function(err,responseData)
{
res.send(responseData);
})
});
}
I want to write unit test case for the above code . so i have written like this
var res={};
var spy=res.send=sinon.spy();
CallbackExample(req,res).then(function()
{
expect(spy.calledOnce).to.equal('true');
});
but this is not working. I think the reason is that function has two different callback like first one callback (Q and promises ) and second one is normal callback ....I think may be because of that reason this is not working. I am not able to move forward because of this obstacle . so how to write unit test case for that function with out making any changes in that function ?....is that possible ? ..I hope any one of you will help me. Thanks in advance I am waiting for yours solution ..
IMO, the promises have not chained properly. Resolve it by using Deferred,
exports.CallbackExample=function(req,res) {
return callfunction().then(function(data){
var deferred = Q.defer();
saveData(data).save(function(err,responseData){
if (err) {
deferred.reject(err);
} else {
res.send(responseData);
deferred.resolve(true);
}
});
return deferred.promise;
});
}

How to use `expectAsync2` correctly when writing dart unittest?

I was trying this method expectAsync2, so there was this question: Why the async test passed, but there are some error messages displayed?
But it seems I didn't use it correctly. Is there any good example of expectAsync2?
In the referenced question expectAsync was just used to guard a async call so that the test doesn't end before the call of new Timer(...) finishes.
You can additionally add provide how often (min/max) the method has to be called to satisfy the test.
If your tested functionality calls a method with more than one parameter you use `expectAsync2)
The mistake in your referenced question was, that your call to expectAsyncX was delayed too.
The call to expectAsyncX has to be made before the async functionality is invoked to register which method has to be called.
library x;
import 'dart:async';
import 'package:unittest/unittest.dart';
class SubjectUnderTest {
int i = 0;
doSomething(x, y) {
i++;
print('$x, $y');
}
}
void main(List<String> args) {
test('async test, check a function with 2 parameters', () {
var sut = new SubjectUnderTest();
var fun = expectAsync2(sut.doSomething, count: 2, max: 2, id: 'check doSomething');
new Timer(new Duration(milliseconds:200), () {
fun(1,2);
expect(sut.i, greaterThan(0));
});
new Timer(new Duration(milliseconds:100), () {
fun(3,4);
expect(sut.i, greaterThan(0));
});
});
}
You can check what happens if you set count and max to 3.
You can have a look at the Asynchronous tests section of the article Unit Testing with Dart.