xref: /aosp_15_r20/external/pdfium/fxjs/cfxjs_engine_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2018 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cfxjs_engine.h"
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cjs_object.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "testing/fxv8_unittest.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-context.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-isolate.h"
14*3ac0a46fSAndroid Build Coastguard Worker 
15*3ac0a46fSAndroid Build Coastguard Worker class FXJSEngineUnitTest : public FXV8UnitTest {
16*3ac0a46fSAndroid Build Coastguard Worker  public:
17*3ac0a46fSAndroid Build Coastguard Worker   FXJSEngineUnitTest() = default;
18*3ac0a46fSAndroid Build Coastguard Worker   ~FXJSEngineUnitTest() override = default;
19*3ac0a46fSAndroid Build Coastguard Worker 
20*3ac0a46fSAndroid Build Coastguard Worker   // FXV8UnitTest:
SetUp()21*3ac0a46fSAndroid Build Coastguard Worker   void SetUp() override {
22*3ac0a46fSAndroid Build Coastguard Worker     FXV8UnitTest::SetUp();
23*3ac0a46fSAndroid Build Coastguard Worker     FXJS_Initialize(1, isolate());
24*3ac0a46fSAndroid Build Coastguard Worker     engine_ = std::make_unique<CFXJS_Engine>(isolate());
25*3ac0a46fSAndroid Build Coastguard Worker   }
TearDown()26*3ac0a46fSAndroid Build Coastguard Worker   void TearDown() override { FXJS_Release(); }
27*3ac0a46fSAndroid Build Coastguard Worker 
engine() const28*3ac0a46fSAndroid Build Coastguard Worker   CFXJS_Engine* engine() const { return engine_.get(); }
29*3ac0a46fSAndroid Build Coastguard Worker 
30*3ac0a46fSAndroid Build Coastguard Worker  private:
31*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<CFXJS_Engine> engine_;
32*3ac0a46fSAndroid Build Coastguard Worker };
33*3ac0a46fSAndroid Build Coastguard Worker 
34*3ac0a46fSAndroid Build Coastguard Worker static bool perm_created = false;
35*3ac0a46fSAndroid Build Coastguard Worker static bool perm_destroyed = false;
36*3ac0a46fSAndroid Build Coastguard Worker static bool temp_created = false;
37*3ac0a46fSAndroid Build Coastguard Worker static bool temp_destroyed = false;
38*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FXJSEngineUnitTest,GC)39*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FXJSEngineUnitTest, GC) {
40*3ac0a46fSAndroid Build Coastguard Worker   // Reset variables since there might be multiple iterations.
41*3ac0a46fSAndroid Build Coastguard Worker   perm_created = false;
42*3ac0a46fSAndroid Build Coastguard Worker   perm_destroyed = false;
43*3ac0a46fSAndroid Build Coastguard Worker   temp_created = false;
44*3ac0a46fSAndroid Build Coastguard Worker   temp_destroyed = false;
45*3ac0a46fSAndroid Build Coastguard Worker 
46*3ac0a46fSAndroid Build Coastguard Worker   v8::Isolate::Scope isolate_scope(isolate());
47*3ac0a46fSAndroid Build Coastguard Worker   v8::HandleScope handle_scope(isolate());
48*3ac0a46fSAndroid Build Coastguard Worker 
49*3ac0a46fSAndroid Build Coastguard Worker   // Object: 1
50*3ac0a46fSAndroid Build Coastguard Worker   engine()->DefineObj(
51*3ac0a46fSAndroid Build Coastguard Worker       "perm", FXJSOBJTYPE_DYNAMIC,
52*3ac0a46fSAndroid Build Coastguard Worker       [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj,
53*3ac0a46fSAndroid Build Coastguard Worker          v8::Local<v8::Object> proxy) {
54*3ac0a46fSAndroid Build Coastguard Worker         pEngine->SetObjectPrivate(obj,
55*3ac0a46fSAndroid Build Coastguard Worker                                   std::make_unique<CJS_Object>(proxy, nullptr));
56*3ac0a46fSAndroid Build Coastguard Worker         perm_created = true;
57*3ac0a46fSAndroid Build Coastguard Worker       },
58*3ac0a46fSAndroid Build Coastguard Worker       [](v8::Local<v8::Object> obj) {
59*3ac0a46fSAndroid Build Coastguard Worker         perm_destroyed = true;
60*3ac0a46fSAndroid Build Coastguard Worker         CFXJS_Engine::SetObjectPrivate(obj, nullptr);
61*3ac0a46fSAndroid Build Coastguard Worker       });
62*3ac0a46fSAndroid Build Coastguard Worker 
63*3ac0a46fSAndroid Build Coastguard Worker   // Object: 2
64*3ac0a46fSAndroid Build Coastguard Worker   engine()->DefineObj(
65*3ac0a46fSAndroid Build Coastguard Worker       "temp", FXJSOBJTYPE_DYNAMIC,
66*3ac0a46fSAndroid Build Coastguard Worker       [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj,
67*3ac0a46fSAndroid Build Coastguard Worker          v8::Local<v8::Object> proxy) {
68*3ac0a46fSAndroid Build Coastguard Worker         pEngine->SetObjectPrivate(obj,
69*3ac0a46fSAndroid Build Coastguard Worker                                   std::make_unique<CJS_Object>(proxy, nullptr));
70*3ac0a46fSAndroid Build Coastguard Worker         temp_created = true;
71*3ac0a46fSAndroid Build Coastguard Worker       },
72*3ac0a46fSAndroid Build Coastguard Worker       [](v8::Local<v8::Object> obj) {
73*3ac0a46fSAndroid Build Coastguard Worker         temp_destroyed = true;
74*3ac0a46fSAndroid Build Coastguard Worker         CFXJS_Engine::SetObjectPrivate(obj, nullptr);
75*3ac0a46fSAndroid Build Coastguard Worker       });
76*3ac0a46fSAndroid Build Coastguard Worker 
77*3ac0a46fSAndroid Build Coastguard Worker   engine()->InitializeEngine();
78*3ac0a46fSAndroid Build Coastguard Worker 
79*3ac0a46fSAndroid Build Coastguard Worker   v8::Context::Scope context_scope(engine()->GetV8Context());
80*3ac0a46fSAndroid Build Coastguard Worker   v8::Local<v8::Object> perm =
81*3ac0a46fSAndroid Build Coastguard Worker       engine()->NewFXJSBoundObject(1, FXJSOBJTYPE_DYNAMIC);
82*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(perm.IsEmpty());
83*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(perm_created);
84*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(perm_destroyed);
85*3ac0a46fSAndroid Build Coastguard Worker 
86*3ac0a46fSAndroid Build Coastguard Worker   {
87*3ac0a46fSAndroid Build Coastguard Worker     v8::HandleScope inner_handle_scope(isolate());
88*3ac0a46fSAndroid Build Coastguard Worker     v8::Local<v8::Object> temp =
89*3ac0a46fSAndroid Build Coastguard Worker         engine()->NewFXJSBoundObject(2, FXJSOBJTYPE_DYNAMIC);
90*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FALSE(temp.IsEmpty());
91*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_TRUE(temp_created);
92*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FALSE(temp_destroyed);
93*3ac0a46fSAndroid Build Coastguard Worker   }
94*3ac0a46fSAndroid Build Coastguard Worker 
95*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
96*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(err);
97*3ac0a46fSAndroid Build Coastguard Worker 
98*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(perm_created);
99*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(perm_destroyed);
100*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(temp_created);
101*3ac0a46fSAndroid Build Coastguard Worker   // TODO(tsepez): temp_destroyed should be true, but it isnt.
102*3ac0a46fSAndroid Build Coastguard Worker   // EXPECT_TRUE(temp_destroyed);
103*3ac0a46fSAndroid Build Coastguard Worker 
104*3ac0a46fSAndroid Build Coastguard Worker   engine()->ReleaseEngine();
105*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(perm_created);
106*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(perm_destroyed);
107*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(temp_created);
108*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(temp_destroyed);
109*3ac0a46fSAndroid Build Coastguard Worker }
110