public void Should_Deserialize_Null()
 {
     Assert.Null(_serializer.Deserialize <string>("null"));
 }
        private async Task ExecuteFromStateAsync(BrowserData state, bool callStart)
        {
            if (callStart)
            {
                var res = await _debot.Client.Debot.FetchAsync(new ParamsOfFetch
                {
                    Address = state.Address
                });

                var serializer  = new TonSerializer();
                var expectedAbi = serializer.Deserialize <JToken>(state.Info.Dabi);
                var actualAbi   = serializer.Deserialize <JToken>(res.Info.Dabi);
                Assert.Equal(expectedAbi, actualAbi);
                if (state.Info != null)
                {
                    Assert.NotNull(res.Info);
                    Assert.Equal(state.Info.Author, res.Info.Author);
                    Assert.Equal(state.Info.Dabi, res.Info.Dabi);
                    Assert.Equal(state.Info.Hello, res.Info.Hello);
                    Assert.Equal(state.Info.Icon, res.Info.Icon);
                    Assert.Equal(state.Info.Interfaces ?? new string[0], res.Info.Interfaces);
                    Assert.Equal(state.Info.Caption, res.Info.Caption);
                    Assert.Equal(state.Info.Language, res.Info.Language);
                    Assert.Equal(state.Info.Name, res.Info.Name);
                    Assert.Equal(state.Info.Publisher, res.Info.Publisher);
                }
                else
                {
                    Assert.Null(res.Info);
                }
            }

            var handle = await FetchDebotAsync(state, state.Address);

            if (callStart)
            {
                await _debot.Client.Debot.StartAsync(new ParamsOfStart
                {
                    DebotHandle = handle.DebotHandle
                });
            }

            while (!state.Finished)
            {
                await HandleMessageQueueAsync(handle, state);

                DebotAction action;
                using (var step = await state.Current.LockAsync())
                {
                    if (!step.Instance.AvailableActions.Any())
                    {
                        break;
                    }

                    using (var next = await state.Next.LockAsync())
                    {
                        step.Instance.Step = next.Instance.RemoveFirst();
                    }

                    step.Instance.Outputs.Clear();
                    action = step.Instance.AvailableActions[step.Instance.Step.Choice - 1];
                }

                _logger.Information($"Executing action {action.Name}");

                await _debot.Client.Debot.ExecuteAsync(new ParamsOfExecute
                {
                    Action      = action,
                    DebotHandle = handle.DebotHandle
                });

                using (var step = await state.Current.LockAsync())
                {
                    var leftArr  = step.Instance.Step.Outputs;
                    var rightArr = step.Instance.Outputs;
                    Assert.Equal(leftArr.Count, rightArr.Count);
                    for (var i = 0; i < leftArr.Count; ++i)
                    {
                        var left  = leftArr[i];
                        var right = rightArr[i];
                        Assert.NotNull(left);
                        Assert.NotNull(right);
                        var pos = left.IndexOf("{}", StringComparison.Ordinal);
                        if (pos >= 0)
                        {
                            Assert.Equal(left.Substring(0, pos), right.Substring(0, pos));
                        }
                        else
                        {
                            Assert.Equal(left, right);
                        }
                    }

                    Assert.Empty(step.Instance.Step.Inputs);
                    Assert.Empty(step.Instance.Step.Invokes);

                    if (!step.Instance.AvailableActions.Any())
                    {
                        break;
                    }
                }
            }

            using (var next = await state.Next.LockAsync())
            {
                Assert.Empty(next.Instance);
            }

            using var terminal = await state.Terminal.LockAsync();

            Assert.Empty(terminal.Instance.Messages);
        }