Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ class ConsoleApiTest : public JsiIntegrationPortableTestBase<
* Expect a console API call to be reported with parameters matching \param
* paramsMatcher.
*/
void expectConsoleApiCall(Matcher<folly::dynamic> paramsMatcher) {
void expectConsoleApiCall(
Matcher<folly::dynamic> paramsMatcher,
std::source_location location = std::source_location::current()) {
if (runtimeEnabled_) {
expectConsoleApiCallImpl(std::move(paramsMatcher));
expectConsoleApiCallImpl(std::move(paramsMatcher), location);
} else {
expectedConsoleApiCalls_.emplace_back(paramsMatcher);
expectedConsoleApiCalls_.emplace_back(paramsMatcher, location);
}
}

Expand All @@ -103,9 +105,11 @@ class ConsoleApiTest : public JsiIntegrationPortableTestBase<
* paramsMatcher, only if the Runtime domain is currently enabled ( = the call
* is reported in real time).
*/
void expectConsoleApiCallImmediate(Matcher<folly::dynamic> paramsMatcher) {
void expectConsoleApiCallImmediate(
Matcher<folly::dynamic> paramsMatcher,
std::source_location location = std::source_location::current()) {
if (runtimeEnabled_) {
expectConsoleApiCallImpl(std::move(paramsMatcher));
expectConsoleApiCallImpl(std::move(paramsMatcher), location);
}
}

Expand All @@ -115,9 +119,10 @@ class ConsoleApiTest : public JsiIntegrationPortableTestBase<
* call will be buffered and reported later upon enabling the domain).
*/
void expectConsoleApiCallBuffered(
const Matcher<folly::dynamic>& paramsMatcher) {
const Matcher<folly::dynamic>& paramsMatcher,
std::source_location location = std::source_location::current()) {
if (!runtimeEnabled_) {
expectedConsoleApiCalls_.emplace_back(paramsMatcher);
expectedConsoleApiCalls_.emplace_back(paramsMatcher, location);
}
}

Expand Down Expand Up @@ -145,19 +150,23 @@ class ConsoleApiTest : public JsiIntegrationPortableTestBase<
return it->second;
}

