Bug 1311426 - Handle Grip with wrapped value in Reps. r=Honza;
authorNicolas Chevobbe <chevobbe.nicolas@gmail.com>
Mon, 24 Oct 2016 07:32:32 +0200
changeset 319915 657c36b85c688b9f77a79f796157edf87bc75a86
parent 319914 b7e94b82004ec38beaf69fce2176433745b277c7
child 319916 a41f871e2d1b37754bbd1001c36c075511b49342
push id33666
push userchevobbe.nicolas@gmail.com
push dateFri, 28 Oct 2016 20:21:34 +0000
treeherderautoland@657c36b85c68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza
bugs1311426
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1311426 - Handle Grip with wrapped value in Reps. r=Honza; Handle object created from a constructor function, like `new Boolean(true)`, `new Number(42)` or `new String("foo")`. It displays the wrapped value using Rep so the primitives are displayed like expected. MozReview-Commit-ID: JrJVeV0C0wO
devtools/client/shared/components/reps/grip.js
devtools/client/shared/components/test/mochitest/test_reps_grip.html
--- a/devtools/client/shared/components/reps/grip.js
+++ b/devtools/client/shared/components/reps/grip.js
@@ -45,16 +45,26 @@ define(function (require, exports, modul
         return this.propIterator(object, max);
       } catch (err) {
         console.error(err);
       }
       return [];
     },
 
     propIterator: function (object, max) {
+      if (Object.keys(object.preview).includes("wrappedValue")) {
+        const { Rep } = createFactories(require("./rep"));
+
+        return [Rep({
+          object: object.preview.wrappedValue,
+          mode: this.props.mode || "tiny",
+          defaultRep: Grip,
+        })];
+      }
+
       // Property filter. Show only interesting properties to the user.
       let isInterestingProp = this.props.isInterestingProp || ((type, value) => {
         return (
           type == "boolean" ||
           type == "number" ||
           (type == "string" && value.length != 0)
         );
       });
--- a/devtools/client/shared/components/test/mochitest/test_reps_grip.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_grip.html
@@ -17,16 +17,19 @@ Test grip rep
 window.onload = Task.async(function* () {
   let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
   let { Grip } = browserRequire("devtools/client/shared/components/reps/grip");
 
   const componentUnderTest = Grip;
 
   try {
     yield testBasic();
+    yield testBooleanObject();
+    yield testNumberObject();
+    yield testStringObject();
 
     // Test property iterator
     yield testMaxProps();
     yield testMoreThanMaxProps();
     yield testUninterestingProps();
     yield testNonEnumerableProps();
 
     // Test that properties are rendered as expected by PropRep
@@ -70,16 +73,118 @@ window.onload = Task.async(function* () 
         mode: "long",
         expectedOutput: defaultOutput,
       }
     ];
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
+  function testBooleanObject() {
+    // Test object: `new Boolean(true)`
+    const testName = "testBooleanObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `Boolean { true }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Boolean`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
+  function testNumberObject() {
+    // Test object: `new Number(42)`
+    const testName = "testNumberObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `Number { 42 }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Number`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
+  function testStringObject() {
+    // Test object: `new String("foo")`
+    const testName = "testStringObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `String { "foo" }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `String`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
   function testMaxProps() {
     // Test object: `{a: "a", b: "b", c: "c"}`;
     const testName = "testMaxProps";
 
     const defaultOutput = `Object { a: "a", b: "b", c: "c" }`;
 
     const modeTests = [
       {
@@ -525,16 +630,57 @@ window.onload = Task.async(function* () 
                 "writable": true,
                 "value": 3
               }
             },
             "ownPropertiesLength": 4,
             "safeGetterValues": {}
           }
         };
-
+      case "testBooleanObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj57",
+          "class": "Boolean",
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {},
+            "wrappedValue": true
+          }
+        };
+      case "testNumberObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj59",
+          "class": "Number",
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {},
+            "wrappedValue": 42
+          }
+        };
+      case "testStringObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj61",
+          "class": "String",
+          "ownPropertyLength": 4,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 4,
+            "safeGetterValues": {},
+            "wrappedValue": "foo"
+          }
+        };
     }
   }
 });
 </script>
 </pre>
 </body>
 </html>