Skip to content

Commit

Permalink
Feature/test suite (#5)
Browse files Browse the repository at this point in the history
* Update package.json. Configure jest test suite. Update lint rules

* SCR: USNA - Add test suite for utils. Add deep object compare implementation

* Improve compare. Clone mock graph data for sandbox

* Clean generated config when clicking reset config button

* Remove json stringify comparision usage

* Organize test files

* Add Link tests. Organize tests structure

* Improve src/utils. Add documentation for src/utils

* Test isEqual behavior against circular structures

* Improve utils tests. Add coverage to gitignore

* Add Node tests

* Add empty object fix on isEqual method

* Group private methods on top of files. Pseudo private function naming in helper graph

* Fix lint errors. Some refactor accross code base. Add some new lint configs

* Init tests for Graph component

* Remove unnecessary webpack plugins

* Remove usage of Object.values. Update graph snapshot

* Major progress in Graph unit tests

* Fix link highlight logic in graph helper 🐛
  • Loading branch information
danielcaldas committed Apr 23, 2017
1 parent 6deebb5 commit b5695f4
Show file tree
Hide file tree
Showing 23 changed files with 2,866 additions and 350 deletions.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["react", "es2015", "stage-0"]
}
33 changes: 21 additions & 12 deletions .eslintrc.js
@@ -1,25 +1,34 @@
module.exports = {
"parser": "babel-eslint",
"extends": [
"eslint:recommended"
],
"plugins": [
"standard",
"promise",
"react"
],
"globals": {
"document": true,
"Reflect": true,
"window": true
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"ecmaFeatures": {
"jsx": true
}
},
"plugins": [
"standard",
"promise",
"react"
],
"rules": {
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error"
},
"globals": {
"document": true,
"Reflect": true,
"window": true
"react/jsx-uses-vars": "error",
"camelcase": "error",
"keyword-spacing": "error",
"max-len": ["error", 120, 4, { "ignoreComments": true }],
"max-lines": ["error", {"max": 250, "skipComments": true}],
"newline-after-var": ["error", "always"],
"no-nested-ternary": "error",
"no-useless-constructor": "error",
"semi": "error"
}
};
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -67,5 +67,6 @@ typings/
dist/
DOCUMENTATION.md
docs
coverage
sandbox/rd3g.sandbox.bundle.js
sandbox/rd3g.sandbox.bundle.js.map
12 changes: 10 additions & 2 deletions README.md
Expand Up @@ -46,8 +46,16 @@ export default {
```

## TODOs
This are some ideas to further development:
- Expose a graph property **background-color** that is applied to the svg graph container.
This consists in a list of ideas for further development:
- Expose a graph property **background-color** that is applied to the svg graph container;
- Expose d3-force values as configurable such as **alphaTarget** simulation value;
- Improve opacity/highlightBehavior strategy maybe use a global *background: rgba(...)* value and then set a higher
value on selected nodes;
- At the moment highlightBehavior is highlighting the mouse hovered node, its 1st degree connections and their 1st
degree connections. Make **highlightBehaviorDegree** which consists in a *step value* on the depth that we wish to highlight.

#### Sanbox/Playground
- Improve page layout (optimize space).

## Contributions
Contributions are welcome fell free to submit new features or simply grab something from
Expand Down
41 changes: 25 additions & 16 deletions package.json
Expand Up @@ -4,35 +4,53 @@
"description": "React component to build interactive and configurable graphs with d3 effortlessly",
"author": "Daniel Caldas",
"license": "MIT",
"scripts": {
"dev": "node_modules/.bin/webpack-dev-server -d --content-base sandbox --inline --hot --port 3002",
"dist": "node_modules/.bin/npm-run-all --parallel dist:*",
"dist:rd3g": "webpack --config webpack.config.dist.js -p --display-modules",
"dist:sandbox": "webpack --config webpack.config.js -p --display-modules",
"docs": "node_modules/documentation/bin/documentation.js build src/**/*.js -f html -o docs && node_modules/documentation/bin/documentation.js build src/**/*.js -f md > DOCUMENTATION.md",
"lint": "node_modules/eslint/bin/eslint.js --config=.eslintrc.js \"src/**/*.js\"",
"test": "jest --verbose --coverage",
"test:clean": "jest --no-cache --updateSnapshot --verbose --coverage",
"test:watch": "jest --verbose --watchAll"
},
"dependencies": {
"d3": "4.7.4",
"react": "15.4.2"
"react": "^15.5.0"
},
"devDependencies": {
"babel-core": "6.24.0",
"babel-jest": "19.0.0",
"babel-loader": "6.4.1",
"babel-plugin-add-module-exports": "0.2.1",
"babel-plugin-react-html-attrs": "2.0.0",
"babel-plugin-transform-class-properties": "6.22.0",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-preset-es2015": "6.16.0",
"babel-preset-react": "6.16.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-react": "6.24.1",
"babel-preset-stage-0": "6.16.0",
"css-loader": "^0.28.0",
"css-loader": "0.28.0",
"documentation": "4.0.0-beta.18",
"eslint": "3.18.0",
"eslint-config-recommended": "1.5.0",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "2.1.1",
"html-webpack-plugin": "2.28.0",
"jest": "19.0.2",
"npm-run-all": "4.0.2",
"react-dom": "15.4.2",
"react-addons-test-utils": "^15.5.0",
"react-dom": "^15.5.0",
"react-jsonschema-form": "0.46.0",
"react-router-dom": "4.0.0",
"style-loader": "^0.16.1",
"react-test-renderer": "^15.5.0",
"style-loader": "0.16.1",
"webpack": "2.3.2",
"webpack-dev-server": "2.4.2"
},
"engines": {
"node": ">=6.9.5"
},
"repository": {
"type": "git",
"url": "git+https://github.com/danielcaldas/react-d3-graph.git"
Expand All @@ -47,14 +65,5 @@
"social-network-analysis",
"social-network-graph",
"visualization"
],
"scripts": {
"dev": "node_modules/.bin/webpack-dev-server -d --content-base sandbox --inline --hot --port 3002",
"dist": "node_modules/.bin/npm-run-all --parallel dist:*",
"dist:rd3g": "webpack --config webpack.config.dist.js -p --display-modules",
"dist:sandbox": "webpack --config webpack.config.js -p --display-modules",
"docs": "node_modules/documentation/bin/documentation.js build src/**/*.js -f html -o docs && node_modules/documentation/bin/documentation.js build src/**/*.js -f md > DOCUMENTATION.md",
"lint": "node_modules/eslint/bin/eslint.js --config=.eslintrc.js \"src/**/*.js\"",
"test": "echo \"Error: no test specified\" && exit 1"
}
]
}
13 changes: 8 additions & 5 deletions sandbox/Sandbox.js
Expand Up @@ -93,6 +93,8 @@ export default class Sandbox extends React.Component {
}

resetGraphConfig = () => {
const generatedConfig = {};

const schemaProps = Utils.generateFormSchema(defaultConfig, '', {});

const schema = {
Expand All @@ -102,14 +104,15 @@ export default class Sandbox extends React.Component {

this.setState({
config: defaultConfig,
generatedConfig,
schema
});
}

render() {
const graphProps = {
id: 'graph',
data: mock,
data: JSON.parse(JSON.stringify(mock)),
config: this.state.config,
onClickNode: this.onClickNode,
onClickLink: this.onClickLink,
Expand All @@ -130,7 +133,7 @@ export default class Sandbox extends React.Component {
<Graph ref='graph' {...graphProps}/>
</div>
<div className='container__form'>
<h4>Graph configurations</h4>
<h4>react-d3-graph configurations</h4>
<Form className='form-wrapper'
schema={this.state.schema}
uiSchema={this.uiSchema}
Expand All @@ -143,11 +146,11 @@ export default class Sandbox extends React.Component {
</div>
<div className='container__graph-config'>
<h4>Your config</h4>
<JSONContainer data={this.state.generatedConfig} />
<JSONContainer data={this.state.generatedConfig} staticData={false} />
</div>
<div className='container__graph-data'>
<h4>Graph data</h4>
<JSONContainer data={mock} />
<JSONContainer data={mock} staticData={true}/>
</div>
</div>
);
Expand All @@ -156,7 +159,7 @@ export default class Sandbox extends React.Component {

class JSONContainer extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return JSON.stringify(nextProps.data) !== JSON.stringify(this.props.data);
return !this.props.staticData && !ReactD3GraphUtils.isEqual(nextProps.data, this.props.data);
}

render() {
Expand Down
154 changes: 77 additions & 77 deletions sandbox/miserables.js
@@ -1,82 +1,82 @@
export default {
nodes: [
{id: 'Myriel', group: 1},
{id: 'Napoleon', group: 1},
{id: 'Mlle.Baptistine', group: 1},
{id: 'Mme.Magloire', group: 1},
{id: 'CountessdeLo', group: 1},
{id: 'Geborand', group: 1},
{id: 'Champtercier', group: 1},
{id: 'Cravatte', group: 1},
{id: 'Count', group: 1},
{id: 'OldMan', group: 1},
{id: 'Labarre', group: 2},
{id: 'Valjean', group: 2},
{id: 'Marguerite', group: 3},
{id: 'Mme.deR', group: 2},
{id: 'Isabeau', group: 2},
{id: 'Gervais', group: 2},
{id: 'Tholomyes', group: 3},
{id: 'Listolier', group: 3},
{id: 'Fameuil', group: 3},
{id: 'Blacheville', group: 3},
{id: 'Favourite', group: 3},
{id: 'Dahlia', group: 3},
{id: 'Zephine', group: 3},
{id: 'Fantine', group: 3},
{id: 'Mme.Thenardier', group: 4},
{id: 'Thenardier', group: 4},
{id: 'Cosette', group: 5},
{id: 'Javert', group: 4},
{id: 'Fauchelevent', group: 0},
{id: 'Bamatabois', group: 2},
{id: 'Perpetue', group: 3},
{id: 'Simplice', group: 2},
{id: 'Scaufflaire', group: 2},
{id: 'Woman1', group: 2},
{id: 'Judge', group: 2},
{id: 'Champmathieu', group: 2},
{id: 'Brevet', group: 2},
{id: 'Chenildieu', group: 2},
{id: 'Cochepaille', group: 2},
{id: 'Pontmercy', group: 4},
{id: 'Boulatruelle', group: 6},
{id: 'Eponine', group: 4},
{id: 'Anzelma', group: 4},
{id: 'Woman2', group: 5},
{id: 'MotherInnocent', group: 0},
{id: 'Gribier', group: 0},
{id: 'Jondrette', group: 7},
{id: 'Mme.Burgon', group: 7},
{id: 'Gavroche', group: 8},
{id: 'Gillenormand', group: 5},
{id: 'Magnon', group: 5},
{id: 'Mlle.Gillenormand', group: 5},
{id: 'Mme.Pontmercy', group: 5},
{id: 'Mlle.Vaubois', group: 5},
{id: 'Lt.Gillenormand', group: 5},
{id: 'Marius', group: 8},
{id: 'BaronessT', group: 5},
{id: 'Mabeuf', group: 8},
{id: 'Enjolras', group: 8},
{id: 'Combeferre', group: 8},
{id: 'Prouvaire', group: 8},
{id: 'Feuilly', group: 8},
{id: 'Courfeyrac', group: 8},
{id: 'Bahorel', group: 8},
{id: 'Bossuet', group: 8},
{id: 'Joly', group: 8},
{id: 'Grantaire', group: 8},
{id: 'MotherPlutarch', group: 9},
{id: 'Gueulemer', group: 4},
{id: 'Babet', group: 4},
{id: 'Claquesous', group: 4},
{id: 'Montparnasse', group: 4},
{id: 'Toussaint', group: 5},
{id: 'Child1', group: 10},
{id: 'Child2', group: 10},
{id: 'Brujon', group: 4},
{id: 'Mme.Hucheloup', group: 8}
{id: 'Myriel'},
{id: 'Napoleon'},
{id: 'Mlle.Baptistine'},
{id: 'Mme.Magloire'},
{id: 'CountessdeLo'},
{id: 'Geborand'},
{id: 'Champtercier'},
{id: 'Cravatte'},
{id: 'Count'},
{id: 'OldMan'},
{id: 'Labarre'},
{id: 'Valjean'},
{id: 'Marguerite'},
{id: 'Mme.deR'},
{id: 'Isabeau'},
{id: 'Gervais'},
{id: 'Tholomyes'},
{id: 'Listolier'},
{id: 'Fameuil'},
{id: 'Blacheville'},
{id: 'Favourite'},
{id: 'Dahlia'},
{id: 'Zephine'},
{id: 'Fantine'},
{id: 'Mme.Thenardier'},
{id: 'Thenardier'},
{id: 'Cosette'},
{id: 'Javert'},
{id: 'Fauchelevent'},
{id: 'Bamatabois'},
{id: 'Perpetue'},
{id: 'Simplice'},
{id: 'Scaufflaire'},
{id: 'Woman1'},
{id: 'Judge'},
{id: 'Champmathieu'},
{id: 'Brevet'},
{id: 'Chenildieu'},
{id: 'Cochepaille'},
{id: 'Pontmercy'},
{id: 'Boulatruelle'},
{id: 'Eponine'},
{id: 'Anzelma'},
{id: 'Woman2'},
{id: 'MotherInnocent'},
{id: 'Gribier'},
{id: 'Jondrette'},
{id: 'Mme.Burgon'},
{id: 'Gavroche'},
{id: 'Gillenormand'},
{id: 'Magnon'},
{id: 'Mlle.Gillenormand'},
{id: 'Mme.Pontmercy'},
{id: 'Mlle.Vaubois'},
{id: 'Lt.Gillenormand'},
{id: 'Marius'},
{id: 'BaronessT'},
{id: 'Mabeuf'},
{id: 'Enjolras'},
{id: 'Combeferre'},
{id: 'Prouvaire'},
{id: 'Feuilly'},
{id: 'Courfeyrac'},
{id: 'Bahorel'},
{id: 'Bossuet'},
{id: 'Joly'},
{id: 'Grantaire'},
{id: 'MotherPlutarch'},
{id: 'Gueulemer'},
{id: 'Babet'},
{id: 'Claquesous'},
{id: 'Montparnasse'},
{id: 'Toussaint'},
{id: 'Child1'},
{id: 'Child2'},
{id: 'Brujon'},
{id: 'Mme.Hucheloup'}
],
links: [
{source: 'Napoleon', target: 'Myriel', value: 1},
Expand Down

0 comments on commit b5695f4

Please sign in to comment.