Better tests for CJS_Field properties.

Fixes some longstanding issues
- Make x,y coordinates used in test have unique values from each other.
- run text widget tests on text widget, not its parent.
- run subset of these tests on the parent itself.
- provide some text values for the text widget.
- fix test helpers to compare distinct arrays/objects for "sameness".
- update an error message to indicate the problem is with caller
  argument, not the object bound across the fxjs interface.

Change-Id: I60834021b64eb275d3ec36bcdea7f71fc11d18ab
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63390
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index 45e5ad7..1d49924 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -1707,7 +1707,7 @@
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
   if (vp.IsEmpty() || !vp->IsArray())
-    return CJS_Result::Failure(JSMessage::kBadObjectError);
+    return CJS_Result::Failure(JSMessage::kValueError);
 
   v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
   if (pRuntime->GetArrayLength(rcArray) < 4)
diff --git a/testing/resources/javascript/field.fragment b/testing/resources/javascript/field.fragment
index 1dbcb0b..d366361 100644
--- a/testing/resources/javascript/field.fragment
+++ b/testing/resources/javascript/field.fragment
@@ -8,9 +8,7 @@
 {{object 2 0}} <<
   /Type /Pages
   /Count 1
-  /Kids [
-    3 0 R
-  ]
+  /Kids [3 0 R]
 >>
 endobj
 % Page number 0.
@@ -39,7 +37,7 @@
   /T (MyField)
   /Type /Annot
   /Subtype /Widget
-  /Rect [100 100 400 400]
+  /Rect [100 101 400 401]
   /Kids [
     6 0 R
     7 0 R
@@ -56,7 +54,9 @@
   /T (MyText)
   /Type /Annot
   /Subtype /Widget
-  /Rect [200 200 220 220]
+  /Rect [200 201 220 221]
+  /V (bleen)
+  /DV (grue)
 >>
 endobj
 {{object 7 0}} <<
@@ -66,7 +66,7 @@
   /T (MyPushButton)
   /Type /Annot
   /Subtype /Widget
-  /Rect [220 220 240 240]
+  /Rect [220 221 240 241]
 >>
 endobj
 {{object 8 0}} <<
@@ -76,7 +76,7 @@
   /T (MyRadio)
   /Type /Annot
   /Subtype /Widget
-  /Rect [240 240 260 260]
+  /Rect [240 241 260 261]
 >>
 endobj
 {{object 9 0}} <<
@@ -86,7 +86,7 @@
   /T (MyCheckBox)
   /Type /Annot
   /Subtype /Widget
-  /Rect [260 260 280 280]
+  /Rect [260 261 280 281]
 >>
 endobj
 {{object 10 0}} <<
@@ -96,7 +96,7 @@
   /T (MyMultiSelect)
   /Type /Annot
   /Subtype /Widget
-  /Rect [ 280 280 300 300 ]
+  /Rect [ 280 281 300 301 ]
   /Opt [ (foo) (bar) (qux) ]
   /V (qux)
 >>
@@ -108,7 +108,7 @@
   /T (MySingleSelect)
   /Type /Annot
   /Subtype /Widget
-  /Rect [ 300 300 320 320 ]
+  /Rect [ 300 301 320 321 ]
   /Opt [
     [ (foo) (Foo) ]
     [ (bar) (Bar) ]
@@ -116,7 +116,6 @@
   ]
 >>
 endobj
-
 % OpenAction action
 {{object 15 0}} <<
   /Type /Action
diff --git a/testing/resources/javascript/field_properties.in b/testing/resources/javascript/field_properties.in
index 5ba47ec..4b3ee4e 100644
--- a/testing/resources/javascript/field_properties.in
+++ b/testing/resources/javascript/field_properties.in
@@ -1,6 +1,5 @@
 {{header}}
 {{include field.fragment}}
-
 % JS program to exexute
 {{object 16 0}} <<
   {{streamlen}}
@@ -18,10 +17,10 @@
     app.alert('Testing properties under delay');
     testRWProperty(field, "delay", false, true);
     // TODO(tsepez): try this case, too.
-    // testTextPropertiesCase(field);
     app.alert('Testing properties under non-delay');
     testRWProperty(field, "delay", true, false);
-    testTextPropertiesCase(field);
+    testFieldPropertiesCase(field);
+    testTextPropertiesCase(text);
     testPushButtonPropertiesCase(button);
     testRadioButtonPropertiesCase(radio);
     testCheckBoxPropertiesCase(check);
@@ -31,6 +30,14 @@
   }
 }
 
