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
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>