diff --git a/.eslintrc.test.config.js b/.eslintrc.test.config.js
index 84349f64b..f41ff4689 100644
--- a/.eslintrc.test.config.js
+++ b/.eslintrc.test.config.js
@@ -23,7 +23,8 @@ module.exports = {
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/valid-expect": "error",
- "max-len": ["error", 180, 4, { "ignoreComments": true }]
+ "max-len": ["error", 180, 4, { "ignoreComments": true }],
+ "max-lines": ["error", {"max": 800, "skipComments": true}],
},
"env": {
"jest/globals": true
diff --git a/.gitignore b/.gitignore
index 38af4ed56..ccaa7d817 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,4 @@ gen-docs
**/.DS_Store
.vscode
cypress/videos/
+cypress/screenshots/
diff --git a/.travis.yml b/.travis.yml
index fb52b5a30..3e44cb249 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ language: node_js
node_js:
- "8.9.0"
install:
- - yarn install
+ - npm install
before_script:
- npm start -- --silent &
script:
diff --git a/cypress.json b/cypress.json
index 0967ef424..dfca4140a 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1 +1,3 @@
-{}
+{
+ "videoRecording": false
+}
diff --git a/cypress/common/page-objects/node.po.js b/cypress/common/page-objects/node.po.js
index f81b55b4d..f54cb7c9f 100644
--- a/cypress/common/page-objects/node.po.js
+++ b/cypress/common/page-objects/node.po.js
@@ -1,3 +1,5 @@
+/*global cy*/
+
/**
* Page Object for interacting with Node component.
* @param {string} id the id of the node.
diff --git a/cypress/common/page-objects/sandbox.po.js b/cypress/common/page-objects/sandbox.po.js
index fe79cea22..d26c9dc03 100644
--- a/cypress/common/page-objects/sandbox.po.js
+++ b/cypress/common/page-objects/sandbox.po.js
@@ -1,19 +1,32 @@
+/*global cy*/
+
/**
* Page Object for interacting with sandbox interface.
* @returns {undefined}
*/
function SandboxPO () {
// whitelist checkbox inputs
- this.checkboxes = [ 'node.renderLabel' ];
-
+ this.checkboxes = ['node.renderLabel', 'staticGraph'];
+
// actions
this.playGraph = () => cy.get('.container__graph > :nth-child(1) > :nth-child(2)').click();
this.pauseGraph = () => cy.get('.container__graph > :nth-child(1) > :nth-child(3)').click();
+ this.addNode = () => cy.get('.container__graph > :nth-child(1) > :nth-child(5)').click();
+ this.removeNode = () => cy.get('.container__graph > :nth-child(1) > :nth-child(6)').click();
+ this.clickJsonTreeNodes = () => {
+ cy.get('.container__graph-data').contains('root').scrollIntoView();
+ cy.get('.container__graph-data').contains('nodes').click();
+ };
+ // must be collapsed
+ this.clickJsonTreeFirstNode = () => cy.get(':nth-child(2) > .rejt-not-collapsed > .rejt-not-collapsed-list > :nth-child(1) > .rejt-collapsed > .rejt-collapsed-text').click();
+ this.addJsonTreeFirstNodeProp = () => cy.get(':nth-child(2) > :nth-child(1) > .rejt-not-collapsed > :nth-child(4) > .rejt-plus-menu').click();
+ this.deleteJsonTreeFirstNodeProp = () => cy.get('.rejt-not-collapsed-list > :nth-child(2) > .rejt-minus-menu').click();
// element getters
this.getFieldInput = (field) => this.checkboxes.includes(field)
? cy.contains(field).children('input')
: cy.contains(field).siblings('.form-control');
+ this.getGraphNumbers = () => cy.get('.container__graph-info');
}
module.exports = SandboxPO;
\ No newline at end of file
diff --git a/cypress/integration/graph.e2e.js b/cypress/integration/graph.e2e.js
new file mode 100644
index 000000000..e55b6d3aa
--- /dev/null
+++ b/cypress/integration/graph.e2e.js
@@ -0,0 +1,105 @@
+/*global cy*/
+const SANDBOX_URL = Cypress.env('SANDBOX_URL');
+
+const NodePO = require('../common/page-objects/node.po');
+const SandboxPO = require('../common/page-objects/sandbox.po');
+let nodes = require('./../../sandbox/data').nodes.map(({id}) => id);
+
+describe('[rd3g-graph] graph tests', function () {
+ before(function () {
+ this.sandboxPO = new SandboxPO();
+ // visit sandbox
+ cy.visit(SANDBOX_URL);
+ // sleep 2 seconds
+ cy.wait(2000);
+ // pause the graph
+ this.sandboxPO.pauseGraph();
+ });
+
+ describe('when data is changed', function () {
+ describe('and we change nodes props', function () {
+ beforeEach(function () {
+ // expand nodes
+ this.sandboxPO.clickJsonTreeNodes();
+ // expand 1st node
+ this.sandboxPO.clickJsonTreeFirstNode();
+ });
+
+ afterEach(function () {
+ this.sandboxPO.clickJsonTreeNodes();
+ });
+
+ it('nodes props modifications should be reflected in the graph', function () {
+ // click (+) add prop to 1st node
+ this.sandboxPO.addJsonTreeFirstNodeProp();
+
+ // prop name be color
+ cy.get('[placeholder="Key"]')
+ .clear()
+ .type('color');
+
+ // prop value be red and press ENTER
+ cy.get('[placeholder="Value"]')
+ .clear()
+ .type('red{enter}');
+
+ const nodePO = new NodePO(nodes[0]);
+
+ nodePO.getColor().should('eq', 'red');
+
+ // delete created prop
+ this.sandboxPO.deleteJsonTreeFirstNodeProp();
+
+ nodePO.getColor().should('eq', '#d3d3d3');
+ });
+
+ describe('and staticGraph is toggled on', function () {
+ beforeEach(function () {
+ cy.contains('staticGraph').scrollIntoView();
+ this.sandboxPO.getFieldInput('staticGraph').click();
+ });
+
+ it('nodes props modifications should be reflected in the graph', function () {
+ cy.get('text').should('have.length', 14);
+
+ this.sandboxPO.addNode();
+ this.sandboxPO.addNode();
+ this.sandboxPO.addNode();
+ this.sandboxPO.addNode();
+
+ cy.get('text').should('have.length', 18);
+
+ // click (+) add prop to 1st node
+ this.sandboxPO.addJsonTreeFirstNodeProp();
+ // prop name be color
+ cy.get('[placeholder="Key"]')
+ .clear()
+ .type('color');
+ // prop value be red and press ENTER
+ cy.get('[placeholder="Value"]')
+ .clear()
+ .type('red{enter}');
+
+ const nodePO = new NodePO(nodes[0]);
+
+ nodePO.getColor().should('eq', 'red');
+
+ // delete created prop
+ this.sandboxPO.deleteJsonTreeFirstNodeProp();
+
+ nodePO.getColor().should('eq', '#d3d3d3');
+
+ this.sandboxPO.removeNode();
+
+ cy.get('text').should('have.length', 17);
+
+ this.sandboxPO.removeNode();
+ this.sandboxPO.removeNode();
+ this.sandboxPO.removeNode();
+
+ cy.get('text').should('have.length', 14);
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/cypress/integration/node.e2e.js b/cypress/integration/node.e2e.js
index c4a94f25d..105782379 100644
--- a/cypress/integration/node.e2e.js
+++ b/cypress/integration/node.e2e.js
@@ -1,6 +1,8 @@
+/*global cy*/
+const SANDBOX_URL = Cypress.env('SANDBOX_URL');
+
const NodePO = require('../common/page-objects/node.po');
const SandboxPO = require('../common/page-objects/sandbox.po');
-const SANDBOX_URL = Cypress.env('SANDBOX_URL');
let nodes = require('./../../sandbox/data').nodes.map(({id}) => id);
describe('[rd3g-node] node tests', function () {
diff --git a/package-lock.json b/package-lock.json
index a15cb75c2..d537936df 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2873,9 +2873,9 @@
}
},
"cypress": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-1.4.1.tgz",
- "integrity": "sha1-YvQHSgDm8S4t/jiKf06BaknOsD8=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-2.0.1.tgz",
+ "integrity": "sha512-6LIrMzvPh/v95JXUclJpCNumf4filJpXCj79kPazh4ohyGXIsUI9nZ7CsFEU6dieX46N1tGORMr93ruVXzhoFw==",
"dev": true,
"requires": {
"@cypress/listr-verbose-renderer": "0.4.1",
@@ -9987,6 +9987,12 @@
}
}
},
+ "mousetrap": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.1.tgz",
+ "integrity": "sha1-KghfXHUSlMdefoH27CVFspy/Qtk=",
+ "dev": true
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -11847,6 +11853,28 @@
"prop-types": "15.6.0"
}
},
+ "react-editable-json-tree": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/react-editable-json-tree/-/react-editable-json-tree-2.1.0.tgz",
+ "integrity": "sha512-4I0rQIBs5S8FLEVjZrCUJAk2+9t/dkmZLQVB2Dt+SombQph/8GZ97yhzV0u8iIU49Use9cWCReyUfZ2oicjOYw==",
+ "dev": true,
+ "requires": {
+ "prop-types": "15.6.0",
+ "react-hotkeys": "0.10.0"
+ }
+ },
+ "react-hotkeys": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/react-hotkeys/-/react-hotkeys-0.10.0.tgz",
+ "integrity": "sha1-0eeL1j8W1ttY1VDTPI6wcfNdlPs=",
+ "dev": true,
+ "requires": {
+ "create-react-class": "15.6.2",
+ "lodash": "4.17.4",
+ "mousetrap": "1.6.1",
+ "prop-types": "15.6.0"
+ }
+ },
"react-jsonschema-form": {
"version": "0.50.1",
"resolved": "https://registry.npmjs.org/react-jsonschema-form/-/react-jsonschema-form-0.50.1.tgz",
diff --git a/package.json b/package.json
index cb68c1687..89ab55cae 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
"babel-preset-react": "6.24.1",
"babel-preset-stage-0": "6.24.1",
"css-loader": "0.28.7",
- "cypress": "1.4.1",
+ "cypress": "2.0.1",
"documentation": "5.3.2",
"eslint": "3.18.0",
"eslint-config-recommended": "1.5.0",
@@ -59,6 +59,7 @@
"npm-run-all": "4.1.1",
"react-addons-test-utils": "15.6.0",
"react-dom": "15.6.1",
+ "react-editable-json-tree": "2.1.0",
"react-jsonschema-form": "0.50.1",
"react-router-dom": "4.2.2",
"react-test-renderer": "15.6.1",
diff --git a/sandbox/Sandbox.jsx b/sandbox/Sandbox.jsx
index 3478742b7..5a174812f 100644
--- a/sandbox/Sandbox.jsx
+++ b/sandbox/Sandbox.jsx
@@ -1,3 +1,5 @@
+/*global console*/
+/*eslint require-jsdoc: 0, valid-jsdoc: 0, no-console: 0*/
import React from 'react';
import Form from 'react-jsonschema-form';
@@ -9,6 +11,7 @@ import { Graph } from '../src';
import data from './data';
import Utils from './utils';
import ReactD3GraphUtils from '../src/utils';
+import { JsonTree } from 'react-editable-json-tree';
/**
* This is a sample integration of react-d3-graph, in this particular case all the rd3g config properties
@@ -49,9 +52,11 @@ export default class Sandbox extends React.Component {
onMouseOutNode = (id) => console.info(`Do something when mouse is out of node (${id})`);
- onMouseOverLink = (source, target) => console.info(`Do something when mouse is over link between ${source} and ${target}`);
+ onMouseOverLink = (source, target) =>
+ console.info(`Do something when mouse is over link between ${source} and ${target}`);
- onMouseOutLink = (source, target) => console.info(`Do something when mouse is out of link between ${source} and ${target}`);
+ onMouseOutLink = (source, target) =>
+ console.info(`Do something when mouse is out of link between ${source} and ${target}`);
/**
* Sets on/off fullscreen visualization mode.
@@ -123,13 +128,14 @@ export default class Sandbox extends React.Component {
onClickRemoveNode = () => {
if (this.state.data.nodes && this.state.data.nodes.length) {
const id = this.state.data.nodes[0].id;
+
this.state.data.nodes.splice(0, 1);
const links = this.state.data.links.filter(l => l.source !== id && l.target !== id);
const data = { nodes: this.state.data.nodes, links };
this.setState({ data });
} else {
- alert('No more nodes to remove!');
+ window.alert('No more nodes to remove!');
}
}
@@ -137,12 +143,12 @@ export default class Sandbox extends React.Component {
let config = {};
let schemaPropsValues = {};
- for(let k of Object.keys(data.formData)) {
+ for (let k of Object.keys(data.formData)) {
// Set value mapping correctly for config object of react-d3-graph
Utils.setValue(config, k, data.formData[k]);
// Set new values for schema of jsonform
schemaPropsValues[k] = {};
- schemaPropsValues[k]['default'] = data.formData[k]
+ schemaPropsValues[k]['default'] = data.formData[k];
}
return {config, schemaPropsValues};
@@ -162,11 +168,9 @@ export default class Sandbox extends React.Component {
* Generate graph configuration file ready to use!
*/
onSubmit = (data) => {
- const {config, schemaPropsValues} = this._buildGraphConfig(data);
+ const { config } = this._buildGraphConfig(data);
- this.setState({
- generatedConfig: config
- });
+ this.setState({ generatedConfig: config });
}
onClickSubmit = () => {
@@ -199,14 +203,21 @@ export default class Sandbox extends React.Component {
* @return {Object} the graph where now nodes containing (x,y) coords.
*/
decorateGraphNodesWithInitialPositioning = (nodes) => {
- return nodes.map(n => ({
- id: n.id,
- x: Math.floor(Math.random() * 500),
- y: Math.floor(Math.random() * 500),
- symbolType: n.symbolType || 'circle'
- }));
+ return nodes.map(n => (
+ Object.assign({}, n, {
+ x: n.x || Math.floor(Math.random() * 500),
+ y: n.y || Math.floor(Math.random() * 500)
+ })
+ ));
}
+ /**
+ * Update graph data each time an update is triggered
+ * by JsonTree
+ * @param {Object} data update graph data (nodes and links)
+ */
+ onGraphDataUpdate = (data) => this.setState({ data });
+
/**
* Build common piece of the interface that contains some interactions such as
* fullscreen, play/pause, + and - buttons.
@@ -218,7 +229,8 @@ export default class Sandbox extends React.Component {
const fullscreen = this.state.fullscreen ?
(❌)
- : ();
+ : ();
return (
@@ -226,8 +238,8 @@ export default class Sandbox extends React.Component {
-
-
+
+
Nodes: {this.state.data.nodes.length} | Links: {this.state.data.links.length}
@@ -238,12 +250,10 @@ export default class Sandbox extends React.Component {
render() {
// This does not happens in this sandbox scenario running time, but if we set staticGraph config
// to true in the constructor we will provide nodes with initial positions
- const data = this.state.config.staticGraph ?
- {
+ const data = {
nodes: this.decorateGraphNodesWithInitialPositioning(this.state.data.nodes),
links: this.state.data.links
- }
- : this.state.data;
+ };
const graphProps = {
id: 'graph',
@@ -302,8 +312,10 @@ export default class Sandbox extends React.Component {
-
Initial Graph Data
-
+
Graph Data (editable)
+
+
+
);
@@ -312,7 +324,7 @@ export default class Sandbox extends React.Component {
}
class JSONContainer extends React.Component {
- shouldComponentUpdate(nextProps, nextState) {
+ shouldComponentUpdate(nextProps) {
return !this.props.staticData && !ReactD3GraphUtils.isDeepEqual(nextProps.data, this.props.data);
}
diff --git a/sandbox/styles.css b/sandbox/styles.css
index d6e9d7adf..bd6edced6 100644
--- a/sandbox/styles.css
+++ b/sandbox/styles.css
@@ -15,7 +15,7 @@
}
.container__graph {
- grid-column: 1 / 5;
+ grid-column: 1 / 4;
grid-row: 1 / 2;
border: 1px solid black;
}
@@ -32,26 +32,30 @@
max-width: 800px;
max-height: 400px;
border: 1px dotted gray;
- margin-left: 80px;
+ margin-left: 20px;
margin-top: 4px;
+ z-index: 1;
}
.container__graph-data {
grid-column: 1 / 2;
grid-row: 2 / 3;
margin-bottom: 4px;
+ z-index: 2;
}
.container__graph-config {
grid-column: 2 / 3;
grid-row: 2 / 3;
margin-bottom: 4px;
+ z-index: 2;
}
.container__form {
grid-column: 5/ 6;
grid-row: 1 / 4;
min-width: 400px;
+ z-index: 3;
}
.cross-icon {
diff --git a/src/components/graph/graph.helper.js b/src/components/graph/graph.helper.js
index 05492ca10..7a1f7fdca 100644
--- a/src/components/graph/graph.helper.js
+++ b/src/components/graph/graph.helper.js
@@ -30,6 +30,8 @@ import ERRORS from '../../err';
import utils from '../../utils';
+const NODE_PROPS_WHITELIST = ['id', 'highlighted', 'x', 'y', 'index', 'vy', 'vx'];
+
/**
* Create d3 forceSimulation to be applied on the graph.
* {@link https://github.com/d3/d3-force#forceSimulation|d3-force#forceSimulation}
@@ -125,8 +127,8 @@ function _initializeNodes(graphNodes) {
node.highlighted = false;
- if (!node.hasOwnProperty('x')) { node['x'] = 0; }
- if (!node.hasOwnProperty('y')) { node['y'] = 0; }
+ if (!node.hasOwnProperty('x')) { node.x = 0; }
+ if (!node.hasOwnProperty('y')) { node.y = 0; }
nodes[node.id.toString()] = node;
}
@@ -312,10 +314,16 @@ function initializeGraphState({data, id, config}, state) {
_validateGraphData(data);
+ const nodesInputSnapshot = data.nodes.map(n => Object.assign({}, n));
+ const linksInputSnapshot = data.links.map(l => Object.assign({}, l));
+
if (state && state.nodes && state.links) {
// absorb existent positioning
graph = {
- nodes: data.nodes.map(n => Object.assign({}, n, state.nodes[n.id])),
+ nodes: data.nodes.map(n => state.nodes[n.id]
+ ? Object.assign({}, n, utils.pick(state.nodes[n.id], NODE_PROPS_WHITELIST))
+ : Object.assign({}, n)
+ ),
links: {}
};
} else {
@@ -339,13 +347,15 @@ function initializeGraphState({data, id, config}, state) {
config: newConfig,
links,
d3Links,
+ linksInputSnapshot,
nodes,
d3Nodes,
+ nodesInputSnapshot,
highlightedNode: '',
simulation,
newGraphElements: false,
configUpdated: false,
- transform: 1
+ transform: 1,
};
}
diff --git a/src/components/graph/index.jsx b/src/components/graph/index.jsx
index 2f7921809..078217116 100644
--- a/src/components/graph/index.jsx
+++ b/src/components/graph/index.jsx
@@ -182,9 +182,10 @@ export default class Graph extends React.Component {
/**
* The tick function simply calls React set state in order to update component and render nodes
* along time as d3 calculates new node positioning.
+ * @param {Object} state - new state to pass on.
* @returns {undefined}
*/
- _tick = () => this.setState(this.state || {});
+ _tick = (state={}) => this.setState(state);
/**
* Configures zoom upon graph with default or user provided values.
@@ -266,7 +267,7 @@ export default class Graph extends React.Component {
* {@link https://github.com/d3/d3-force#simulation_stop}
* @returns {undefined}
*/
- pauseSimulation = () => !this.state.config.staticGraph && this.state.simulation.stop();
+ pauseSimulation = () => this.state.simulation.stop();
/**
* This method resets all nodes fixed positions by deleting the properties fx (fixed x)
@@ -309,14 +310,14 @@ export default class Graph extends React.Component {
}
componentWillReceiveProps(nextProps) {
- const newGraphElements = nextProps.data.nodes.length !== this.state.d3Nodes.length
- || nextProps.data.links.length !== this.state.d3Links.length;
-
- if (newGraphElements && nextProps.config.staticGraph) {
- utils.throwErr(this.constructor.name, ERRORS.STATIC_GRAPH_DATA_UPDATE);
- }
-
- const configUpdated = !utils.isDeepEqual(nextProps.config, this.state.config);
+ const newGraphElements = nextProps.data.nodes.length !== this.state.nodesInputSnapshot.length
+ || nextProps.data.links.length !== this.state.linksInputSnapshot.length
+ || !utils.isDeepEqual(nextProps.data, {
+ nodes: this.state.nodesInputSnapshot,
+ links: this.state.linksInputSnapshot,
+ });
+ const configUpdated = !utils.isObjectEmpty(nextProps.config)
+ && !utils.isDeepEqual(nextProps.config, this.state.config);
const state = newGraphElements ? graphHelper.initializeGraphState(nextProps, this.state) : this.state;
const config = configUpdated ? utils.merge(DEFAULT_CONFIG, nextProps.config || {}) : this.state.config;
@@ -336,17 +337,17 @@ export default class Graph extends React.Component {
componentDidUpdate() {
// if the property staticGraph was activated we want to stop possible ongoing simulation
- this.state.config.staticGraph && this.state.simulation.stop();
+ this.state.config.staticGraph && this.pauseSimulation();
if (!this.state.config.staticGraph && this.state.newGraphElements) {
this._graphForcesConfig();
this.restartSimulation();
- this.state.newGraphElements = false;
+ this.setState({ newGraphElements: false });
}
if (this.state.configUpdated) {
this._zoomConfig();
- this.state.configUpdated = false;
+ this.setState({ configUpdated: false });
}
}
@@ -360,7 +361,7 @@ export default class Graph extends React.Component {
}
componentWillUnmount() {
- this.state.simulation.stop();
+ this.pauseSimulation();
}
render() {
diff --git a/src/err.js b/src/err.js
index 1bf9d881e..3f747c55e 100644
--- a/src/err.js
+++ b/src/err.js
@@ -1,7 +1,6 @@
/*eslint max-len: ["error", 200]*/
export default {
GRAPH_NO_ID_PROP: "id prop not defined! id property is mandatory and it should be unique.",
- STATIC_GRAPH_DATA_UPDATE: "a static graph cannot receive new data (nodes or links). Make sure config.staticGraph is set to true if you want to update graph data",
INVALID_LINKS: "you provided a invalid links data structure. Links source and target attributes must point to an existent node",
INSUFFICIENT_DATA: "you have not provided enough data for react-d3-graph to render something. You need to provide at least one node"
};
diff --git a/src/utils.js b/src/utils.js
index 875bb20f4..f282a0296 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -12,7 +12,7 @@ const MAX_DEPTH = 20;
/**
* Checks whether a certain object property is from object type and is a non empty object.
* @param {Object} o - the object.
- * @param {number|string} k - the object property.
+ * @param {string} k - the object property.
* @returns {boolean} returns true if o[k] is an non empty object.
* @memberof utils
*/
@@ -39,7 +39,14 @@ function isDeepEqual(o1, o2, _depth=0) {
return false;
}
- for (let k of Object.keys(o1)) {
+ const o1Keys = Object.keys(o1);
+ const o2Keys = Object.keys(o2);
+
+ if (o1Keys.length !== o2Keys.length) {
+ return false;
+ }
+
+ for (let k of o1Keys) {
const nestedO = _isPropertyNestedObject(o1, k) && _isPropertyNestedObject(o2, k);
if (nestedO && _depth < MAX_DEPTH) {
@@ -103,6 +110,23 @@ function merge(o1={}, o2={}, _depth=0) {
return o;
}
+/**
+ * Create new object from the inputted one only with the props passed
+ * in the props list.
+ * @param {Object} o - the object to pick props from.
+ * @param {Array.} props - list of props that we want to pick from o.
+ * @returns {Object} the object resultant from the picking operation.
+ */
+function pick(o, props) {
+ return Object.keys(o).reduce((acc, k) => {
+ if (o.hasOwnProperty(k) && props.includes(k)) {
+ acc[k] = o[k];
+ }
+
+ return acc;
+ }, {});
+}
+
/**
* Helper function for customized error logging.
* @param {string} component - the name of the component where the error is to be thrown.
@@ -120,5 +144,6 @@ export default {
isDeepEqual,
isObjectEmpty,
merge,
+ pick,
throwErr
};
diff --git a/test/component/graph/graph.helper.test.js b/test/component/graph/graph.helper.test.js
index d7cf49b2d..25cc1cba0 100644
--- a/test/component/graph/graph.helper.test.js
+++ b/test/component/graph/graph.helper.test.js
@@ -2,7 +2,6 @@ import * as graphHelper from '../../../src/components/graph/graph.helper';
import config from '../../../src/components/graph/config';
-jest.mock('../../../src/utils');
import utils from '../../../src/utils';
jest.mock('d3-force');
@@ -14,6 +13,13 @@ import {
} from 'd3-force';
describe('Graph Helper', () => {
+ beforeAll(() => {
+ utils.isDeepEqual = jest.fn();
+ utils.isObjectEmpty = jest.fn();
+ utils.merge = jest.fn();
+ utils.throwErr = jest.fn();
+ });
+
describe('#buildNodeProps', () => {
let that = {};
@@ -334,7 +340,21 @@ describe('Graph Helper', () => {
simulation: {
force: forceStub
},
- transform: 1
+ transform: 1,
+ nodesInputSnapshot: [{
+ id: 'A'
+ }, {
+ id: 'B'
+ }, {
+ id: 'C'
+ }],
+ linksInputSnapshot: [{
+ source: 'A',
+ target: 'B'
+ }, {
+ source: 'C',
+ target: 'A'
+ }]
}
);
});
diff --git a/test/utils.test.js b/test/utils.test.js
index 113d249de..013157d4d 100644
--- a/test/utils.test.js
+++ b/test/utils.test.js
@@ -63,8 +63,8 @@ describe('Utils', () => {
beforeEach(() => {
that.o1 = {
a:1,
- b:{
- c:{ d: false, e: 'test', f: 12 },
+ b: {
+ c: { d: false, e: 'test', f: 12 },
g: 'test',
h: undefined,
i: {},
@@ -74,7 +74,8 @@ describe('Utils', () => {
m: {
n: {
o: 1
- }
+ },
+ p: [ { x: 1 }, { y: 2 } ]
}
}
}
@@ -82,8 +83,8 @@ describe('Utils', () => {
that.o2 = {
a:1,
- b:{
- c:{ d: false, e: 'test', f: 12 },
+ b: {
+ c: { d: false, e: 'test', f: 12 },
g: 'test',
h: undefined,
i: {},
@@ -93,7 +94,8 @@ describe('Utils', () => {
m: {
n: {
o: 1
- }
+ },
+ p: [ { x: 1 }, { y: 2 } ]
}
}
}
@@ -178,6 +180,40 @@ describe('Utils', () => {
that.o2.b.g = [1, 2, 3];
expect(utils.isDeepEqual(that.o1, that.o2)).toEqual(false);
});
+
+ test('should return false when o1.a.b.c and o2.a.b.c are objects with different number of properties', () => {
+ that.o2.b.c = { d: false, e: 'test', f: 12, ff: false };
+ expect(utils.isDeepEqual(that.o1, that.o2)).toEqual(false);
+ });
+
+ test('should return false when o1.b.j.m.p array\'s first object has different x value ', () => {
+ that.o1.b.j.m.p[0].x = 9000;
+ expect(utils.isDeepEqual(that.o1, that.o2)).toEqual(false);
+ });
+ });
+
+ describe('#pick', () => {
+ let that = {};
+
+ beforeEach(() => {
+ that.o = {
+ a: 1,
+ b: {
+ j: {
+ k: null,
+ l: 'test',
+ }
+ },
+ c: 'test',
+ f: 0
+ };
+ });
+
+ test('should pick given props and return expected object', () => {
+ const result = utils.pick(that.o, ['a', 'f', 'not a o prop']);
+
+ expect(result).toEqual({ a: 1, f: 0 });
+ });
});
describe('#throwErr', () => {
diff --git a/yarn.lock b/yarn.lock
index 184e023e6..5d4cd4c49 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -74,8 +74,8 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e"
"@types/node@*":
- version "9.4.5"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.5.tgz#d2a90c634208173d1b1a0a6ba9f1df3de62edcf5"
+ version "9.4.6"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e"
"@types/sinon-chai@2.7.29":
version "2.7.29"
@@ -239,8 +239,8 @@ are-we-there-yet@~1.1.2:
readable-stream "^2.0.6"
argparse@^1.0.7:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
dependencies:
sprintf-js "~1.0.2"
@@ -324,8 +324,8 @@ asap@~2.0.3:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
asn1.js@^4.0.0:
- version "4.9.2"
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
+ version "4.10.1"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
dependencies:
bn.js "^4.0.0"
inherits "^2.0.1"
@@ -1258,12 +1258,12 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
base62@^1.1.0:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/base62/-/base62-1.2.5.tgz#f59b629268aadafa2887667546b1fe3e15565507"
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/base62/-/base62-1.2.7.tgz#5c01aad73c0124f9535cff1bdb9c4e6ccf838cfb"
base64-js@^1.0.2:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801"
base@^0.11.1:
version "0.11.2"
@@ -1386,8 +1386,8 @@ braces@^1.8.2:
repeat-element "^1.1.2"
braces@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e"
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb"
dependencies:
arr-flatten "^1.1.0"
array-unique "^0.3.2"
@@ -1395,6 +1395,7 @@ braces@^2.3.0:
extend-shallow "^2.0.1"
fill-range "^4.0.0"
isobject "^3.0.1"
+ kind-of "^6.0.2"
repeat-element "^1.1.2"
snapdragon "^0.8.1"
snapdragon-node "^2.0.1"
@@ -1580,12 +1581,12 @@ caniuse-api@^1.5.2:
lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
- version "1.0.30000808"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000808.tgz#30dfd83009d5704f02dffb37725068ed12a366bb"
+ version "1.0.30000809"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000809.tgz#b0b88434a598f40b546d46a4dbd839b0ff798f4d"
caniuse-lite@^1.0.30000792:
- version "1.0.30000808"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000808.tgz#7d759b5518529ea08b6705a19e70dbf401628ffc"
+ version "1.0.30000809"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000809.tgz#1e12c1344b8f74d56737ee2614bcedb648943479"
caseless@~0.12.0:
version "0.12.0"
@@ -1620,7 +1621,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
dependencies:
@@ -1829,9 +1830,9 @@ colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
-combined-stream@^1.0.5, combined-stream@~1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
dependencies:
delayed-stream "~1.0.0"
@@ -1878,10 +1879,10 @@ component-emitter@^1.2.1:
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
compressible@~2.0.11:
- version "2.0.12"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
+ version "2.0.13"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9"
dependencies:
- mime-db ">= 1.30.0 < 2"
+ mime-db ">= 1.33.0 < 2"
compression@^1.5.2:
version "1.7.1"
@@ -2012,7 +2013,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-create-react-class@^15.6.0:
+create-react-class@^15.5.2, create-react-class@^15.6.0:
version "15.6.3"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036"
dependencies:
@@ -2158,9 +2159,9 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
dependencies:
cssom "0.3.x"
-cypress@1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/cypress/-/cypress-1.4.1.tgz#62f4074a00e6f12e2dfe388a7f4e816a49ceb03f"
+cypress@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/cypress/-/cypress-2.0.1.tgz#cbb62e7c2ff7e646aab5ab0570db07ceaecf3d4e"
dependencies:
"@cypress/listr-verbose-renderer" "0.4.1"
"@cypress/xvfb" "1.1.3"
@@ -2551,6 +2552,13 @@ define-property@^1.0.0:
dependencies:
is-descriptor "^1.0.0"
+define-property@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
+ dependencies:
+ is-descriptor "^1.0.2"
+ isobject "^3.0.1"
+
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
@@ -2903,8 +2911,8 @@ envify@^3.0.0:
through "~2.3.4"
errno@^0.1.3:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026"
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
dependencies:
prr "~1.0.1"
@@ -2940,8 +2948,8 @@ es-to-primitive@^1.1.1:
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
- version "0.10.38"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3"
+ version "0.10.39"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.39.tgz#fca21b67559277ca4ac1a1ed7048b107b6f76d87"
dependencies:
es6-iterator "~2.0.3"
es6-symbol "~3.1.1"
@@ -3420,7 +3428,7 @@ extend-shallow@^2.0.1:
dependencies:
is-extendable "^0.1.0"
-extend-shallow@^3.0.0:
+extend-shallow@^3.0.0, extend-shallow@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
dependencies:
@@ -3666,11 +3674,11 @@ form-data@~2.1.1:
mime-types "^2.1.12"
form-data@~2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
dependencies:
asynckit "^0.4.0"
- combined-stream "^1.0.5"
+ combined-stream "1.0.6"
mime-types "^2.1.12"
forwarded@~0.1.2:
@@ -4108,12 +4116,12 @@ hoek@2.x.x:
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoek@4.x.x:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
hoist-non-react-statics@^2.3.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40"
home-or-tmp@^2.0.0:
version "2.0.0"
@@ -4472,7 +4480,7 @@ is-descriptor@^0.1.0:
is-data-descriptor "^0.1.4"
kind-of "^5.0.0"
-is-descriptor@^1.0.0:
+is-descriptor@^1.0.0, is-descriptor@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
dependencies:
@@ -4547,12 +4555,17 @@ is-installed-globally@0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
+is-my-ip-valid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
+
is-my-json-valid@^2.10.0:
- version "2.17.1"
- resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471"
+ version "2.17.2"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
+ is-my-ip-valid "^1.0.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
@@ -4568,11 +4581,15 @@ is-number@^3.0.0:
dependencies:
kind-of "^3.0.2"
-is-odd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088"
+is-number@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
+
+is-odd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24"
dependencies:
- is-number "^3.0.0"
+ is-number "^4.0.0"
is-path-cwd@^1.0.0:
version "1.0.0"
@@ -4674,9 +4691,9 @@ is-whitespace-character@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz#9ae0176f3282b65457a1992cdb084f8a5f833e3b"
-is-windows@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
+is-windows@^1.0.1, is-windows@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
is-word-character@^1.0.0:
version "1.0.1"
@@ -4720,24 +4737,24 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
istanbul-api@^1.1.14:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.2.tgz#e17cd519dd5ec4141197f246fdf380b75487f3b1"
dependencies:
async "^2.1.4"
fileset "^2.0.2"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.1.2"
istanbul-lib-hook "^1.1.0"
- istanbul-lib-instrument "^1.9.1"
- istanbul-lib-report "^1.1.2"
- istanbul-lib-source-maps "^1.2.2"
- istanbul-reports "^1.1.3"
+ istanbul-lib-instrument "^1.9.2"
+ istanbul-lib-report "^1.1.3"
+ istanbul-lib-source-maps "^1.2.3"
+ istanbul-reports "^1.1.4"
js-yaml "^3.7.0"
mkdirp "^0.5.1"
once "^1.4.0"
-istanbul-lib-coverage@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
+istanbul-lib-coverage@^1.1.1, istanbul-lib-coverage@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14"
istanbul-lib-hook@^1.1.0:
version "1.1.0"
@@ -4745,40 +4762,40 @@ istanbul-lib-hook@^1.1.0:
dependencies:
append-transform "^0.4.0"
-istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.1:
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e"
+istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.2:
+ version "1.9.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babylon "^6.18.0"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.1.2"
semver "^5.3.0"
-istanbul-lib-report@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425"
+istanbul-lib-report@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz#2df12188c0fa77990c0d2176d2d0ba3394188259"
dependencies:
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.1.2"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c"
+istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6"
dependencies:
debug "^3.1.0"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.1.2"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10"
+istanbul-reports@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.4.tgz#5ccba5e22b7b5a5d91d5e0a830f89be334bf97bd"
dependencies:
handlebars "^4.0.3"
@@ -5172,7 +5189,7 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
-kind-of@^5.0.0, kind-of@^5.0.2:
+kind-of@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
@@ -5605,19 +5622,15 @@ miller-rabin@^4.0.0:
bn.js "^4.0.0"
brorand "^1.0.1"
-"mime-db@>= 1.30.0 < 2":
- version "1.32.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414"
-
-mime-db@~1.30.0:
- version "1.30.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
+"mime-db@>= 1.33.0 < 2", mime-db@~1.33.0:
+ version "1.33.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
-mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
- version "2.1.17"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
+mime-types@^2.1.12, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7:
+ version "2.1.18"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies:
- mime-db "~1.30.0"
+ mime-db "~1.33.0"
mime@1.4.1:
version "1.4.1"
@@ -5695,6 +5708,10 @@ module-deps-sortable@4.0.6:
through2 "^2.0.0"
xtend "^4.0.0"
+mousetrap@^1.5.2:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.1.tgz#2a085f5c751294c75e7e81f6ec2545b29cbf42d9"
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -5719,16 +5736,17 @@ nan@^2.3.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
nanomatch@^1.2.5:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79"
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.8.tgz#e2fb86f002b408424731ad1c92564343c5063378"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
- define-property "^1.0.0"
- extend-shallow "^2.0.1"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
fragment-cache "^0.2.1"
- is-odd "^1.0.0"
- kind-of "^5.0.2"
+ is-odd "^2.0.0"
+ is-windows "^1.0.2"
+ kind-of "^6.0.2"
object.pick "^1.3.0"
regex-not "^1.0.0"
snapdragon "^0.8.1"
@@ -6048,8 +6066,8 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
osenv@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
@@ -6572,12 +6590,12 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
supports-color "^3.2.3"
postcss@^6.0.1:
- version "6.0.17"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.17.tgz#e259a051ca513f81e9afd0c21f7f82eda50c65c5"
+ version "6.0.19"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.19.tgz#76a78386f670b9d9494a655bf23ac012effd1555"
dependencies:
- chalk "^2.3.0"
+ chalk "^2.3.1"
source-map "^0.6.1"
- supports-color "^5.1.0"
+ supports-color "^5.2.0"
prelude-ls@~1.1.2:
version "1.1.2"
@@ -6747,8 +6765,8 @@ randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
safe-buffer "^5.1.0"
randomfill@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
dependencies:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
@@ -6799,6 +6817,22 @@ react-dom@^0.14.0:
version "0.14.9"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.14.9.tgz#05064a3dcf0fb1880a3b2bfc9d58c55d8d9f6293"
+react-editable-json-tree@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/react-editable-json-tree/-/react-editable-json-tree-2.1.0.tgz#c865ed0e77788f4512eea486f692f27563e645b7"
+ dependencies:
+ prop-types "^15.6.0"
+ react-hotkeys "^0.10.0"
+
+react-hotkeys@^0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-0.10.0.tgz#d1e78bd63f16d6db58d550d33c8eb071f35d94fb"
+ dependencies:
+ create-react-class "^15.5.2"
+ lodash "^4.13.1"
+ mousetrap "^1.5.2"
+ prop-types "^15.5.8"
+
react-jsonschema-form@0.50.1:
version "0.50.1"
resolved "https://registry.yarnpkg.com/react-jsonschema-form/-/react-jsonschema-form-0.50.1.tgz#30652f701645f3af25435ec5f6c42260c426b881"
@@ -7888,7 +7922,7 @@ supports-color@^4.0.0, supports-color@^4.1.0, supports-color@^4.2.1:
dependencies:
has-flag "^2.0.0"
-supports-color@^5.1.0, supports-color@^5.2.0:
+supports-color@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
dependencies:
@@ -7951,8 +7985,8 @@ tar@^2.2.1:
inherits "2"
test-exclude@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.0.tgz#07e3613609a362c74516a717515e13322ab45b3c"
dependencies:
arrify "^1.0.1"
micromatch "^2.3.11"
@@ -8124,11 +8158,11 @@ type-check@~0.3.2:
prelude-ls "~1.1.2"
type-is@~1.6.15:
- version "1.6.15"
- resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
+ version "1.6.16"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
dependencies:
media-typer "0.3.0"
- mime-types "~2.1.15"
+ mime-types "~2.1.18"
typedarray@^0.0.6, typedarray@~0.0.5:
version "0.0.6"
@@ -8139,8 +8173,8 @@ ua-parser-js@^0.7.9:
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
uglify-js@3.3.x:
- version "3.3.10"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.10.tgz#8e47821d4cf28e14c1826a0078ba0825ed094da8"
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.11.tgz#e9d058b20715138bb4e8e5cae2ea581686bdaae3"
dependencies:
commander "~2.14.1"
source-map "~0.6.1"