Bug 1309749 - Add reps for NaN and Infinity. r=Honza; draft
authorNicolas Chevobbe <chevobbe.nicolas@gmail.com>
Sat, 15 Oct 2016 10:58:29 +0200
changeset 426939 bd3030f6065515f31b037cb45ec4869f653d4a9c
parent 426771 90d8afaddf9150853b0b68b35b30c1e54a8683e7
child 534321 124a8d96b5371e8220c9863432db9dfff9bd4b22
push id32859
push userchevobbe.nicolas@gmail.com
push dateWed, 19 Oct 2016 11:45:31 +0000
reviewersHonza
bugs1309749
milestone52.0a1
Bug 1309749 - Add reps for NaN and Infinity. r=Honza; Add reps and test for it. Edit Number rep's `supportsObject` function because there was an error for `-0` object, due to some change in the function which detect which rep to use. MozReview-Commit-ID: 8Dz40E7LBb0
devtools/client/shared/components/reps/infinity.js
devtools/client/shared/components/reps/moz.build
devtools/client/shared/components/reps/nan.js
devtools/client/shared/components/reps/number.js
devtools/client/shared/components/reps/rep.js
devtools/client/shared/components/test/mochitest/chrome.ini
devtools/client/shared/components/test/mochitest/test_reps_infinity.html
devtools/client/shared/components/test/mochitest/test_reps_nan.html
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/reps/infinity.js
@@ -0,0 +1,41 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+// Make this available to both AMD and CJS environments
+define(function (require, exports, module) {
+  // Dependencies
+  const React = require("devtools/client/shared/vendor/react");
+
+  // Shortcuts
+  const { span } = React.DOM;
+
+  /**
+   * Renders a Infinity object
+   */
+  const InfinityRep = React.createClass({
+    displayName: "Infinity",
+
+    render: function () {
+      return (
+        span({className: "objectBox objectBox-number"},
+          this.props.object.type
+        )
+      );
+    }
+  });
+
+  function supportsObject(object, type) {
+    return type == "Infinity" || type == "-Infinity";
+  }
+
+  // Exports from this module
+  exports.InfinityRep = {
+    rep: InfinityRep,
+    supportsObject: supportsObject
+  };
+});
--- a/devtools/client/shared/components/reps/moz.build
+++ b/devtools/client/shared/components/reps/moz.build
@@ -10,16 +10,18 @@ DevToolsModules(
     'caption.js',
     'date-time.js',
     'document.js',
     'event.js',
     'function.js',
     'grip-array.js',
     'grip-map.js',
     'grip.js',
+    'infinity.js',
+    'nan.js',
     'null.js',
     'number.js',
     'object-with-text.js',
     'object-with-url.js',
     'object.js',
     'prop-rep.js',
     'regexp.js',
     'rep-utils.js',
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/reps/nan.js
@@ -0,0 +1,41 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+// Make this available to both AMD and CJS environments
+define(function (require, exports, module) {
+  // Dependencies
+  const React = require("devtools/client/shared/vendor/react");
+
+  // Shortcuts
+  const { span } = React.DOM;
+
+  /**
+   * Renders a NaN object
+   */
+  const NaNRep = React.createClass({
+    displayName: "NaN",
+
+    render: function () {
+      return (
+        span({className: "objectBox objectBox-nan"},
+          "NaN"
+        )
+      );
+    }
+  });
+
+  function supportsObject(object, type) {
+    return type == "NaN";
+  }
+
+  // Exports from this module
+  exports.NaNRep = {
+    rep: NaNRep,
+    supportsObject: supportsObject
+  };
+});
--- a/devtools/client/shared/components/reps/number.js
+++ b/devtools/client/shared/components/reps/number.js
@@ -34,18 +34,17 @@ define(function (require, exports, modul
         span({className: "objectBox objectBox-number"},
           this.stringify(value)
         )
       );
     }
   });
 
   function supportsObject(object, type) {
-    return type == "boolean" || type == "number" ||
-      (type == "object" && object.type == "-0");
+    return ["boolean", "number", "-0"].includes(type);
   }
 
   // Exports from this module
 
   exports.Number = {
     rep: Number,
     supportsObject: supportsObject
   };
