1 // Copyright 2017 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/xfa/cfxjse_engine.h"
6 #include "fxjs/xfa/cfxjse_value.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "testing/xfa_js_embedder_test.h"
9 #include "xfa/fxfa/cxfa_eventparam.h"
10
11 class CFXJSE_FormCalcContextEmbedderTest : public XFAJSEmbedderTest {
12 public:
13 CFXJSE_FormCalcContextEmbedderTest() = default;
14 ~CFXJSE_FormCalcContextEmbedderTest() override = default;
15
16 protected:
ExecuteExpectNull(ByteStringView input)17 bool ExecuteExpectNull(ByteStringView input) {
18 return Execute(input) && GetValue()->IsNull();
19 }
20 };
21
22 // TODO(dsinclair): Comment out tests are broken and need to be fixed.
23
TEST_F(CFXJSE_FormCalcContextEmbedderTest,TranslateEmpty)24 TEST_F(CFXJSE_FormCalcContextEmbedderTest, TranslateEmpty) {
25 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
26
27 const char input[] = "";
28 EXPECT_TRUE(Execute(input));
29 // TODO(dsinclair): This should probably throw as a blank formcalc script
30 // is invalid.
31 }
32
TEST_F(CFXJSE_FormCalcContextEmbedderTest,TranslateNumber)33 TEST_F(CFXJSE_FormCalcContextEmbedderTest, TranslateNumber) {
34 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
35
36 const char input[] = "123";
37 EXPECT_TRUE(Execute(input));
38
39 CFXJSE_Value* value = GetValue();
40 EXPECT_TRUE(value->IsInteger());
41 EXPECT_EQ(123, value->ToInteger()) << "Program: " << input;
42 }
43
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Numeric)44 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Numeric) {
45 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
46
47 struct {
48 const char* program;
49 int result;
50 } tests[] = {{"123 + 456", 579},
51 {"2 - 3 * 10 / 2 + 7", -6},
52 {"10 * 3 + 5 * 4", 50},
53 {"(5 - \"abc\") * 3", 15},
54 {"\"100\" / 10e1", 1},
55 {"5 + null + 3", 8},
56 // {"if (\"abc\") then\n"
57 // " 10\n"
58 // "else\n"
59 // " 20\n"
60 // "endif",
61 // 20},
62 // {"3 / 0 + 1", 0},
63 {"-(17)", -17},
64 {"-(-17)", 17},
65 {"+(17)", 17},
66 {"+(-17)", -17},
67 {"if (1 < 2) then\n1\nendif", 1},
68 {"if (\"abc\" > \"def\") then\n"
69 " 1 and 0\n"
70 "else\n"
71 " 0\n"
72 "endif",
73 0}};
74
75 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
76 EXPECT_TRUE(Execute(tests[i].program));
77
78 CFXJSE_Value* value = GetValue();
79 EXPECT_TRUE(value->IsInteger());
80 EXPECT_EQ(tests[i].result, value->ToInteger())
81 << "Program: " << tests[i].program;
82 }
83 }
84
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Strings)85 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Strings) {
86 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
87
88 struct {
89 const char* program;
90 const char* result;
91 } tests[] = {
92 {"\"abc\"", "abc"},
93 {"concat(\"The total is \", 2, \" dollars and \", 57, \" cents.\")",
94 "The total is 2 dollars and 57 cents."}};
95
96 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
97 EXPECT_TRUE(Execute(tests[i].program));
98
99 CFXJSE_Value* value = GetValue();
100 EXPECT_TRUE(value->IsString());
101 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
102 << "Program: " << tests[i].program << " Result: '" << value->ToString()
103 << "'";
104 }
105 }
106
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Booleans)107 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Booleans) {
108 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
109
110 struct {
111 const char* program;
112 bool result;
113 } tests[] = {{"0 and 1 or 2 > 1", true},
114 {"2 < 3 not 1 == 1", false},
115 {"\"abc\" | 2", true},
116 {"1 or 0", true},
117 {"0 | 0", false},
118 {"0 or 1 | 0 or 0", true},
119 {"1 and 0", false},
120 // {"0 & 0", true}, // TODO(dsinclair) Confirm with Reader.
121 {"0 and 1 & 0 and 0", false},
122 {"not(\"true\")", true},
123 {"not(1)", false},
124 {"3 == 3", true},
125 {"3 <> 4", true},
126 {"\"abc\" eq \"def\"", false},
127 {"\"def\" ne \"abc\"", true},
128 {"5 + 5 == 10", true},
129 {"5 + 5 <> \"10\"", false},
130 {"3 < 3", false},
131 {"3 > 4", false},
132 {"\"abc\" <= \"def\"", true},
133 {"\"def\" > \"abc\"", true},
134 {"12 >= 12", true},
135 {"\"true\" < \"false\"", false}};
136
137 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
138 EXPECT_TRUE(Execute(tests[i].program));
139
140 CFXJSE_Value* value = GetValue();
141 EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
142 EXPECT_EQ(tests[i].result, value->ToBoolean())
143 << "Program: " << tests[i].program;
144 }
145 }
146
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Abs)147 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Abs) {
148 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
149
150 struct {
151 const char* program;
152 float result;
153 } tests[] = {{"Abs(1.03)", 1.03f}, {"Abs(-1.03)", 1.03f}, {"Abs(0)", 0.0f}};
154
155 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
156 EXPECT_TRUE(Execute(tests[i].program));
157
158 CFXJSE_Value* value = GetValue();
159 EXPECT_TRUE(value->IsNumber());
160 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
161 << "Program: " << tests[i].program;
162 }
163 }
164
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Avg)165 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Avg) {
166 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
167
168 struct {
169 const char* program;
170 float result;
171 } tests[] = {{"Avg(0, 32, 16)", 16.0f}, {"Avg(2.5, 17, null)", 9.75f}};
172
173 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
174 EXPECT_TRUE(Execute(tests[i].program));
175
176 CFXJSE_Value* value = GetValue();
177 EXPECT_TRUE(value->IsNumber());
178 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
179 << "Program: " << tests[i].program;
180 }
181 }
182
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Ceil)183 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ceil) {
184 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
185
186 struct {
187 const char* program;
188 int result;
189 } tests[] = {{"Ceil(2.5875)", 3}, {"Ceil(-5.9)", -5}, {"Ceil(\"abc\")", 0}};
190
191 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
192 EXPECT_TRUE(Execute(tests[i].program));
193
194 CFXJSE_Value* value = GetValue();
195 EXPECT_TRUE(value->IsInteger());
196 EXPECT_EQ(tests[i].result, value->ToInteger())
197 << "Program: " << tests[i].program;
198 }
199 }
200
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Count)201 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Count) {
202 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
203
204 struct {
205 const char* program;
206 int result;
207 } tests[] = {{"Count(\"Tony\", \"Blue\", 41)", 3}};
208
209 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
210 EXPECT_TRUE(Execute(tests[i].program));
211
212 CFXJSE_Value* value = GetValue();
213 EXPECT_TRUE(value->IsInteger());
214 EXPECT_EQ(tests[i].result, value->ToInteger())
215 << "Program: " << tests[i].program;
216 }
217 }
218
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Floor)219 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Floor) {
220 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
221
222 struct {
223 const char* program;
224 int result;
225 } tests[] = {{"Floor(21.3409873)", 21},
226 {"Floor(5.999965342)", 5},
227 {"Floor(3.2 * 15)", 48}};
228
229 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
230 EXPECT_TRUE(Execute(tests[i].program));
231
232 CFXJSE_Value* value = GetValue();
233 EXPECT_TRUE(value->IsInteger());
234 EXPECT_EQ(tests[i].result, value->ToInteger())
235 << "Program: " << tests[i].program;
236 }
237 }
238
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Max)239 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Max) {
240 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
241
242 struct {
243 const char* program;
244 int result;
245 } tests[] = {{"Max(234, 15, 107)", 234},
246 {"Max(\"abc\", 15, \"Tony Blue\")", 15},
247 {"Max(\"abc\")", 0}};
248
249 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
250 EXPECT_TRUE(Execute(tests[i].program));
251
252 CFXJSE_Value* value = GetValue();
253 EXPECT_TRUE(value->IsInteger());
254 EXPECT_EQ(tests[i].result, value->ToInteger())
255 << "Program: " << tests[i].program;
256 }
257 }
258
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Min)259 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Min) {
260 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
261
262 struct {
263 const char* program;
264 int result;
265 } tests[] = {{"Min(234, 15, 107)", 15},
266 // TODO(dsinclair): Verify with Reader; I believe this should
267 // have a return of 0.
268 // {"Min(\"abc\", 15, \"Tony Blue\")", 15},
269 {"Min(\"abc\")", 0}};
270
271 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
272 EXPECT_TRUE(Execute(tests[i].program));
273
274 CFXJSE_Value* value = GetValue();
275 EXPECT_TRUE(value->IsInteger());
276 EXPECT_EQ(tests[i].result, value->ToInteger())
277 << "Program: " << tests[i].program;
278 }
279 }
280
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Mod)281 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Mod) {
282 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
283
284 struct {
285 const char* program;
286 int result;
287 } tests[] = {{"Mod(64, -3)", 1}, {"Mod(-13, 3)", -1}, {"Mod(\"abc\", 2)", 0}};
288
289 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
290 EXPECT_TRUE(Execute(tests[i].program));
291
292 CFXJSE_Value* value = GetValue();
293 EXPECT_TRUE(value->IsInteger());
294 EXPECT_EQ(tests[i].result, value->ToInteger())
295 << "Program: " << tests[i].program;
296 }
297 }
298
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Round)299 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Round) {
300 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
301
302 struct {
303 const char* program;
304 float result;
305 } tests[] = {{"Round(12.389764537, 4)", 12.3898f},
306 {"Round(20/3, 2)", 6.67f},
307 {"Round(8.9897, \"abc\")", 9.0f},
308 {"Round(FV(400, 0.10/12, 30*12), 2)", 904195.17f}};
309
310 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
311 EXPECT_TRUE(Execute(tests[i].program));
312
313 CFXJSE_Value* value = GetValue();
314 EXPECT_TRUE(value->IsNumber()) << "Program: " << tests[i].program;
315 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
316 << "Program: " << tests[i].program;
317 }
318 }
319
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Sum)320 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Sum) {
321 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
322
323 struct {
324 const char* program;
325 int result;
326 } tests[] = {{"Sum(2, 4, 6, 8)", 20},
327 {"Sum(-2, 4, -6, 8)", 4},
328 {"Sum(4, 16, \"abc\", 19)", 39}};
329
330 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
331 EXPECT_TRUE(Execute(tests[i].program));
332
333 CFXJSE_Value* value = GetValue();
334 EXPECT_TRUE(value->IsInteger());
335 EXPECT_EQ(tests[i].result, value->ToInteger())
336 << "Program: " << tests[i].program;
337 }
338 }
339
340 // TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Date) {
341 // ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
342 //
343 // TODO(dsinclair): Make compatible with windows.
344 // time_t seconds = time(nullptr);
345 // int days = seconds / (60 * 60 * 24);
346
347 // EXPECT_TRUE(Execute("Date()"));
348
349 // CFXJSE_Value* value = GetValue();
350 // EXPECT_TRUE(value->IsNumber());
351 // EXPECT_EQ(days, value->ToInteger());
352 // }
353
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Date2Num)354 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Date2Num) {
355 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
356
357 struct {
358 const char* program;
359 int result;
360 } tests[] = {
361 // {"Date2Num(\"Mar 15, 1996\")", 35138},
362 {"Date2Num(\"1/1/1900\", \"D/M/YYYY\")", 1},
363 {"Date2Num(\"03/15/96\", \"MM/DD/YY\")", 35138},
364 // {"Date2Num(\"Aug 1, 1996\", \"MMM D, YYYY\")", 35277},
365 {"Date2Num(\"96-08-20\", \"YY-MM-DD\", \"fr_FR\")", 35296},
366 {"Date2Num(\"1/3/00\", \"D/M/YY\") - Date2Num(\"1/2/00\", \"D/M/YY\")",
367 29}};
368
369 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
370 EXPECT_TRUE(Execute(tests[i].program));
371
372 CFXJSE_Value* value = GetValue();
373 EXPECT_TRUE(value->IsInteger());
374 EXPECT_EQ(tests[i].result, value->ToInteger())
375 << "Program: " << tests[i].program;
376 }
377 }
378
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DateFmt)379 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DateFmt) {
380 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
381
382 struct {
383 const char* program;
384 const char* result;
385 } tests[] = {
386 // {"DateFmt(1)", "M/D/YY"},
387 // {"DateFmt(2, \"fr_CA\")", "YY-MM-DD"},
388 {"DateFmt(3, \"de_DE\")", "D. MMMM YYYY"},
389 // {"DateFmt(4, \"fr_FR\")", "EEE D' MMMM YYYY"}
390 };
391
392 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
393 EXPECT_TRUE(Execute(tests[i].program));
394
395 CFXJSE_Value* value = GetValue();
396 EXPECT_TRUE(value->IsString());
397 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
398 << "Program: " << tests[i].program << " Result: '" << value->ToString()
399 << "'";
400 }
401 }
402
TEST_F(CFXJSE_FormCalcContextEmbedderTest,IsoDate2Num)403 TEST_F(CFXJSE_FormCalcContextEmbedderTest, IsoDate2Num) {
404 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
405
406 struct {
407 const char* program;
408 int result;
409 } tests[] = {{"IsoDate2Num(\"1900\")", 1},
410 {"IsoDate2Num(\"1900-01\")", 1},
411 {"IsoDate2Num(\"1900-01-01\")", 1},
412 {"IsoDate2Num(\"19960315T20:20:20\")", 35138},
413 {"IsoDate2Num(\"2000-03-01\") - IsoDate2Num(\"20000201\")", 29}};
414
415 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
416 EXPECT_TRUE(Execute(tests[i].program));
417
418 CFXJSE_Value* value = GetValue();
419 EXPECT_TRUE(value->IsInteger());
420 EXPECT_EQ(tests[i].result, value->ToInteger())
421 << "Program: " << tests[i].program;
422 }
423 }
424
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_IsoTime2Num)425 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_IsoTime2Num) {
426 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
427
428 struct {
429 const char* program;
430 int result;
431 } tests[] = {{"IsoTime2Num(\"00:00:00Z\")", 1}};
432
433 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
434 EXPECT_TRUE(Execute(tests[i].program));
435
436 CFXJSE_Value* value = GetValue();
437 EXPECT_TRUE(value->IsInteger());
438 EXPECT_EQ(tests[i].result, value->ToInteger())
439 << "Program: " << tests[i].program;
440 }
441 }
442
TEST_F(CFXJSE_FormCalcContextEmbedderTest,LocalDateFmt)443 TEST_F(CFXJSE_FormCalcContextEmbedderTest, LocalDateFmt) {
444 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
445
446 struct {
447 const char* program;
448 const char* result;
449 } tests[] = {// {"LocalDateFmt(1, \"de_DE\")", "tt.MM.uu"},
450 // {"LocalDateFmt(2, \"fr_CA\")", "aa-MM-jj"},
451 {"LocalDateFmt(3, \"de_CH\")", "t. MMMM jjjj"},
452 {"LocalDateFmt(4, \"fr_FR\")", "EEEE j MMMM aaaa"}};
453
454 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
455 EXPECT_TRUE(Execute(tests[i].program));
456
457 CFXJSE_Value* value = GetValue();
458 EXPECT_TRUE(value->IsString());
459 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
460 << "Program: " << tests[i].program << " Result: '" << value->ToString()
461 << "'";
462 }
463 }
464
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_LocalTimeFmt)465 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_LocalTimeFmt) {
466 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
467
468 struct {
469 const char* program;
470 const char* result;
471 } tests[] = {{"LocalTimeFmt(1, \"de_DE\")", "HH:mm"},
472 {"LocalTimeFmt(2, \"fr_CA\")", "HH:mm::ss"},
473 {"LocalTimeFmt(3, \"de_CH\")", "HH:mm:ss z"},
474 {"LocalTimeFmt(4, \"fr_FR\")", "HH' h 'mm z"}};
475
476 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
477 EXPECT_TRUE(Execute(tests[i].program));
478
479 CFXJSE_Value* value = GetValue();
480 EXPECT_TRUE(value->IsString());
481 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
482 << "Program: " << tests[i].program << " Result: '" << value->ToString()
483 << "'";
484 }
485 }
486
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Num2Date)487 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Num2Date) {
488 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
489
490 struct {
491 const char* program;
492 const char* result;
493 } tests[] = {
494 {"Num2Date(1, \"DD/MM/YYYY\")", "01/01/1900"},
495 {"Num2Date(35139, \"DD-MMM-YYYY\", \"de_DE\")", "16-Mrz-1996"},
496 // {"Num2Date(Date2Num(\"Mar 15, 2000\") - Date2Num(\"98-03-15\", "
497 // "\"YY-MM-DD\", \"fr_CA\"))",
498 // "Jan 1, 1902"}
499 };
500
501 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
502 EXPECT_TRUE(Execute(tests[i].program));
503
504 CFXJSE_Value* value = GetValue();
505 EXPECT_TRUE(value->IsString()) << "Program: " << tests[i].program;
506 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
507 << "Program: " << tests[i].program << " Result: '" << value->ToString()
508 << "'";
509 }
510 }
511
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Num2GMTime)512 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Num2GMTime) {
513 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
514
515 struct {
516 const char* program;
517 const char* result;
518 } tests[] = {// Broken on Windows only.
519 {"Num2GMTime(1, \"HH:MM:SS\")", "00:00:00"},
520 // Below broken on other platforms.
521 {"Num2GMTime(65593001, \"HH:MM:SS Z\")", "18:13:13 GMT"},
522 {"Num2GMTime(43993001, TimeFmt(4, \"de_DE\"), \"de_DE\")",
523 "12.13 Uhr GMT"}};
524
525 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
526 EXPECT_TRUE(Execute(tests[i].program));
527
528 CFXJSE_Value* value = GetValue();
529 EXPECT_TRUE(value->IsString());
530 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
531 << "Program: " << tests[i].program << " Result: '" << value->ToString()
532 << "'";
533 }
534 }
535
536 // TODO(dsinclair): Broken on Mac ...
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Num2Time)537 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Num2Time) {
538 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
539
540 struct {
541 const char* program;
542 const char* result;
543 } tests[] = {{"Num2Time(1, \"HH:MM:SS\")", "00:00:00"}};
544
545 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
546 EXPECT_TRUE(Execute(tests[i].program));
547
548 CFXJSE_Value* value = GetValue();
549 EXPECT_TRUE(value->IsString());
550 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
551 << "Program: " << tests[i].program << " Result: '" << value->ToString()
552 << "'";
553 }
554 }
555
556 // TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Time) {
557 // ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
558 // TODO(dsinclair): Make compatible with windows.
559 // struct timeval tp;
560 // gettimeofday(&tp, nullptr);
561
562 // EXPECT_TRUE(Execute("Time()"));
563
564 // CFXJSE_Value* value = GetValue();
565 // EXPECT_TRUE(value->IsInteger());
566 // EXPECT_EQ(tp.tv_sec * 1000L + tp.tv_usec / 1000, value->ToInteger())
567 // << "Program: Time()";
568 // }
569
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Time2Num)570 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Time2Num) {
571 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
572
573 struct {
574 const char* program;
575 int result;
576 } tests[] = {
577 // {"Time2Num(\"00:00:00 GMT\", \"HH:MM:SS Z\")", 1},
578 {"Time2Num(\"13:13:13 GMT\", \"HH:MM:SS Z\", \"fr_FR\")", 47593001}};
579
580 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
581 EXPECT_TRUE(Execute(tests[i].program));
582
583 CFXJSE_Value* value = GetValue();
584 EXPECT_TRUE(value->IsInteger());
585 EXPECT_EQ(tests[i].result, value->ToInteger())
586 << "Program: " << tests[i].program;
587 }
588 }
589
TEST_F(CFXJSE_FormCalcContextEmbedderTest,TimeFmt)590 TEST_F(CFXJSE_FormCalcContextEmbedderTest, TimeFmt) {
591 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
592
593 struct {
594 const char* program;
595 const char* result;
596 } tests[] = {
597 // {"TimeFmt(1)", "h::MM A"},
598 {"TimeFmt(2, \"fr_CA\")", "HH:MM:SS"},
599 {"TimeFmt(3, \"fr_FR\")", "HH:MM:SS Z"},
600 // {"TimeFmt(4, \"de_DE\")", "H.MM' Uhr 'Z"}
601 };
602
603 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
604 EXPECT_TRUE(Execute(tests[i].program));
605
606 CFXJSE_Value* value = GetValue();
607 EXPECT_TRUE(value->IsString());
608 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
609 << "Program: " << tests[i].program << " Result: '" << value->ToString()
610 << "'";
611 }
612 }
613
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Apr)614 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Apr) {
615 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
616
617 struct {
618 const char* program;
619 float result;
620 } tests[] = {{"Apr(35000, 269.50, 360)", 0.08515404566f},
621 {"Apr(210000 * 0.75, 850 + 110, 25 * 26)", 0.07161332404f}};
622
623 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
624 EXPECT_TRUE(Execute(tests[i].program));
625
626 CFXJSE_Value* value = GetValue();
627 EXPECT_TRUE(value->IsNumber());
628 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
629 << "Program: " << tests[i].program;
630 }
631 }
632
TEST_F(CFXJSE_FormCalcContextEmbedderTest,CTerm)633 TEST_F(CFXJSE_FormCalcContextEmbedderTest, CTerm) {
634 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
635
636 struct {
637 const char* program;
638 float result;
639 } tests[] = {
640 // {"CTerm(0.02, 1000, 100)", 116.2767474515f},
641 {"CTerm(0.10, 500000, 12000)", 39.13224648502f},
642 // {"CTerm(0.0275 + 0.0025, 1000000, 55000 * 0.10)", 176.02226044975f}
643 };
644
645 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
646 EXPECT_TRUE(Execute(tests[i].program));
647
648 CFXJSE_Value* value = GetValue();
649 EXPECT_TRUE(value->IsNumber());
650 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
651 << "Program: " << tests[i].program;
652 }
653 }
654
TEST_F(CFXJSE_FormCalcContextEmbedderTest,FV)655 TEST_F(CFXJSE_FormCalcContextEmbedderTest, FV) {
656 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
657
658 struct {
659 const char* program;
660 float result;
661 } tests[] = {{"FV(400, 0.10 / 12, 30 * 12)", 904195.16991842445f},
662 {"FV(1000, 0.075 / 4, 10 * 4)", 58791.96145535981f}};
663
664 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
665 EXPECT_TRUE(Execute(tests[i].program));
666
667 CFXJSE_Value* value = GetValue();
668 EXPECT_TRUE(value->IsNumber());
669 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
670 << "Program: " << tests[i].program;
671 }
672 }
673
TEST_F(CFXJSE_FormCalcContextEmbedderTest,IPmt)674 TEST_F(CFXJSE_FormCalcContextEmbedderTest, IPmt) {
675 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
676
677 struct {
678 const char* program;
679 float result;
680 } tests[] = {{"IPmt(30000, 0.085, 295.50, 7, 3)", 624.8839283142f},
681 {"IPmt(160000, 0.0475, 980, 24, 12)", 7103.80833569485f},
682 {"IPmt(15000, 0.065, 65.50, 15, 1)", 0.0f}};
683
684 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
685 EXPECT_TRUE(Execute(tests[i].program));
686
687 CFXJSE_Value* value = GetValue();
688 EXPECT_TRUE(value->IsNumber());
689 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
690 << "Program: " << tests[i].program;
691 }
692 }
693
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_NPV)694 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_NPV) {
695 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
696
697 struct {
698 const char* program;
699 float result;
700 } tests[] = {{"NPV(0.065, 5000)", 4694.83568075117f},
701 {"NPV(0.10, 500, 1500, 4000, 10000)", 11529.60863329007f},
702 {"NPV(0.0275 / 12, 50, 60, 40, 100, 25)", 273.14193838457f}};
703
704 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
705 EXPECT_TRUE(Execute(tests[i].program));
706
707 CFXJSE_Value* value = GetValue();
708 EXPECT_TRUE(value->IsNumber()) << "Program: " << tests[i].program;
709 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
710 << "Program: " << tests[i].program;
711 }
712 }
713
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Pmt)714 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Pmt) {
715 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
716
717 struct {
718 const char* program;
719 float result;
720 } tests[] = {// {"Pmt(150000, 0.0475 / 12, 25 * 12)", 855.17604207164f},
721 {"Pmt(25000, 0.085, 12)", 3403.82145169876f}};
722
723 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
724 EXPECT_TRUE(Execute(tests[i].program));
725
726 CFXJSE_Value* value = GetValue();
727 EXPECT_TRUE(value->IsNumber());
728 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
729 << "Program: " << tests[i].program;
730 }
731 }
732
TEST_F(CFXJSE_FormCalcContextEmbedderTest,PPmt)733 TEST_F(CFXJSE_FormCalcContextEmbedderTest, PPmt) {
734 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
735
736 struct {
737 const char* program;
738 float result;
739 } tests[] = {
740 {"PPmt(30000, 0.085, 295.50, 7, 3)", 261.6160716858f},
741 {"PPmt(160000, 0.0475, 980, 24, 12)", 4656.19166430515f},
742 // {"PPmt(15000, 0.065, 65.50, 15, 1)", 0.0f}
743 };
744
745 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
746 EXPECT_TRUE(Execute(tests[i].program));
747
748 CFXJSE_Value* value = GetValue();
749 EXPECT_TRUE(value->IsNumber());
750 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
751 << "Program: " << tests[i].program;
752 }
753 }
754
TEST_F(CFXJSE_FormCalcContextEmbedderTest,PV)755 TEST_F(CFXJSE_FormCalcContextEmbedderTest, PV) {
756 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
757
758 struct {
759 const char* program;
760 float result;
761 } tests[] = {
762 {"PV(400, 0.10 / 12, 30 * 12)", 45580.32799074439f},
763 // {"PV(1000, 0.075 / 4, 10 * 4)", 58791.96145535981f}
764 };
765
766 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
767 EXPECT_TRUE(Execute(tests[i].program));
768
769 CFXJSE_Value* value = GetValue();
770 EXPECT_TRUE(value->IsNumber());
771 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
772 << "Program: " << tests[i].program;
773 }
774 }
775
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Rate)776 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Rate) {
777 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
778
779 struct {
780 const char* program;
781 float result;
782 } tests[] = {{"Rate(12000, 8000, 5)", 0.0844717712f},
783 {"Rate(10000, 0.25 * 5000, 4 * 12)", 0.04427378243f}};
784
785 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
786 EXPECT_TRUE(Execute(tests[i].program));
787
788 CFXJSE_Value* value = GetValue();
789 EXPECT_TRUE(value->IsNumber());
790 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
791 << "Program: " << tests[i].program;
792 }
793 }
794
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Term)795 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Term) {
796 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
797
798 struct {
799 const char* program;
800 float result;
801 } tests[] = {// {"Term(475, .05, 1500)", 3.00477517728f},
802 {"Term(2500, 0.0275 + 0.0025, 5000)", 1.97128786369f}};
803
804 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
805 EXPECT_TRUE(Execute(tests[i].program));
806
807 CFXJSE_Value* value = GetValue();
808 EXPECT_TRUE(value->IsNumber());
809 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
810 << "Program: " << tests[i].program;
811 }
812 }
813
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Choose)814 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Choose) {
815 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
816
817 struct {
818 const char* program;
819 const char* result;
820 } tests[] = {
821 {"Choose(3, \"Taxes\", \"Price\", \"Person\", \"Teller\")", "Person"},
822 {"Choose(2, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", "9"},
823 {"Choose(20/3, \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\")",
824 "F"}};
825
826 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
827 EXPECT_TRUE(Execute(tests[i].program));
828
829 CFXJSE_Value* value = GetValue();
830 EXPECT_TRUE(value->IsString());
831 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
832 << "Program: " << tests[i].program << " Result: '" << value->ToString()
833 << "'";
834 }
835 }
836
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Exists)837 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Exists) {
838 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
839
840 EXPECT_TRUE(Execute("Exists(\"hello world\")"));
841 CFXJSE_Value* value = GetValue();
842 EXPECT_TRUE(value->IsInteger());
843 EXPECT_FALSE(value->ToBoolean());
844 }
845
TEST_F(CFXJSE_FormCalcContextEmbedderTest,HasValue)846 TEST_F(CFXJSE_FormCalcContextEmbedderTest, HasValue) {
847 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
848
849 struct {
850 const char* program;
851 bool result;
852 } tests[] = {{"HasValue(2)", true}, {"HasValue(\" \")", false}};
853
854 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
855 EXPECT_TRUE(Execute(tests[i].program));
856
857 CFXJSE_Value* value = GetValue();
858 EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
859 EXPECT_EQ(tests[i].result, value->ToBoolean())
860 << "Program: " << tests[i].program;
861 }
862 }
863
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Oneof)864 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Oneof) {
865 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
866
867 struct {
868 const char* program;
869 bool result;
870 } tests[] = {
871 {"Oneof(3, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", true},
872 {"Oneof(\"John\", \"Bill\", \"Gary\", \"Joan\", \"John\", \"Lisa\")",
873 true},
874 {"Oneof(3, 1, 25)", false},
875 {"Oneof(3, 3, null)", true},
876 {"Oneof(3, null, null)", false},
877 };
878
879 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
880 EXPECT_TRUE(Execute(tests[i].program));
881
882 CFXJSE_Value* value = GetValue();
883 EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
884 EXPECT_EQ(tests[i].result, value->ToBoolean())
885 << "Program: " << tests[i].program;
886 }
887 }
888
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Within)889 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Within) {
890 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
891
892 struct {
893 const char* program;
894 bool result;
895 } tests[] = {{"Within(\"C\", \"A\", \"D\")", true},
896 {"Within(1.5, 0, 2)", true},
897 {"Within(-1, 0, 2)", false}};
898
899 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
900 EXPECT_TRUE(Execute(tests[i].program));
901
902 CFXJSE_Value* value = GetValue();
903 EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
904 EXPECT_EQ(tests[i].result, value->ToBoolean())
905 << "Program: " << tests[i].program;
906 }
907 }
908
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Eval)909 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Eval) {
910 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
911
912 struct {
913 const char* program;
914 int result;
915 } tests[] = {{"eval(\"10*3+5*4\")", 50}};
916
917 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
918 EXPECT_TRUE(Execute(tests[i].program));
919
920 CFXJSE_Value* value = GetValue();
921 EXPECT_TRUE(value->IsInteger());
922 EXPECT_EQ(tests[i].result, value->ToInteger())
923 << "Program: " << tests[i].program;
924 }
925 }
926
TEST_F(CFXJSE_FormCalcContextEmbedderTest,DISABLED_Null)927 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Null) {
928 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
929
930 struct {
931 const char* program;
932 const char* result;
933 } tests[] = {{"Null()", "null"},
934 {"Concat(\"ABC\", Null(), \"DEF\")", "ABCDEF"}};
935
936 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
937 EXPECT_TRUE(Execute(tests[i].program));
938
939 CFXJSE_Value* value = GetValue();
940 EXPECT_TRUE(value->IsString());
941 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
942 << "Program: " << tests[i].program << " Result: '" << value->ToString()
943 << "'";
944 }
945
946 EXPECT_TRUE(Execute("Null() + 5"));
947
948 CFXJSE_Value* value = GetValue();
949 EXPECT_TRUE(value->IsInteger());
950 EXPECT_EQ(5, value->ToInteger());
951 }
952
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Ref)953 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ref) {
954 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
955
956 struct {
957 const char* program;
958 const char* result;
959 } tests[] = {{"Ref(\"10*3+5*4\")", "10*3+5*4"}, {"Ref(\"hello\")", "hello"}};
960
961 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
962 EXPECT_TRUE(Execute(tests[i].program));
963
964 CFXJSE_Value* value = GetValue();
965 EXPECT_TRUE(value->IsString());
966 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
967 << "Program: " << tests[i].program << " Result: '" << value->ToString()
968 << "'";
969 }
970 }
971
TEST_F(CFXJSE_FormCalcContextEmbedderTest,UnitType)972 TEST_F(CFXJSE_FormCalcContextEmbedderTest, UnitType) {
973 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
974
975 struct {
976 const char* program;
977 const char* result;
978 } tests[] = {{"UnitType(\"36 in\")", "in"},
979 {"UnitType(\"2.54centimeters\")", "cm"},
980 {"UnitType(\"picas\")", "pt"},
981 {"UnitType(\"2.cm\")", "cm"},
982 {"UnitType(\"2.zero cm\")", "in"},
983 {"UnitType(\"kilometers\")", "in"}};
984
985 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
986 EXPECT_TRUE(Execute(tests[i].program));
987
988 CFXJSE_Value* value = GetValue();
989 EXPECT_TRUE(value->IsString());
990 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
991 << "Program: " << tests[i].program << " Result: '" << value->ToString()
992 << "'";
993 }
994 }
995
TEST_F(CFXJSE_FormCalcContextEmbedderTest,UnitValue)996 TEST_F(CFXJSE_FormCalcContextEmbedderTest, UnitValue) {
997 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
998
999 struct {
1000 const char* program;
1001 float result;
1002 } tests[] = {
1003 {"UnitValue(\"2in\")", 2.0f}, {"UnitValue(\"2in\", \"cm\")", 5.08f},
1004 // {"UnitValue(\"6\", \"pt\")", 432f},
1005 // {"UnitType(\"A\", \"cm\")", 0.0f},
1006 // {"UnitType(\"5.08cm\", \"kilograms\")", 2.0f}
1007 };
1008
1009 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1010 EXPECT_TRUE(Execute(tests[i].program));
1011
1012 CFXJSE_Value* value = GetValue();
1013 EXPECT_TRUE(value->IsNumber());
1014 EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
1015 << "Program: " << tests[i].program;
1016 }
1017 }
1018
TEST_F(CFXJSE_FormCalcContextEmbedderTest,At)1019 TEST_F(CFXJSE_FormCalcContextEmbedderTest, At) {
1020 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1021
1022 struct {
1023 const char* program;
1024 int result;
1025 } tests[] = {{"At(\"ABCDEFGH\", \"AB\")", 1},
1026 {"At(\"ABCDEFGH\", \"F\")", 6},
1027 {"At(23412931298471, 29)", 5}};
1028
1029 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1030 EXPECT_TRUE(Execute(tests[i].program));
1031
1032 CFXJSE_Value* value = GetValue();
1033 EXPECT_TRUE(value->IsInteger());
1034 EXPECT_EQ(tests[i].result, value->ToInteger())
1035 << "Program: " << tests[i].program;
1036 }
1037 }
1038
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Concat)1039 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Concat) {
1040 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1041
1042 struct {
1043 const char* program;
1044 const char* result;
1045 } tests[] = {{"Concat(\"ABC\", \"DEF\")", "ABCDEF"},
1046 {"Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue"},
1047 {"Concat(\"You owe \", WordNum(1154.67, 2), \".\")",
1048 "You owe One Thousand One Hundred Fifty-four Dollars And "
1049 "Sixty-seven Cents."}};
1050
1051 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1052 EXPECT_TRUE(Execute(tests[i].program));
1053
1054 CFXJSE_Value* value = GetValue();
1055 EXPECT_TRUE(value->IsString());
1056 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1057 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1058 << "'";
1059 }
1060 }
1061
TEST_F(CFXJSE_FormCalcContextEmbedderTest,Decode)1062 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Decode) {
1063 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1064
1065 struct {
1066 const char* program;
1067 const char* result;
1068 } tests[] = {
1069 // HTML
1070 {R"(Decode("", "html"))", ""},
1071 {R"(Decode("abcÂxyz", "html"))", "abc\xC3\x82xyz"},
1072 {R"(Decode("abc&NoneSuchButVeryLongIndeed;", "html"))", "abc"},
1073 {R"(Decode("AÆÁ", "html"))", "A\xC3\x86\xC3\x81"},
1074 {R"(Decode("xyz&#", "html"))", "xyz"},
1075 {R"(Decode("|&zzzzzz;|", "html"))", "||"},
1076
1077 // XML
1078 {R"(Decode("", "xml"))", ""},
1079 {R"(Decode("~!@#$%%^&*()_+|`", "xml"))", "~!@#$%%^&*()_+|`"},
1080 {R"(Decode("abc&nonesuchbutverylongindeed;", "xml"))", "abc"},
1081 {R"(Decode(""E<>[].'", "xml"))", "\"E<>[].'"},
1082 {R"(Decode("xyz&#", "xml"))", "xyz"},
1083 {R"(Decode("|&zzzzzz;|", "xml"))", "||"},
1084
1085 // URL
1086 {R"(Decode("", "url"))", ""},
1087 {R"(Decode("~%26^&*()_+|`{", "url"))", "~&^&*()_+|`{"},
1088 {R"(Decode("~%26^&*()_+|`{", "mbogo"))", "~&^&*()_+|`{"},
1089 {R"(Decode("~%26^&*()_+|`{"))", "~&^&*()_+|`{"},
1090 {R"(Decode("~%~~"))", ""},
1091 {R"(Decode("?%~"))", ""},
1092 {R"(Decode("?%"))", "?"},
1093 };
1094
1095 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1096 EXPECT_TRUE(Execute(tests[i].program));
1097 CFXJSE_Value* value = GetValue();
1098 EXPECT_TRUE(value->IsString());
1099 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1100 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1101 << "'";
1102 }
1103 }
1104
1105 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Encode) {
1106 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1107
1108 struct {
1109 const char* program;
1110 const char* result;
1111 } tests[] = {
1112 {"Encode(\"X/~&^*<=>?|\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
1113 {"Encode(\"X/~&^*<=>?|\", \"mbogo\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
1114 {"Encode(\"X/~&^*<=>?|\", \"url\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
1115 {"Encode(\"X/~&^*<=>?|\", \"xml\")", "X/~&^*<=>?|"},
1116 {"Encode(\"X/~&^*<=>?|\", \"html\")", "X/~&^*<=>?|"},
1117
1118 {"Encode(\"\\u0022\\u00f5\\ufed0\", \"url\")", "%22%f5%fe%d0"},
1119 {"Encode(\"\\u0022\\u00f4\\ufed0\", \"xml\")", ""ôﻐ"},
1120 {"Encode(\"\\u0022\\u00f5\\ufed0\", \"html\")", ""õﻐ"},
1121
1122 #if !defined(OS_WIN)
1123 // Windows wchar_t isn't wide enough to handle these anyways.
1124 // TODO(tsepez): fix surrogate encodings.
1125 {"Encode(\"\\uD83D\\uDCA9\", \"url\")", "%01%f4%a9"},
1126 {"Encode(\"\\uD83D\\uDCA9\", \"xml\")", ""},
1127 {"Encode(\"\\uD83D\\uDCA9\", \"html\")", ""},
1128 #endif // !defined(OS_WIN)
1129 };
1130
1131 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1132 EXPECT_TRUE(Execute(tests[i].program));
1133
1134 CFXJSE_Value* value = GetValue();
1135 EXPECT_TRUE(value->IsString());
1136 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1137 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1138 << "'";
1139 }
1140 }
1141
1142 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Format) {
1143 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1144
1145 struct {
1146 const char* program;
1147 const char* result;
1148 } tests[] = {{"Format(\"MMM D, YYYY\", \"20020901\")", "Sep 1, 2002"},
1149 {"Format(\"$9,999,999.99\", 1234567.89)", "$1,234,567.89"}};
1150
1151 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1152 EXPECT_TRUE(Execute(tests[i].program));
1153
1154 CFXJSE_Value* value = GetValue();
1155 EXPECT_TRUE(value->IsString());
1156 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1157 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1158 << "'";
1159 }
1160 }
1161
1162 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Left) {
1163 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1164
1165 struct {
1166 const char* program;
1167 const char* result;
1168 } tests[] = {{"Left(\"ABCDEFGH\", 3)", "ABC"},
1169 {"Left(\"Tony Blue\", 5)", "Tony "}};
1170
1171 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1172 EXPECT_TRUE(Execute(tests[i].program));
1173
1174 CFXJSE_Value* value = GetValue();
1175 EXPECT_TRUE(value->IsString());
1176 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1177 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1178 << "'";
1179 }
1180 }
1181
1182 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Len) {
1183 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1184
1185 struct {
1186 const char* program;
1187 int result;
1188 } tests[] = {
1189 {"Len(\"ABCDEFGH\")", 8}, {"Len(4)", 1}, {"Len(Str(4.532, 6, 4))", 6}};
1190
1191 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1192 EXPECT_TRUE(Execute(tests[i].program));
1193
1194 CFXJSE_Value* value = GetValue();
1195 EXPECT_TRUE(value->IsInteger());
1196 EXPECT_EQ(tests[i].result, value->ToInteger())
1197 << "Program: " << tests[i].program;
1198 }
1199 }
1200
1201 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Lower) {
1202 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1203
1204 struct {
1205 const char* program;
1206 const char* result;
1207 } tests[] = {{"Lower(\"ABC\")", "abc"},
1208 {"Lower(\"21 Main St.\")", "21 main st."},
1209 {"Lower(15)", "15"}};
1210
1211 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1212 EXPECT_TRUE(Execute(tests[i].program));
1213
1214 CFXJSE_Value* value = GetValue();
1215 EXPECT_TRUE(value->IsString());
1216 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1217 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1218 << "'";
1219 }
1220 }
1221
1222 // This is testing for an OOB read, so will likely only fail under ASAN.
1223 TEST_F(CFXJSE_FormCalcContextEmbedderTest, bug_854623) {
1224 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1225
1226 const uint8_t test_string[] = {
1227 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x28, 0x22, 0xc3,
1228 0x85, 0xc3, 0x85, 0xc3, 0x85, 0x22, 0x29}; // Lower("ÅÅÅ")
1229 Execute(ByteString(test_string, sizeof(test_string)).AsStringView());
1230 }
1231
1232 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ltrim) {
1233 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1234
1235 struct {
1236 const char* program;
1237 const char* result;
1238 } tests[] = {{"Ltrim(\" ABCD\")", "ABCD"},
1239 {"Ltrim(Rtrim(\" Tony Blue \"))", "Tony Blue"}};
1240
1241 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1242 EXPECT_TRUE(Execute(tests[i].program));
1243
1244 CFXJSE_Value* value = GetValue();
1245 EXPECT_TRUE(value->IsString());
1246 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1247 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1248 << "'";
1249 }
1250 }
1251
1252 TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Parse) {
1253 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1254
1255 struct {
1256 const char* program;
1257 const char* result;
1258 } tests[] = {{"Parse(\"MMM D, YYYY\", \"Sep 1, 2002\")", "2002-09-01"}};
1259
1260 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1261 EXPECT_TRUE(Execute(tests[i].program));
1262
1263 CFXJSE_Value* value = GetValue();
1264 EXPECT_TRUE(value->IsString());
1265 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1266 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1267 << "'";
1268 }
1269
1270 EXPECT_TRUE(Execute("Parse(\"$9,999,999.99\", \"$1,234,567.89\")"));
1271 CFXJSE_Value* value = GetValue();
1272 EXPECT_TRUE(value->IsNumber());
1273 EXPECT_FLOAT_EQ(1234567.89f, value->ToFloat());
1274 }
1275
1276 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Replace) {
1277 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1278
1279 struct {
1280 const char* program;
1281 const char* result;
1282 } tests[] = {{"Replace(\"Tony Blue\", \"Tony\", \"Chris\")", "Chris Blue"},
1283 {"Replace(\"ABCDEFGH\", \"D\")", "ABCEFGH"},
1284 {"Replace(\"ABCDEFGH\", \"d\")", "ABCDEFGH"}};
1285
1286 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1287 EXPECT_TRUE(Execute(tests[i].program));
1288
1289 CFXJSE_Value* value = GetValue();
1290 EXPECT_TRUE(value->IsString());
1291 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1292 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1293 << "'";
1294 }
1295 }
1296
1297 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Right) {
1298 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1299
1300 struct {
1301 const char* program;
1302 const char* result;
1303 } tests[] = {{"Right(\"ABCDEFGH\", 3)", "FGH"},
1304 {"Right(\"Tony Blue\", 5)", " Blue"}};
1305
1306 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1307 EXPECT_TRUE(Execute(tests[i].program));
1308
1309 CFXJSE_Value* value = GetValue();
1310 EXPECT_TRUE(value->IsString());
1311 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1312 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1313 << "'";
1314 }
1315 }
1316
1317 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Rtrim) {
1318 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1319
1320 struct {
1321 const char* program;
1322 const char* result;
1323 } tests[] = {{"Rtrim(\"ABCD \")", "ABCD"},
1324 {"Rtrim(\"Tony Blue \t\")", "Tony Blue"}};
1325
1326 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1327 EXPECT_TRUE(Execute(tests[i].program));
1328
1329 CFXJSE_Value* value = GetValue();
1330 EXPECT_TRUE(value->IsString());
1331 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1332 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1333 << "'";
1334 }
1335 }
1336
1337 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Space) {
1338 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1339
1340 struct {
1341 const char* program;
1342 const char* result;
1343 } tests[] = {{"Space(5)", " "},
1344 {"Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue"}};
1345
1346 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1347 EXPECT_TRUE(Execute(tests[i].program));
1348
1349 CFXJSE_Value* value = GetValue();
1350 EXPECT_TRUE(value->IsString());
1351 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1352 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1353 << "'";
1354 }
1355 }
1356
1357 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Str) {
1358 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1359
1360 struct {
1361 const char* program;
1362 const char* result;
1363 } tests[] = {{"Str(2.456)", " 2"},
1364 {"Str(4.532, 6, 4)", "4.5320"},
1365 {"Str(234.458, 4)", " 234"},
1366 {"Str(31.2345, 4, 2)", "****"}};
1367
1368 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1369 EXPECT_TRUE(Execute(tests[i].program));
1370
1371 CFXJSE_Value* value = GetValue();
1372 EXPECT_TRUE(value->IsString());
1373 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1374 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1375 << "'";
1376 }
1377 }
1378
1379 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Stuff) {
1380 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1381
1382 struct {
1383 const char* program;
1384 const char* result;
1385 } tests[] = {{"Stuff(\"TonyBlue\", 5, 0, \" \")", "Tony Blue"},
1386 {"Stuff(\"ABCDEFGH\", 4, 2)", "ABCFGH"},
1387 {"Stuff(\"members-list@myweb.com\", 0, 0, \"cc:\")",
1388 "cc:members-list@myweb.com"}};
1389
1390 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1391 EXPECT_TRUE(Execute(tests[i].program));
1392
1393 CFXJSE_Value* value = GetValue();
1394 EXPECT_TRUE(value->IsString());
1395 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1396 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1397 << "'";
1398 }
1399 }
1400
1401 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Substr) {
1402 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1403
1404 // Test wrong number of parameters.
1405 EXPECT_FALSE(Execute("Substr()"));
1406 EXPECT_FALSE(Execute("Substr(1)"));
1407 EXPECT_FALSE(Execute("Substr(1, 2)"));
1408 EXPECT_FALSE(Execute("Substr(1, 2, 3, 4)"));
1409
1410 // Test null input.
1411 EXPECT_TRUE(ExecuteExpectNull("Substr(null, 0, 4)"));
1412 EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", null, 4)"));
1413 EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", 0, null)"));
1414 EXPECT_TRUE(ExecuteExpectNull("Substr(null, null, 4)"));
1415 EXPECT_TRUE(ExecuteExpectNull("Substr(null, 0, null)"));
1416 EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", null, null)"));
1417 EXPECT_TRUE(ExecuteExpectNull("Substr(null, null, null)"));
1418
1419 struct {
1420 const char* program;
1421 const char* result;
1422 } static const kTests[] = {{"Substr(\"ABCDEFG\", -1, 4)", "ABCD"},
1423 {"Substr(\"ABCDEFG\", 0, 4)", "ABCD"},
1424 {"Substr(\"ABCDEFG\", 3, 4)", "CDEF"},
1425 {"Substr(\"ABCDEFG\", 4, 4)", "DEFG"},
1426 {"Substr(\"ABCDEFG\", 5, 4)", "EFG"},
1427 {"Substr(\"ABCDEFG\", 6, 4)", "FG"},
1428 {"Substr(\"ABCDEFG\", 7, 4)", "G"},
1429 {"Substr(\"ABCDEFG\", 8, 4)", ""},
1430 {"Substr(\"ABCDEFG\", 5, -1)", ""},
1431 {"Substr(\"ABCDEFG\", 5, 0)", ""},
1432 {"Substr(\"ABCDEFG\", 5, 1)", "E"},
1433 {"Substr(\"abcdefghi\", 5, 3)", "efg"},
1434 {"Substr(3214, 2, 1)", "2"},
1435 {"Substr(\"21 Waterloo St.\", 4, 5)", "Water"}};
1436
1437 for (const auto& test : kTests) {
1438 EXPECT_TRUE(Execute(test.program));
1439
1440 CFXJSE_Value* value = GetValue();
1441 EXPECT_TRUE(value->IsString());
1442 EXPECT_STREQ(test.result, value->ToString().c_str())
1443 << "Program: " << test.program << " Result: '" << value->ToString()
1444 << "'";
1445 }
1446 }
1447
1448 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Uuid) {
1449 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1450
1451 EXPECT_TRUE(Execute("Uuid()"));
1452
1453 CFXJSE_Value* value = GetValue();
1454 EXPECT_TRUE(value->IsString());
1455 }
1456
1457 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Upper) {
1458 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1459
1460 struct {
1461 const char* program;
1462 const char* result;
1463 } tests[] = {{"Upper(\"abc\")", "ABC"},
1464 {"Upper(\"21 Main St.\")", "21 MAIN ST."},
1465 {"Upper(15)", "15"}};
1466
1467 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1468 EXPECT_TRUE(Execute(tests[i].program));
1469
1470 CFXJSE_Value* value = GetValue();
1471 EXPECT_TRUE(value->IsString());
1472 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1473 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1474 << "'";
1475 }
1476 }
1477
1478 TEST_F(CFXJSE_FormCalcContextEmbedderTest, WordNum) {
1479 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1480
1481 struct {
1482 const char* program;
1483 const char* result;
1484 } tests[] = {
1485 // {"WordNum(123.45)",
1486 // "One Hundred and Twenty-three"}, // This looks like it's wrong in the
1487 // // Formcalc document.
1488 // {"WordNum(123.45, 1)", "One Hundred and Twenty-three Dollars"},
1489 {"WordNum(1154.67, 2)",
1490 "One Thousand One Hundred Fifty-four Dollars And Sixty-seven Cents"},
1491 {"WordNum(43, 2)", "Forty-three Dollars And Zero Cents"}};
1492
1493 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1494 EXPECT_TRUE(Execute(tests[i].program));
1495
1496 CFXJSE_Value* value = GetValue();
1497 EXPECT_TRUE(value->IsString());
1498 EXPECT_STREQ(tests[i].result, value->ToString().c_str())
1499 << "Program: " << tests[i].program << " Result: '" << value->ToString()
1500 << "'";
1501 }
1502 }
1503
1504 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Get) {
1505 // TODO(dsinclair): Is this supported?
1506 }
1507
1508 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Post) {
1509 // TODO(dsinclair): Is this supported?
1510 }
1511
1512 TEST_F(CFXJSE_FormCalcContextEmbedderTest, Put) {
1513 // TODO(dsinclair): Is this supported?
1514 }
1515
1516 TEST_F(CFXJSE_FormCalcContextEmbedderTest, InvalidFunctions) {
1517 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1518
1519 const char* const tests[] = {
1520 "F()",
1521 "()",
1522 "()()()",
1523 "Round(2.0)()",
1524 };
1525
1526 for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
1527 EXPECT_FALSE(ExecuteSilenceFailure(tests[i]));
1528 }
1529 }
1530
1531 TEST_F(CFXJSE_FormCalcContextEmbedderTest, MethodCall) {
1532 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1533
1534 const char test[] = {"$form.form1.TextField11.getAttribute(\"h\")"};
1535 EXPECT_TRUE(Execute(test));
1536
1537 CFXJSE_Value* value = GetValue();
1538 EXPECT_TRUE(value->IsString());
1539 EXPECT_STREQ("12.7mm", value->ToString().c_str());
1540 }
1541
1542 TEST_F(CFXJSE_FormCalcContextEmbedderTest, GetXFAEventChange) {
1543 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1544
1545 CXFA_EventParam params;
1546 params.m_wsChange = L"changed";
1547
1548 CFXJSE_Engine* context = GetScriptContext();
1549 context->SetEventParam(¶ms);
1550
1551 const char test[] = {"xfa.event.change"};
1552 EXPECT_TRUE(Execute(test));
1553
1554 CFXJSE_Value* value = GetValue();
1555 EXPECT_TRUE(value->IsString());
1556 EXPECT_STREQ("changed", value->ToString().c_str());
1557 context->SetEventParam(nullptr);
1558 }
1559
1560 TEST_F(CFXJSE_FormCalcContextEmbedderTest, SetXFAEventChange) {
1561 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1562
1563 CXFA_EventParam params;
1564 CFXJSE_Engine* context = GetScriptContext();
1565 context->SetEventParam(¶ms);
1566
1567 const char test[] = {"xfa.event.change = \"changed\""};
1568 EXPECT_TRUE(Execute(test));
1569 EXPECT_EQ(L"changed", params.m_wsChange);
1570 context->SetEventParam(nullptr);
1571 }
1572
1573 TEST_F(CFXJSE_FormCalcContextEmbedderTest, SetXFAEventFullTextFails) {
1574 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1575
1576 CXFA_EventParam params;
1577 params.m_wsFullText = L"Original Full Text";
1578
1579 CFXJSE_Engine* context = GetScriptContext();
1580 context->SetEventParam(¶ms);
1581
1582 const char test[] = {"xfa.event.fullText = \"Changed Full Text\""};
1583 EXPECT_TRUE(Execute(test));
1584 EXPECT_EQ(L"Original Full Text", params.m_wsFullText);
1585 context->SetEventParam(nullptr);
1586 }
1587
1588 TEST_F(CFXJSE_FormCalcContextEmbedderTest, EventChangeSelection) {
1589 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1590
1591 CXFA_EventParam params;
1592 params.m_wsPrevText = L"1234";
1593 params.m_iSelStart = 1;
1594 params.m_iSelEnd = 3;
1595
1596 CFXJSE_Engine* context = GetScriptContext();
1597 context->SetEventParam(¶ms);
1598
1599 // Moving end to start works fine.
1600 EXPECT_TRUE(Execute("xfa.event.selEnd = \"1\""));
1601 EXPECT_EQ(1, params.m_iSelStart);
1602 EXPECT_EQ(1, params.m_iSelEnd);
1603
1604 // Moving end before end, forces start to move in response.
1605 EXPECT_TRUE(Execute("xfa.event.selEnd = \"0\""));
1606 EXPECT_EQ(0, params.m_iSelStart);
1607 EXPECT_EQ(0, params.m_iSelEnd);
1608
1609 // Negatives not allowed
1610 EXPECT_TRUE(Execute("xfa.event.selEnd = \"-1\""));
1611 EXPECT_EQ(0, params.m_iSelStart);
1612 EXPECT_EQ(0, params.m_iSelEnd);
1613
1614 // Negatives not allowed
1615 EXPECT_TRUE(Execute("xfa.event.selStart = \"-1\""));
1616 EXPECT_EQ(0, params.m_iSelStart);
1617 EXPECT_EQ(0, params.m_iSelEnd);
1618
1619 params.m_iSelEnd = 1;
1620
1621 // Moving start to end works fine.
1622 EXPECT_TRUE(Execute("xfa.event.selStart = \"1\""));
1623 EXPECT_EQ(1, params.m_iSelStart);
1624 EXPECT_EQ(1, params.m_iSelEnd);
1625
1626 // Moving start after end moves end.
1627 EXPECT_TRUE(Execute("xfa.event.selStart = \"2\""));
1628 EXPECT_EQ(2, params.m_iSelStart);
1629 EXPECT_EQ(2, params.m_iSelEnd);
1630
1631 // Setting End past end of string clamps to string length;
1632 EXPECT_TRUE(Execute("xfa.event.selEnd = \"20\""));
1633 EXPECT_EQ(2, params.m_iSelStart);
1634 EXPECT_EQ(4, params.m_iSelEnd);
1635
1636 // Setting Start past end of string clamps to string length;
1637 EXPECT_TRUE(Execute("xfa.event.selStart = \"20\""));
1638 EXPECT_EQ(4, params.m_iSelStart);
1639 EXPECT_EQ(4, params.m_iSelEnd);
1640
1641 context->SetEventParam(nullptr);
1642 }
1643
1644 TEST_F(CFXJSE_FormCalcContextEmbedderTest, XFAEventCancelAction) {
1645 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1646
1647 CXFA_EventParam params;
1648 params.m_bCancelAction = false;
1649
1650 CFXJSE_Engine* context = GetScriptContext();
1651 context->SetEventParam(¶ms);
1652
1653 EXPECT_TRUE(Execute("xfa.event.cancelAction"));
1654
1655 CFXJSE_Value* value = GetValue();
1656 EXPECT_TRUE(value->IsBoolean());
1657 EXPECT_FALSE(value->ToBoolean());
1658
1659 EXPECT_TRUE(Execute("xfa.event.cancelAction = \"true\""));
1660 EXPECT_TRUE(params.m_bCancelAction);
1661
1662 context->SetEventParam(nullptr);
1663 }
1664
1665 TEST_F(CFXJSE_FormCalcContextEmbedderTest, ComplexTextChangeEvent) {
1666 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1667
1668 CXFA_EventParam params;
1669 params.m_wsChange = L"g";
1670 params.m_wsPrevText = L"abcd";
1671 params.m_iSelStart = 1;
1672 params.m_iSelEnd = 3;
1673
1674 CFXJSE_Engine* context = GetScriptContext();
1675 context->SetEventParam(¶ms);
1676
1677 EXPECT_EQ(L"abcd", params.m_wsPrevText);
1678 EXPECT_EQ(L"agd", params.GetNewText());
1679 EXPECT_EQ(L"g", params.m_wsChange);
1680 EXPECT_EQ(1, params.m_iSelStart);
1681 EXPECT_EQ(3, params.m_iSelEnd);
1682
1683 const char change_event[] = {"xfa.event.change = \"xyz\""};
1684 EXPECT_TRUE(Execute(change_event));
1685
1686 EXPECT_EQ(L"abcd", params.m_wsPrevText);
1687 EXPECT_EQ(L"xyz", params.m_wsChange);
1688 EXPECT_EQ(L"axyzd", params.GetNewText());
1689 EXPECT_EQ(1, params.m_iSelStart);
1690 EXPECT_EQ(3, params.m_iSelEnd);
1691
1692 const char sel_event[] = {"xfa.event.selEnd = \"1\""};
1693 EXPECT_TRUE(Execute(sel_event));
1694
1695 EXPECT_EQ(L"abcd", params.m_wsPrevText);
1696 EXPECT_EQ(L"xyz", params.m_wsChange);
1697 EXPECT_EQ(L"axyzbcd", params.GetNewText());
1698 EXPECT_EQ(1, params.m_iSelStart);
1699 EXPECT_EQ(1, params.m_iSelEnd);
1700
1701 context->SetEventParam(nullptr);
1702 }
1703
1704 // Should not crash.
1705 TEST_F(CFXJSE_FormCalcContextEmbedderTest, BUG_1223) {
1706 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1707
1708 EXPECT_FALSE(Execute("!.somExpression=0"));
1709 }
1710