diff --git a/README.md b/README.md
index 864adc4..952c15c 100644
--- a/README.md
+++ b/README.md
@@ -24,8 +24,9 @@ Update data
First download raw data from ClinicalTrials.gov (instructions are in the Jupyter notebook). Then run the notebook, toggling `REGENERATE_SUMMARY` and `REGENERATE_PUBMED_LINKS` to regenerate the data from scratch. Running this notebook will automatically update the data used in the app.
+To rebuild the JavaScript, run `npm run watch` (development) and `npm run build` (production).
+
Run tests
---------
-Test the data utility functions, run in the `data` directory: `nosetests tests/test_utils.py`
-Test the JavaScript: TBA.
+Toest the data utility functions, run in the `data` directory: `nosetests tests/test_utils.py`. To test the JavaScript: `npm run test`.
diff --git a/app/js/package.json b/app/js/package.json
index 1eaed02..0261ba1 100644
--- a/app/js/package.json
+++ b/app/js/package.json
@@ -23,7 +23,8 @@
},
"devDependencies": {
"browserify": "^9.0.8",
- "mocha": "^2.2.5",
+ "chai": "^3.5.0",
+ "mocha": "^2.5.3",
"uglifyjs": "^2.4.10",
"watchify": "^3.2.1"
}
diff --git a/app/js/test/mocha.opts b/app/js/test/mocha.opts
new file mode 100644
index 0000000..a35a923
--- /dev/null
+++ b/app/js/test/mocha.opts
@@ -0,0 +1,2 @@
+--reporter dot
+--ui bdd
\ No newline at end of file
diff --git a/app/js/test/test_utils.js b/app/js/test/test_utils.js
new file mode 100644
index 0000000..df776fa
--- /dev/null
+++ b/app/js/test/test_utils.js
@@ -0,0 +1,45 @@
+var expect = require('chai').expect;
+var utils = require('../utils');
+
+describe('Utils', function () {
+ describe('#getChartDescription', function () {
+ it('should construct description for a sponsor', function () {
+ var data = {
+ overdue: 4,
+ rate: 0.4,
+ total: 10
+ }, name = 'Sanofi', orgName = 'sanofi';
+ var description = utils.getChartDescription(data, name, orgName);
+ var expected = "Since Jan 2006, Sanofi completed" +
+ " 10 eligible trials and " +
+ "hasn't published results for 4 trials. That " +
+ "means 40.0% of its trials are missing results. See " +
+ "all its completed trials on " +
+ "ClinicalTrials.gov .";
+ expect(description).to.equal(expected);
+ });
+
+ it('should construct description for all sponsors', function () {
+ var data = {
+ overdue: 40,
+ rate: 0.4,
+ total: 100
+ }, name = 'all major trial sponsors', orgName = '';
+ var description = utils.getChartDescription(data, name, orgName);
+ var expected = "Since Jan 2006, all major trial " +
+ "sponsors completed" +
+ " 100 eligible trials and " +
+ "haven't published results for 40 trials. That " +
+ "means 40.0% of their trials are missing results. ";
+ expect(description).to.equal(expected);
+ });
+ });
+ // describe('#reshapeData', function () {
+ // it('should reshape our data', function () {
+ // });
+ // });
+});
diff --git a/app/js/utils.js b/app/js/utils.js
index 8c08d6a..0223d4a 100644
--- a/app/js/utils.js
+++ b/app/js/utils.js
@@ -8,8 +8,8 @@ var getChartDescription = function (data, name, orgName) {
title += data.overdue.toLocaleString() + ' trial';
title += (data.overdue === 1) ? '' : 's';
title += '. ';
- title += 'That means ' + (data.rate *100).toFixed(1) + '% of ';
- title += (orgName === '') ? ' their ' : ' its ';
+ title += 'That means ' + (data.rate * 100).toFixed(1) + '% of ';
+ title += (orgName === '') ? 'their ' : 'its ';
title += 'trials are missing results. ';
url = 'https://clinicaltrials.gov/ct2/results/displayOpt?';
url += 'flds=a&flds=b&flds=f&flds=c&flds=g&flds=s&flds=u&submit_fld_opt=on';