+function testFieldPropertiesCase(field) {
+  testROProperty(field, "name", "MyField");
+  // TODO(tsepez): this is rect of first child somehow.
+  testRWProperty(field, "rect", [200,221,220,201], [100,121,120,101]);
+ // Put it back to where it started.
+  testRWProperty(field, "rect", [100,121,120,101], [200,221,220,201]);
+}
+
 function testTextPropertiesCase(field) {
   try {
     // TODO(tsepez): devise tests and uncomment.
@@ -42,7 +49,7 @@
     // testRIProperty(field, "commitOnSelChange", false, true);
     // testROProperty(field, "currentValueIndices", "clams");
     testXXProperty(field, "defaultStyle");
-    testRIProperty(field, "defaultValue", "", "clams");
+    testRIProperty(field, "defaultValue", "grue", "clams");
     testRIProperty(field, "doNotScroll", false, true);
     testRIProperty(field, "doNotSpellCheck", false, true);
     testRWProperty(field, "display", 2, 3);
@@ -54,13 +61,13 @@
     testRWProperty(field, "lineWidth", 1, 4);
     testRIProperty(field, "multiline", false, true);
     // testROProperty(field, "multipleSelection", "clams");
-    testROProperty(field, "name", "MyField");
+    testROProperty(field, "name", "MyField.MyText");
     // testROProperty(field, "numItems", "clams");
     testROProperty(field, "page", 0);
     testRIProperty(field, "password", false, 42);
     testRWProperty(field, "print", true, false);
     testRIProperty(field, "readonly", false, true);
-    // testRWProperty(field, "rect", [0,0,0,0], [0,0,0,0]);
+    testROProperty(field, "rect", [200,221,220,201]);
     // testROProperty(field, "required", "clams");
     testRIProperty(field, "richText", false, true);
     testRIProperty(field, "richValue", undefined, "clams");
@@ -73,8 +80,8 @@
     testRIProperty(field, "textSize", 0, 32);
     testROProperty(field, "type", "text");
     testRIProperty(field, "userName", "");
-    testRIProperty(field, "value", "", "clams");
-    testROProperty(field, "valueAsString", "");
+    testRWProperty(field, "value", "bleen", "clams");
+    testROProperty(field, "valueAsString", "clams");  // Set by previous line.
   } catch (e) {
     app.alert("Unexpected error: " + e);
   }
diff --git a/testing/resources/javascript/field_properties_expected.txt b/testing/resources/javascript/field_properties_expected.txt
index 104e437..676953e 100644
--- a/testing/resources/javascript/field_properties_expected.txt
+++ b/testing/resources/javascript/field_properties_expected.txt
@@ -4,6 +4,12 @@
 Alert: Testing properties under non-delay
 Alert: PASS: delay = true
 Alert: PASS: delay = false
+Alert: PASS: name = MyField
+Alert: PASS: name threw Field.name: Operation not supported.
+Alert: PASS: rect = 200,221,220,201
+Alert: PASS: rect = 100,121,120,101
+Alert: PASS: rect = 100,121,120,101
+Alert: PASS: rect = 200,221,220,201
 Alert: PASS: alignment = left
 Alert: PASS: alignment = left
 Alert: PASS: borderStyle = solid
@@ -16,8 +22,8 @@
 Alert: PASS: comb = false
 Alert: PASS: defaultStyle threw Field.defaultStyle: Operation not supported.
 Alert: PASS: defaultStyle threw Field.defaultStyle: Operation not supported.
-Alert: PASS: defaultValue = 
-Alert: PASS: defaultValue = 
+Alert: PASS: defaultValue = grue
+Alert: PASS: defaultValue = grue
 Alert: PASS: doNotScroll = false
 Alert: PASS: doNotScroll = false
 Alert: PASS: doNotSpellCheck = false
@@ -36,7 +42,7 @@
 Alert: PASS: lineWidth = 4
 Alert: PASS: multiline = false
 Alert: PASS: multiline = false
-Alert: PASS: name = MyField
+Alert: PASS: name = MyField.MyText
 Alert: PASS: name threw Field.name: Operation not supported.
 Alert: PASS: page = 0
 Alert: PASS: page threw Field.page: Cannot assign to readonly property.
@@ -46,6 +52,8 @@
 Alert: PASS: print = false
 Alert: PASS: readonly = false
 Alert: PASS: readonly = false
+Alert: PASS: rect = 200,221,220,201
+Alert: PASS: rect threw Field.rect: Incorrect parameter value.
 Alert: PASS: richText = false
 Alert: PASS: richText = false
 Alert: PASS: richValue = undefined
@@ -66,9 +74,9 @@
 Alert: PASS: type threw Field.type: Operation not supported.
 Alert: PASS: userName = 
 Alert: PASS: userName = 
-Alert: PASS: value = 
-Alert: PASS: value = 
-Alert: PASS: valueAsString = 
+Alert: PASS: value = bleen
+Alert: PASS: value = clams
+Alert: PASS: valueAsString = clams
 Alert: PASS: valueAsString threw Field.valueAsString: Operation not supported.
 Alert: PASS: buttonAlignX = 0
 Alert: PASS: buttonAlignX = 0
diff --git a/testing/resources/javascript/property_test_helpers.js b/testing/resources/javascript/property_test_helpers.js
index 1c75241..47a25ef 100644
--- a/testing/resources/javascript/property_test_helpers.js
+++ b/testing/resources/javascript/property_test_helpers.js
@@ -2,10 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Treat two distinct objects with the same members as equal, e.g. in JS
+// ([0, 1] == [0, 1]) evaluates to false. Without this function, we can't
+// supply an expected result of object/array type for our tests.
+function kindaSortaEqual(arg1, arg2) {
+  if (arg1 == arg2) {
+    return true;
+  }
+  if (typeof arg1 != "object") {
+    return false;
+  }
+  if (typeof arg2 != "object") {
+    return false;
+  }
+  return arg1.toString() == arg2.toString();
+}
+
 function testReadProperty(that, prop, expected) {
   try {
     var actual = that[prop];
-    if (actual == expected) {
+    if (kindaSortaEqual(actual, expected)) {
       app.alert('PASS: ' + prop + ' = ' + actual);
     } else {
       app.alert('FAIL: ' + prop + ' = ' + actual + ', expected = ' + expected);
@@ -28,7 +44,7 @@
   try {
     that[prop] = newValue;
     var actual = that[prop];
-    if (actual == newValue) {
+    if (kindaSortaEqual(actual, newValue)) {
       app.alert('PASS: ' + prop + ' = ' + actual);
     } else {
       app.alert('FAIL: ' + prop + ' = ' + actual + ', expected = ' + newValue);
@@ -42,7 +58,7 @@
   try {
     that[prop] = newValue;
     var actual = that[prop];
-    if (actual == expected) {
+    if (kindaSortaEqual(actual, expected)) {
       app.alert('PASS: ' + prop + ' = ' + actual);
     } else {
       app.alert('FAIL: ' + prop + ' = ' + actual + ', expected = ' + expected);