void expectConsoleApiCallImpl(Matcher<folly::dynamic> paramsMatcher) {
this->expectMessageFromPage(JsonParsed(AllOf(
AtJsonPtr("/method", "Runtime.consoleAPICalled"),
AtJsonPtr("/params", std::move(paramsMatcher)))));
void expectConsoleApiCallImpl(
Matcher<folly::dynamic> paramsMatcher,
std::source_location location) {
this->expectMessageFromPage(
JsonParsed(AllOf(
AtJsonPtr("/method", "Runtime.consoleAPICalled"),
AtJsonPtr("/params", std::move(paramsMatcher)))),
location);
}

void enableRuntimeDomain() {
InSequence s;
auto executionContextInfo = this->expectMessageFromPage(JsonParsed(
AllOf(AtJsonPtr("/method", "Runtime.executionContextCreated"))));
if (!runtimeEnabled_) {
for (auto& call : expectedConsoleApiCalls_) {
expectConsoleApiCallImpl(call);
for (auto& [call, location] : expectedConsoleApiCalls_) {
expectConsoleApiCallImpl(call, location);
}
expectedConsoleApiCalls_.clear();
}
Expand Down Expand Up @@ -200,7 +209,8 @@ class ConsoleApiTest : public JsiIntegrationPortableTestBase<
}
}

std::vector<Matcher<folly::dynamic>> expectedConsoleApiCalls_;
std::vector<std::pair<Matcher<folly::dynamic>, std::source_location>>
expectedConsoleApiCalls_;
bool runtimeEnabled_{false};
std::unordered_map<std::string, std::string> scriptUrlsById_;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include <gmock/gmock.h>

#pragma once

/**
* A variant of GMOCK_ON_CALL_IMPL that allows specifying the source location as
* a std::source_location parameter.
*/
#define GMOCK_ON_CALL_WITH_SOURCE_LOCATION_IMPL_( \
location, mock_expr, Setter, call) \
((mock_expr).gmock_##call)( \
::testing::internal::GetWithoutMatchers(), nullptr) \
.Setter((location).file_name(), (location).line(), #mock_expr, #call)

/**
* A variant of EXPECT_CALL that allows specifying the source location as a
* std::source_location parameter;
*/
#define EXPECT_CALL_WITH_SOURCE_LOCATION(location, obj, call) \
GMOCK_ON_CALL_WITH_SOURCE_LOCATION_IMPL_( \
location, obj, InternalExpectedAt, call)
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
#include <jsinspector-modern/InspectorInterfaces.h>

#include <memory>
#include <source_location>

#include "FollyDynamicMatchers.h"
#include "GmockHelpers.h"
#include "InspectorMocks.h"
#include "UniquePtrFactory.h"
#include "utils/InspectorFlagOverridesGuard.h"
Expand Down Expand Up @@ -88,13 +90,15 @@ class JsiIntegrationPortableTestBase : public ::testing::Test,
*/
virtual void setupRuntimeBeforeRegistration(jsi::Runtime& /*runtime*/) {}

void connect() {
void connect(
std::source_location location = std::source_location::current()) {
ASSERT_FALSE(toPage_) << "Can only connect once in a JSI integration test.";
toPage_ = page_->connect(remoteConnections_.make_unique());

using namespace ::testing;
// Default to ignoring console messages originating inside the backend.
EXPECT_CALL(
EXPECT_CALL_WITH_SOURCE_LOCATION(
location,
fromPage(),
onMessage(JsonParsed(AllOf(
AtJsonPtr("/method", "Runtime.consoleAPICalled"),
Expand All @@ -103,7 +107,8 @@ class JsiIntegrationPortableTestBase : public ::testing::Test,

// We'll always get an onDisconnect call when we tear
// down the test. Expect it in order to satisfy the strict mock.
EXPECT_CALL(*remoteConnections_[0], onDisconnect());
EXPECT_CALL_WITH_SOURCE_LOCATION(
location, *remoteConnections_[0], onDisconnect());
}

void reload() {
Expand Down Expand Up @@ -146,10 +151,13 @@ class JsiIntegrationPortableTestBase : public ::testing::Test,
*/
template <typename Matcher>
std::shared_ptr<const std::optional<folly::dynamic>> expectMessageFromPage(
Matcher&& matcher) {
Matcher&& matcher,
std::source_location location = std::source_location::current()) {
using namespace ::testing;
ScopedTrace scope(location.file_name(), location.line(), "");
std::shared_ptr result =
std::make_shared<std::optional<folly::dynamic>>(std::nullopt);
EXPECT_CALL(fromPage(), onMessage(matcher))
EXPECT_CALL_WITH_SOURCE_LOCATION(location, fromPage(), onMessage(matcher))
.WillOnce(
([result](auto message) { *result = folly::parseJson(message); }))
.RetiresOnSaturation();
Expand Down Expand Up @@ -188,15 +196,17 @@ class JsiIntegrationPortableTestBase : public ::testing::Test,
JsiIntegrationPortableTestBase<EngineAdapter, Executor>& test_;
};

SecondaryConnection connectSecondary() {
SecondaryConnection connectSecondary(
std::source_location location = std::source_location::current()) {
auto toPage = page_->connect(remoteConnections_.make_unique());

SecondaryConnection secondary{
std::move(toPage), *this, remoteConnections_.objectsVended() - 1};

using namespace ::testing;
// Default to ignoring console messages originating inside the backend.
EXPECT_CALL(
EXPECT_CALL_WITH_SOURCE_LOCATION(
location,
secondary.fromPage(),
onMessage(JsonParsed(AllOf(
AtJsonPtr("/method", "Runtime.consoleAPICalled"),
Expand All @@ -205,7 +215,8 @@ class JsiIntegrationPortableTestBase : public ::testing::Test,

// We'll always get an onDisconnect call when we tear
// down the test. Expect it in order to satisfy the strict mock.
EXPECT_CALL(secondary.fromPage(), onDisconnect());
EXPECT_CALL_WITH_SOURCE_LOCATION(
location, secondary.fromPage(), onDisconnect());

return secondary;
}
Expand Down
Loading
Loading