Skip to content

Commit 864fa7a

Browse files
robhoganfacebook-github-bot
authored andcommitted
Move integration tests to OSS (#43094)
Summary: Pull Request resolved: #43094 Merge the internal `cxxcdp-tester` project into `jsinspector-modern/tests`. Note: These tests still use RN default feature flags and therefore test against the legacy CDP registry - that's addressed in the next diff. Changelog: [Internal] Reviewed By: motiz88 Differential Revision: D53766994
1 parent c02e83c commit 864fa7a

7 files changed

Lines changed: 1036 additions & 0 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "FollyDynamicMatchers.h"
9+
#include "ReactInstanceIntegrationTest.h"
10+
11+
#include <glog/logging.h>
12+
#include <gmock/gmock.h>
13+
#include <gtest/gtest.h>
14+
15+
#include <jsinspector-modern/InspectorInterfaces.h>
16+
17+
namespace facebook::react::jsinspector_modern {
18+
19+
using namespace testing;
20+
21+
TEST_F(ReactInstanceIntegrationTest, ConsoleLogTest) {
22+
InSequence s;
23+
24+
EXPECT_CALL(getRemoteConnection(), onMessage(_))
25+
.Times(2)
26+
.RetiresOnSaturation();
27+
28+
EXPECT_CALL(
29+
getRemoteConnection(),
30+
onMessage(JsonParsed(AllOf(
31+
AtJsonPtr("/params/args/0/value", Eq("Hello, World!")),
32+
AtJsonPtr("/method", Eq("Runtime.consoleAPICalled"))))));
33+
34+
EXPECT_CALL(getRemoteConnection(), onDisconnect());
35+
36+
send("Runtime.enable");
37+
run("console.log('Hello, World!');");
38+
}
39+
40+
} // namespace facebook::react::jsinspector_modern
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "ReactInstanceIntegrationTest.h"
9+
#include "UniquePtrFactory.h"
10+
#include "prelude.js.h"
11+
12+
#include <folly/json.h>
13+
#include <glog/logging.h>
14+
#include <react/runtime/hermes/HermesInstance.h>
15+
16+
namespace facebook::react::jsinspector_modern {
17+
18+
ReactInstanceIntegrationTest::ReactInstanceIntegrationTest()
19+
: runtime(nullptr),
20+
instance(nullptr),
21+
messageQueueThread(std::make_shared<MockMessageQueueThread>()),
22+
errorHandler(std::make_shared<ErrorUtils>()) {}
23+
24+
void ReactInstanceIntegrationTest::SetUp() {
25+
auto mockRegistry = std::make_unique<MockTimerRegistry>();
26+
auto timerManager =
27+
std::make_shared<react::TimerManager>(std::move(mockRegistry));
28+
29+
auto jsErrorHandlingFunc = [](react::MapBuffer error) noexcept {
30+
LOG(INFO) << "Error: \nFile: " << error.getString(react::kFrameFileName)
31+
<< "\nLine: " << error.getInt(react::kFrameLineNumber)
32+
<< "\nColumn: " << error.getInt(react::kFrameColumnNumber)
33+
<< "\nMethod: " << error.getString(react::kFrameMethodName);
34+
};
35+
36+
auto jsRuntimeFactory = std::make_unique<react::HermesInstance>();
37+
std::unique_ptr<react::JSRuntime> runtime_ =
38+
jsRuntimeFactory->createJSRuntime(nullptr, nullptr, messageQueueThread);
39+
jsi::Runtime* jsiRuntime = &runtime_->getRuntime();
40+
41+
// Error handler:
42+
jsiRuntime->global().setProperty(
43+
*jsiRuntime,
44+
"ErrorUtils",
45+
jsi::Object::createFromHostObject(*jsiRuntime, errorHandler));
46+
47+
instance = std::make_unique<react::ReactInstance>(
48+
std::move(runtime_),
49+
messageQueueThread,
50+
timerManager,
51+
std::move(jsErrorHandlingFunc));
52+
timerManager->setRuntimeExecutor(instance->getBufferedRuntimeExecutor());
53+
54+
// JS Environment:
55+
initializeRuntime(preludeJsCode);
56+
57+
// Inspector:
58+
auto& inspector = getInspectorInstance();
59+
auto pages = inspector.getPages();
60+
61+
// We should now have at least a single page once the above runtime has been
62+
// initialized.
63+
assert(pages.size() > 0);
64+
size_t pageId = pages.back().id;
65+
66+
clientToVM_ = inspector.connect(pageId, mockRemoteConnections_.make_unique());
67+
}
68+
69+
void ReactInstanceIntegrationTest::TearDown() {
70+
clientToVM_->disconnect();
71+
}
72+
73+
void ReactInstanceIntegrationTest::initializeRuntime(std::string_view script) {
74+
react::ReactInstance::JSRuntimeFlags flags{
75+
.isProfiling = false,
76+
};
77+
instance->initializeRuntime(flags, [](jsi::Runtime&) {});
78+
79+
messageQueueThread->tick();
80+
81+
std::string init(script);
82+
// JS calls no longer buffered after calling loadScript
83+
instance->loadScript(std::make_unique<react::JSBigStdString>(init), "");
84+
85+
messageQueueThread->flush();
86+
}
87+
88+
void ReactInstanceIntegrationTest::send(
89+
const std::string& method,
90+
const folly::dynamic& params) {
91+
folly::dynamic request = folly::dynamic::object();
92+
93+
request["method"] = method;
94+
request["id"] = id_++;
95+
request["params"] = params;
96+
97+
sendJSONString(folly::toJson(request));
98+
}
99+
100+
void ReactInstanceIntegrationTest::sendJSONString(const std::string& message) {
101+
// The runtime must be initialized and connected to before messaging
102+
clientToVM_->sendMessage(message);
103+
}
104+
105+
jsi::Value ReactInstanceIntegrationTest::run(const std::string& script) {
106+
auto runtimeExecutor = instance->getUnbufferedRuntimeExecutor();
107+
auto ret = jsi::Value::undefined();
108+
109+
runtimeExecutor([script, &ret](jsi::Runtime& rt) {
110+
ret = rt.evaluateJavaScript(
111+
std::make_unique<jsi::StringBuffer>(script), "<test>");
112+
});
113+
114+
messageQueueThread->flush();
115+
116+
while (verbose_ && errorHandler->size() > 0) {
117+
LOG(INFO) << "Error: " << errorHandler->getLastError().getMessage();
118+
}
119+
120+
return ret;
121+
}
122+
123+
bool ReactInstanceIntegrationTest::verbose(bool isVerbose) {
124+
const bool previous = verbose_;
125+
verbose_ = isVerbose;
126+
return previous;
127+
}
128+
129+
} // namespace facebook::react::jsinspector_modern
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <folly/json.h>
11+
#include <gtest/gtest.h>
12+
#include <jsinspector-modern/InspectorInterfaces.h>
13+
#include <memory>
14+
15+
#include "InspectorMocks.h"
16+
#include "UniquePtrFactory.h"
17+
#include "stubs.h"
18+
19+
namespace facebook::react::jsinspector_modern {
20+
21+
class ReactInstanceIntegrationTest : public ::testing::Test {
22+
protected:
23+
ReactInstanceIntegrationTest();
24+
void SetUp() override;
25+
void TearDown() override;
26+
27+
jsi::Value run(const std::string& script);
28+
bool verbose(bool isVerbose);
29+
30+
void send(
31+
const std::string& method,
32+
const folly::dynamic& params = folly::dynamic::object());
33+
void sendJSONString(const std::string& message);
34+
35+
jsi::Runtime* runtime;
36+
std::unique_ptr<react::ReactInstance> instance;
37+
std::shared_ptr<MockMessageQueueThread> messageQueueThread;
38+
std::shared_ptr<ErrorUtils> errorHandler;
39+
40+
MockRemoteConnection& getRemoteConnection() {
41+
return *mockRemoteConnections_[0];
42+
}
43+
44+
private:
45+
void initializeRuntime(std::string_view script);
46+
47+
size_t id_ = 1;
48+
bool verbose_ = false;
49+
UniquePtrFactory<MockRemoteConnection> mockRemoteConnections_;
50+
std::unique_ptr<ILocalConnection> clientToVM_;
51+
};
52+
53+
} // namespace facebook::react::jsinspector_modern
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "ReactInstanceIntegrationTest.h"
9+
10+
#include <glog/logging.h>
11+
#include <gmock/gmock.h>
12+
#include <gtest/gtest.h>
13+
14+
#include <jsinspector-modern/InspectorInterfaces.h>
15+
16+
namespace facebook::react::jsinspector_modern {
17+
18+
using testing::StrEq;
19+
20+
TEST_F(ReactInstanceIntegrationTest, RuntimeEvalTest) {
21+
auto val = run("1 + 2");
22+
EXPECT_EQ(val.asNumber(), 3);
23+
}
24+
25+
} // namespace facebook::react::jsinspector_modern

0 commit comments

Comments
 (0)