Add test for PDF's JS "global".

Exercises a separate code path that stores some JS objects
outside of JS.  Needed before re-writing some other portions
of the JS_Defines.h code.

R=jam@chromium.org

Review URL: https://codereview.chromium.org/943783002
diff --git a/testing/resources/javascript/globals.in b/testing/resources/javascript/globals.in
new file mode 100644
index 0000000..6d2f3ca
--- /dev/null
+++ b/testing/resources/javascript/globals.in
@@ -0,0 +1,137 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /Contents [21 0 R]
+  /MediaBox [0 0 612 792]
+>>
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+% JS program to exexute
+{{object 11 0}} <<
+>>
+stream
+// The "global" object stores data in a C-like manner, and
+// can theoretically persist them between sessions (though
+// pdfium deliberately excludes that functionality).
+
+var some_object = { "colors": [ "red", "green", "blue"] };
+
+var props_to_test = [
+  // Cover both bool values.
+  { "name": "true_var", "value": true },
+  { "name": "false_var", "value": false },
+
+  // Include both zero and a number with some fractional digits.
+  { "name": "zero_var", "value": 0 },
+  { "name": "number_var", "value": -3.918 },
+
+  // TODO(tsepez): unicode doesn't seem to survive.
+  { "name": "string_var", "value": "This is a string" },
+
+  // Try a complex object.
+  { "name": "object_var", "value": some_object },
+
+  // Test null and undefined.
+  { "name": "null_var", "value": null },
+  { "name": "undefined_var", "value": undefined }
+];
+
+function setup_global() {
+  for (var i = 0; i < props_to_test.length; ++i) {
+    var prop = props_to_test[i];
+    global[prop.name] = prop.value;
+  }
+}
+
+function delete_global() {
+  for (var i = 0; i < props_to_test.length; ++i) {
+    var prop = props_to_test[i];
+    delete global[prop.name];
+  }
+}
+
+function persist_global(should_persist) {
+  for (var i = 0; i < props_to_test.length; ++i) {
+    var prop = props_to_test[i];
+    global.setPersistent(prop.name, should_persist);
+  }
+}
+
+function dump_global(msg) {
+  app.alert("************ " + msg + " ************");
+  app.alert("Enumerable Globals:");
+  for (var name in global) {
+    app.alert("  " + name + " = " + global[name] +
+              ", own property = " + global.hasOwnProperty(name));
+  }
+  app.alert("Expected Globals:");
+  for (var i = 0; i < props_to_test.length; ++i) {
+    var prop = props_to_test[i];
+    var actual = global[prop.name];
+    app.alert("  " + prop.name + " = " + actual);
+    if (actual != null && typeof actual == "object") {
+      app.alert("    " + actual.colors[0]);
+      app.alert("    " + actual.colors[1]);
+      app.alert("    " + actual.colors[2]);
+    }
+  }
+}
+
+dump_global("Initial State");
+
+// Check that they all exist.
+setup_global();
+dump_global("After Setup");
+
+// Test deletion.
+delete_global();
+dump_global("After Deletion");
+
+// setPersistent() should be a no-op for pdfium.
+setup_global();
+persist_global(false);
+dump_global("After Setup and Persist false");
+
+// Test setting deleted variables as persistent.
+delete_global();
+persist_global(true);
+dump_global("After Delete and Persist");
+
+// Exit with variables marked as persistent to test whatever path
+// may exist to persist them (should be igonored on pdfium).
+setup_global();
+persist_global(true);
+dump_global("After Setup and Persist true");
+
+endstream
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/globals_expected.txt b/testing/resources/javascript/globals_expected.txt
new file mode 100644
index 0000000..ddaa00c
--- /dev/null
+++ b/testing/resources/javascript/globals_expected.txt
@@ -0,0 +1,105 @@
+Alert: ************ Initial State ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert: Expected Globals:
+Alert:   true_var = undefined
+Alert:   false_var = undefined
+Alert:   zero_var = undefined
+Alert:   number_var = undefined
+Alert:   string_var = undefined
+Alert:   object_var = undefined
+Alert:   null_var = undefined
+Alert:   undefined_var = undefined
+Alert: ************ After Setup ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert:   true_var = true, own property = true
+Alert:   false_var = false, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   null_var = null, own property = true
+Alert:   undefined_var = undefined, own property = true
+Alert: Expected Globals:
+Alert:   true_var = true
+Alert:   false_var = false
+Alert:   zero_var = 0
+Alert:   number_var = -3.918
+Alert:   string_var = This is a string
+Alert:   object_var = [object Object]
+Alert:     red
+Alert:     green
+Alert:     blue
+Alert:   null_var = null
+Alert:   undefined_var = undefined
+Alert: ************ After Deletion ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert: Expected Globals:
+Alert:   true_var = undefined
+Alert:   false_var = undefined
+Alert:   zero_var = undefined
+Alert:   number_var = undefined
+Alert:   string_var = undefined
+Alert:   object_var = undefined
+Alert:   null_var = undefined
+Alert:   undefined_var = undefined
+Alert: ************ After Setup and Persist false ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert:   true_var = true, own property = true
+Alert:   false_var = false, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   null_var = null, own property = true
+Alert:   undefined_var = undefined, own property = true
+Alert: Expected Globals:
+Alert:   true_var = true
+Alert:   false_var = false
+Alert:   zero_var = 0
+Alert:   number_var = -3.918
+Alert:   string_var = This is a string
+Alert:   object_var = [object Object]
+Alert:     red
+Alert:     green
+Alert:     blue
+Alert:   null_var = null
+Alert:   undefined_var = undefined
+Alert: ************ After Delete and Persist ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert: Expected Globals:
+Alert:   true_var = undefined
+Alert:   false_var = undefined
+Alert:   zero_var = undefined
+Alert:   number_var = undefined
+Alert:   string_var = undefined
+Alert:   object_var = undefined
+Alert:   null_var = undefined
+Alert:   undefined_var = undefined
+Alert: ************ After Setup and Persist true ************
+Alert: Enumerable Globals:
+Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
+Alert:   true_var = true, own property = true
+Alert:   false_var = false, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   null_var = null, own property = true
+Alert:   undefined_var = undefined, own property = true
+Alert: Expected Globals:
+Alert:   true_var = true
+Alert:   false_var = false
+Alert:   zero_var = 0
+Alert:   number_var = -3.918
+Alert:   string_var = This is a string
+Alert:   object_var = [object Object]
+Alert:     red
+Alert:     green
+Alert:     blue
+Alert:   null_var = null
+Alert:   undefined_var = undefined