--- a/devtools/client/shared/components/reps/rep.js
+++ b/devtools/client/shared/components/reps/rep.js
@@ -16,16 +16,18 @@ define(function (require, exports, modul
   // Load all existing rep templates
   const { Undefined } = require("./undefined");
   const { Null } = require("./null");
   const { StringRep } = require("./string");
   const { Number } = require("./number");
   const { ArrayRep } = require("./array");
   const { Obj } = require("./object");
   const { SymbolRep } = require("./symbol");
+  const { InfinityRep } = require("./infinity");
+  const { NaNRep } = require("./nan");
 
   // DOM types (grips)
   const { Attribute } = require("./attribute");
   const { DateTime } = require("./date-time");
   const { Document } = require("./document");
   const { Event } = require("./event");
   const { Func } = require("./function");
   const { RegExp } = require("./regexp");
@@ -57,16 +59,18 @@ define(function (require, exports, modul
     GripArray,
     GripMap,
     Grip,
     Undefined,
     Null,
     StringRep,
     Number,
     SymbolRep,
+    InfinityRep,
+    NaNRep,
   ];
 
   /**
    * Generic rep that is using for rendering native JS types or an object.
    * The right template used for rendering is picked automatically according
    * to the current value type. The value must be passed is as 'object'
    * property.
    */
@@ -97,18 +101,18 @@ define(function (require, exports, modul
    *
    * @param defaultObject {React.Component} The default template
    * that should be used to render given object if none is found.
    */
   function getRep(object, defaultRep = Obj) {
     let type = typeof object;
     if (type == "object" && object instanceof String) {
       type = "string";
-    } else if (object && type == "object" && object.type === "symbol") {
-      type = "symbol";
+    } else if (object && type == "object" && object.type) {
+      type = object.type;
     }
 
     if (isGrip(object)) {
       type = object.class;
     }
 
     for (let i = 0; i < reps.length; i++) {
       let rep = reps[i];
--- a/devtools/client/shared/components/test/mochitest/chrome.ini
+++ b/devtools/client/shared/components/test/mochitest/chrome.ini
@@ -11,16 +11,18 @@ support-files =
 [test_reps_attribute.html]
 [test_reps_date-time.html]
 [test_reps_document.html]
 [test_reps_event.html]
 [test_reps_function.html]
 [test_reps_grip.html]
 [test_reps_grip-array.html]
 [test_reps_grip-map.html]
+[test_reps_infinity.html]
+[test_reps_nan.html]
 [test_reps_null.html]
 [test_reps_number.html]
 [test_reps_object.html]
 [test_reps_object-with-text.html]
 [test_reps_object-with-url.html]
 [test_reps_regexp.html]
 [test_reps_string.html]
 [test_reps_stylesheet.html]
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/test/mochitest/test_reps_infinity.html
@@ -0,0 +1,71 @@
+
+<!DOCTYPE HTML>
+<html>
+<!--
+Test Infinity rep
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Rep test - Infinity</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body>
+<pre id="test">
+<script src="head.js" type="application/javascript;version=1.8"></script>
+<script type="application/javascript;version=1.8">
+"use strict";
+
+window.onload = Task.async(function* () {
+  let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
+  let { InfinityRep } = browserRequire("devtools/client/shared/components/reps/infinity");
+
+  try {
+    yield testInfinity();
+    yield testNegativeInfinity();
+  } catch (e) {
+    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
+  } finally {
+    SimpleTest.finish();
+  }
+
+  function testInfinity() {
+    const stub = getGripStub("testInfinity");
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    is(renderedRep.type, InfinityRep.rep,
+      `Rep correctly selects ${InfinityRep.rep.displayName} for Infinity value`);
+
+    const renderedComponent = renderComponent(InfinityRep.rep, { object: stub });
+    is(renderedComponent.textContent, "Infinity",
+      "Infinity rep has expected text content for Infinity");
+  }
+
+  function testNegativeInfinity() {
+    const stub = getGripStub("testNegativeInfinity");
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    is(renderedRep.type, InfinityRep.rep,
+      `Rep correctly selects ${InfinityRep.rep.displayName} for negative Infinity value`);
+
+    const renderedComponent = renderComponent(InfinityRep.rep, { object: stub });
+    is(renderedComponent.textContent, "-Infinity",
+      "Infinity rep has expected text content for negative Infinity");
+  }
+
+  function getGripStub(name) {
+    switch (name) {
+      case "testInfinity":
+        return {
+          type: "Infinity"
+        };
+      case "testNegativeInfinity":
+        return {
+          type: "-Infinity"
+        };
+    }
+    return null;
+  }
+});
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/test/mochitest/test_reps_nan.html
@@ -0,0 +1,46 @@
+
+<!DOCTYPE HTML>
+<html>
+<!--
+Test NaN rep
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Rep test - NaN</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body>
+<pre id="test">
+<script src="head.js" type="application/javascript;version=1.8"></script>
+<script type="application/javascript;version=1.8">
+"use strict";
+
+window.onload = Task.async(function* () {
+  let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
+  let { NaNRep } = browserRequire("devtools/client/shared/components/reps/nan");
+
+  try {
+    yield testNaN();
+  } catch (e) {
+    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
+  } finally {
+    SimpleTest.finish();
+  }
+
+  function testNaN() {
+    const stub = {
+      type: "NaN"
+    };
+    const renderedRep = shallowRenderComponent(Rep, {object: stub});
+    is(renderedRep.type, NaNRep.rep,
+      `Rep correctly selects ${NaNRep.rep.displayName} for NaN value`);
+
+    const renderedComponent = renderComponent(NaNRep.rep, {object: stub});
+    is(renderedComponent.textContent, "NaN", "NaN rep has expected text content");
+  }
+});
+</script>
+</pre>
+</body>
+</html>