1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#define FML_USED_ON_EMBEDDER
6
7#include <functional>
8#include <future>
9#include <memory>
10
11#include "flutter/shell/common/pipeline.h"
12#include "gtest/gtest.h"
13
14namespace flutter {
15namespace testing {
16
17using IntPipeline = Pipeline<int>;
18using Continuation = IntPipeline::ProducerContinuation;
19
20TEST(PipelineTest, ConsumeOneVal) {
21 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(2);
22
23 Continuation continuation = pipeline->Produce();
24
25 const int test_val = 1;
26 bool result = continuation.Complete(std::make_unique<int>(test_val));
27 ASSERT_EQ(result, true);
28
29 PipelineConsumeResult consume_result = pipeline->Consume(
30 [&test_val](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val); });
31
32 ASSERT_EQ(consume_result, PipelineConsumeResult::Done);
33}
34
35TEST(PipelineTest, ContinuationCanOnlyBeUsedOnce) {
36 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(2);
37
38 Continuation continuation = pipeline->Produce();
39
40 const int test_val = 1;
41 bool result = continuation.Complete(std::make_unique<int>(test_val));
42 ASSERT_EQ(result, true);
43
44 PipelineConsumeResult consume_result_1 = pipeline->Consume(
45 [&test_val](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val); });
46
47 result = continuation.Complete(std::make_unique<int>(test_val));
48 ASSERT_EQ(result, false);
49 ASSERT_EQ(consume_result_1, PipelineConsumeResult::Done);
50
51 PipelineConsumeResult consume_result_2 =
52 pipeline->Consume([](std::unique_ptr<int> v) { FAIL(); });
53
54 result = continuation.Complete(std::make_unique<int>(test_val));
55 ASSERT_EQ(result, false);
56 ASSERT_EQ(consume_result_2, PipelineConsumeResult::NoneAvailable);
57}
58
59TEST(PipelineTest, PushingMoreThanDepthCompletesFirstSubmission) {
60 const int depth = 1;
61 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(depth);
62
63 Continuation continuation_1 = pipeline->Produce();
64 Continuation continuation_2 = pipeline->Produce();
65
66 const int test_val_1 = 1, test_val_2 = 2;
67 bool result = continuation_1.Complete(std::make_unique<int>(test_val_1));
68 ASSERT_EQ(result, true);
69 result = continuation_2.Complete(std::make_unique<int>(test_val_2));
70 ASSERT_EQ(result, false);
71
72 PipelineConsumeResult consume_result_1 = pipeline->Consume(
73 [&test_val_1](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val_1); });
74
75 ASSERT_EQ(consume_result_1, PipelineConsumeResult::Done);
76}
77
78TEST(PipelineTest, PushingMultiProcessesInOrder) {
79 const int depth = 2;
80 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(depth);
81
82 Continuation continuation_1 = pipeline->Produce();
83 Continuation continuation_2 = pipeline->Produce();
84
85 const int test_val_1 = 1, test_val_2 = 2;
86 bool result = continuation_1.Complete(std::make_unique<int>(test_val_1));
87 ASSERT_EQ(result, true);
88 result = continuation_2.Complete(std::make_unique<int>(test_val_2));
89 ASSERT_EQ(result, true);
90
91 PipelineConsumeResult consume_result_1 = pipeline->Consume(
92 [&test_val_1](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val_1); });
93 ASSERT_EQ(consume_result_1, PipelineConsumeResult::MoreAvailable);
94
95 PipelineConsumeResult consume_result_2 = pipeline->Consume(
96 [&test_val_2](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val_2); });
97 ASSERT_EQ(consume_result_2, PipelineConsumeResult::Done);
98}
99
100TEST(PipelineTest, ProduceIfEmptyDoesNotConsumeWhenQueueIsNotEmpty) {
101 const int depth = 2;
102 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(depth);
103
104 Continuation continuation_1 = pipeline->Produce();
105 Continuation continuation_2 = pipeline->ProduceIfEmpty();
106
107 const int test_val_1 = 1, test_val_2 = 2;
108 bool result = continuation_1.Complete(std::make_unique<int>(test_val_1));
109 ASSERT_EQ(result, true);
110 result = continuation_2.Complete(std::make_unique<int>(test_val_2));
111 ASSERT_EQ(result, false);
112
113 PipelineConsumeResult consume_result_1 = pipeline->Consume(
114 [&test_val_1](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val_1); });
115 ASSERT_EQ(consume_result_1, PipelineConsumeResult::Done);
116}
117
118TEST(PipelineTest, ProduceIfEmptySuccessfulIfQueueIsEmpty) {
119 const int depth = 1;
120 fml::RefPtr<IntPipeline> pipeline = fml::MakeRefCounted<IntPipeline>(depth);
121
122 Continuation continuation_1 = pipeline->ProduceIfEmpty();
123
124 const int test_val_1 = 1;
125 bool result = continuation_1.Complete(std::make_unique<int>(test_val_1));
126 ASSERT_EQ(result, true);
127
128 PipelineConsumeResult consume_result_1 = pipeline->Consume(
129 [&test_val_1](std::unique_ptr<int> v) { ASSERT_EQ(*v, test_val_1); });
130 ASSERT_EQ(consume_result_1, PipelineConsumeResult::Done);
131}
132
133} // namespace testing
134} // namespace flutter
135