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