xref: /aosp_15_r20/external/pdfium/fxjs/cfxjs_engine_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2015 The PDFium Authors
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 "fxjs/cfxjs_engine.h"
6 
7 #include "testing/external_engine_embedder_test.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "v8/include/v8-context.h"
10 #include "v8/include/v8-isolate.h"
11 #include "v8/include/v8-local-handle.h"
12 #include "v8/include/v8-object.h"
13 #include "v8/include/v8-value.h"
14 
15 namespace {
16 
17 const double kExpected0 = 6.0;
18 const double kExpected1 = 7.0;
19 const double kExpected2 = 8.0;
20 
21 const wchar_t kScript0[] = L"fred = 6";
22 const wchar_t kScript1[] = L"fred = 7";
23 const wchar_t kScript2[] = L"fred = 8";
24 
25 }  // namespace
26 
27 class CFXJSEngineEmbedderTest : public ExternalEngineEmbedderTest {};
28 
CheckAssignmentInEngineContext(CFXJS_Engine * current_engine,double expected)29 void CheckAssignmentInEngineContext(CFXJS_Engine* current_engine,
30                                     double expected) {
31   v8::Context::Scope context_scope(current_engine->GetV8Context());
32   v8::Local<v8::Object> This = current_engine->GetThisObj();
33   v8::Local<v8::Value> fred = current_engine->GetObjectProperty(This, "fred");
34   EXPECT_TRUE(fred->IsNumber());
35   EXPECT_EQ(expected, current_engine->ToDouble(fred));
36 }
37 
TEST_F(CFXJSEngineEmbedderTest,Getters)38 TEST_F(CFXJSEngineEmbedderTest, Getters) {
39   v8::Isolate::Scope isolate_scope(isolate());
40   v8::HandleScope handle_scope(isolate());
41   v8::Context::Scope context_scope(GetV8Context());
42 
43   absl::optional<IJS_Runtime::JS_Error> err =
44       engine()->Execute(WideString(kScript1));
45   EXPECT_FALSE(err);
46   CheckAssignmentInEngineContext(engine(), kExpected1);
47 }
48 
TEST_F(CFXJSEngineEmbedderTest,MultipleEngines)49 TEST_F(CFXJSEngineEmbedderTest, MultipleEngines) {
50   v8::Isolate::Scope isolate_scope(isolate());
51   v8::HandleScope handle_scope(isolate());
52 
53   CFXJS_Engine engine1(isolate());
54   engine1.InitializeEngine();
55 
56   CFXJS_Engine engine2(isolate());
57   engine2.InitializeEngine();
58 
59   v8::Context::Scope context_scope(GetV8Context());
60   {
61     absl::optional<IJS_Runtime::JS_Error> err =
62         engine()->Execute(WideString(kScript0));
63     EXPECT_FALSE(err);
64     CheckAssignmentInEngineContext(engine(), kExpected0);
65   }
66   {
67     // engine1 executing in engine1's context doesn't affect main.
68     v8::Context::Scope context_scope1(engine1.GetV8Context());
69     absl::optional<IJS_Runtime::JS_Error> err =
70         engine1.Execute(WideString(kScript1));
71     EXPECT_FALSE(err);
72     CheckAssignmentInEngineContext(engine(), kExpected0);
73     CheckAssignmentInEngineContext(&engine1, kExpected1);
74   }
75   {
76     // engine1 executing in engine2's context doesn't affect engine1.
77     v8::Context::Scope context_scope2(engine2.GetV8Context());
78     absl::optional<IJS_Runtime::JS_Error> err =
79         engine1.Execute(WideString(kScript2));
80     EXPECT_FALSE(err);
81     CheckAssignmentInEngineContext(engine(), kExpected0);
82     CheckAssignmentInEngineContext(&engine1, kExpected1);
83     CheckAssignmentInEngineContext(&engine2, kExpected2);
84   }
85   engine1.ReleaseEngine();
86   engine2.ReleaseEngine();
87 }
88 
TEST_F(CFXJSEngineEmbedderTest,JSCompileError)89 TEST_F(CFXJSEngineEmbedderTest, JSCompileError) {
90   v8::Isolate::Scope isolate_scope(isolate());
91   v8::HandleScope handle_scope(isolate());
92   v8::Context::Scope context_scope(GetV8Context());
93 
94   absl::optional<IJS_Runtime::JS_Error> err =
95       engine()->Execute(L"functoon(x) { return x+1; }");
96   EXPECT_TRUE(err);
97   EXPECT_STREQ(L"SyntaxError: Unexpected token '{'", err->exception.c_str());
98   EXPECT_EQ(1, err->line);
99   EXPECT_EQ(12, err->column);
100 }
101 
TEST_F(CFXJSEngineEmbedderTest,JSRuntimeError)102 TEST_F(CFXJSEngineEmbedderTest, JSRuntimeError) {
103   v8::Isolate::Scope isolate_scope(isolate());
104   v8::HandleScope handle_scope(isolate());
105   v8::Context::Scope context_scope(GetV8Context());
106 
107   absl::optional<IJS_Runtime::JS_Error> err =
108       engine()->Execute(L"let a = 3;\nundefined.colour");
109   EXPECT_TRUE(err);
110   EXPECT_EQ(
111       L"TypeError: Cannot read properties of undefined (reading 'colour')",
112       err->exception);
113   EXPECT_EQ(2, err->line);
114   EXPECT_EQ(10, err->column);
115 }
116