Flutter Engine
type_conversions_unittests.cc
Go to the documentation of this file.
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 #include "flutter/runtime/dart_vm_lifecycle.h"
6 #include "flutter/testing/dart_isolate_runner.h"
7 #include "flutter/testing/fixture_test.h"
8 #include "flutter/testing/testing.h"
9 #include "flutter/third_party/tonic/converter/dart_converter.h"
10 
11 namespace flutter {
12 namespace testing {
13 
15  public:
17  : settings_(CreateSettingsForFixture()),
18  vm_(DartVMRef::Create(settings_)) {}
19 
20  ~TypeConversionsTest() = default;
21 
22  [[nodiscard]] bool RunWithEntrypoint(const std::string& entrypoint) {
23  if (running_isolate_) {
24  return false;
25  }
26  auto thread = CreateNewThread();
27  TaskRunners single_threaded_task_runner(GetCurrentTestName(), thread,
28  thread, thread, thread);
29  auto isolate =
30  RunDartCodeInIsolate(vm_, settings_, single_threaded_task_runner,
31  entrypoint, {}, GetFixturesPath());
32  if (!isolate || isolate->get()->GetPhase() != DartIsolate::Phase::Running) {
33  return false;
34  }
35 
36  running_isolate_ = std::move(isolate);
37  return true;
38  }
39 
40  private:
41  Settings settings_;
42  DartVMRef vm_;
43  std::unique_ptr<AutoIsolateShutdown> running_isolate_;
44  FML_DISALLOW_COPY_AND_ASSIGN(TypeConversionsTest);
45 };
46 
47 TEST_F(TypeConversionsTest, TestFixture) {
48  ASSERT_TRUE(RunWithEntrypoint("main"));
49 }
50 
51 TEST_F(TypeConversionsTest, CanConvertEmptyList) {
54  "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
55  auto bool_handle = Dart_GetNativeArgument(args, 0);
56  ASSERT_FALSE(tonic::LogIfError(bool_handle));
57  ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
58  event.Signal();
59  }));
61  "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
62  std::vector<int64_t> items;
63  auto items_handle = tonic::ToDart(items);
64  ASSERT_FALSE(tonic::LogIfError(items_handle));
65  tonic::DartInvokeField(::Dart_RootLibrary(), "testCanConvertEmptyList",
66  {items_handle});
67  }));
68  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
69  event.Wait();
70 }
71 
72 TEST_F(TypeConversionsTest, CanConvertListOfStrings) {
75  "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
76  auto bool_handle = Dart_GetNativeArgument(args, 0);
77  ASSERT_FALSE(tonic::LogIfError(bool_handle));
78  ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
79  event.Signal();
80  }));
82  "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
83  std::vector<std::string> items;
84  items.push_back("tinker");
85  items.push_back("tailor");
86  items.push_back("soldier");
87  items.push_back("sailor");
88  auto items_handle = tonic::ToDart(items);
89  ASSERT_FALSE(tonic::LogIfError(items_handle));
90  tonic::DartInvokeField(::Dart_RootLibrary(),
91  "testCanConvertListOfStrings", {items_handle});
92  }));
93  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
94  event.Wait();
95 }
96 
97 TEST_F(TypeConversionsTest, CanConvertListOfDoubles) {
100  "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
101  auto bool_handle = Dart_GetNativeArgument(args, 0);
102  ASSERT_FALSE(tonic::LogIfError(bool_handle));
103  ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
104  event.Signal();
105  }));
107  "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
108  std::vector<double> items;
109  items.push_back(1.0);
110  items.push_back(2.0);
111  items.push_back(3.0);
112  items.push_back(4.0);
113  auto items_handle = tonic::ToDart(items);
114  ASSERT_FALSE(tonic::LogIfError(items_handle));
115  tonic::DartInvokeField(::Dart_RootLibrary(),
116  "testCanConvertListOfDoubles", {items_handle});
117  }));
118  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
119  event.Wait();
120 }
121 
122 TEST_F(TypeConversionsTest, CanConvertListOfInts) {
125  "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
126  auto bool_handle = Dart_GetNativeArgument(args, 0);
127  ASSERT_FALSE(tonic::LogIfError(bool_handle));
128  ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
129  event.Signal();
130  }));
132  "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
133  std::vector<int32_t> items;
134  items.push_back(1);
135  items.push_back(2);
136  items.push_back(3);
137  items.push_back(4);
138  auto items_handle = tonic::ToDart(items);
139  ASSERT_FALSE(tonic::LogIfError(items_handle));
140  tonic::DartInvokeField(::Dart_RootLibrary(), "testCanConvertListOfInts",
141  {items_handle});
142  }));
143  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
144  event.Wait();
145 }
146 
147 TEST_F(TypeConversionsTest, CanConvertListOfFloatsToListOfDartDoubles) {
150  "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
151  auto bool_handle = Dart_GetNativeArgument(args, 0);
152  ASSERT_FALSE(tonic::LogIfError(bool_handle));
153  ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
154  event.Signal();
155  }));
157  "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
158  std::vector<float> items;
159  items.push_back(1.0f);
160  items.push_back(2.0f);
161  items.push_back(3.0f);
162  items.push_back(4.0f);
163  auto items_handle = tonic::ToDart(items);
164  ASSERT_FALSE(tonic::LogIfError(items_handle));
165  // This will fail on type mismatch.
166  tonic::DartInvokeField(::Dart_RootLibrary(),
167  "testCanConvertListOfDoubles", {items_handle});
168  }));
169  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
170  event.Wait();
171 }
172 
173 } // namespace testing
174 } // namespace flutter
G_BEGIN_DECLS FlValue * args
fml::RefPtr< fml::TaskRunner > CreateNewThread(std::string name="")
Creates a new thread, initializes a message loop on it, and, returns its task runner to the unit-test...
Definition: thread_test.cc:26
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition: testing.cc:12
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
Definition: dart_invoke.cc:12
bool RunWithEntrypoint(const std::string &entrypoint)
virtual Settings CreateSettingsForFixture()
Definition: fixture_test.cc:17
#define CREATE_NATIVE_ENTRY(native_entry)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
GdkEventButton * event
Definition: fl_view.cc:62
void AddNativeCallback(std::string name, Dart_NativeFunction callback)
Definition: fixture_test.cc:58
std::unique_ptr< AutoIsolateShutdown > RunDartCodeInIsolate(DartVMRef &vm_ref, const Settings &settings, const TaskRunners &task_runners, std::string entrypoint, const std::vector< std::string > &args, const std::string &fixtures_path, fml::WeakPtr< IOManager > io_manager)
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15