Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typo/race condition #49

Merged
merged 4 commits into from
Mar 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.*node_modules/flow-bin.*
.*node_modules/jsxhint.*
.*node_modules/.*mocha.*
.*node_modules/reactify.*
.*build.*

[include]
Expand Down
11 changes: 11 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"node": true, // allow "require", "module.exports", etc.
"browser": true, // allow document, window, console, etc.
"lastsemic": true, // allow missing semicolons in one-liners
"unused": "vars", // unused vars are bad, but function params are OK
"undef": true, // catch use before define errors
"globalstrict": true, // allow module-level "use strict", which is OK with browserify.
"laxbreak": true, // allow ambiguous continuation lines, e.g. "+" on next line
"esnext": true, // allow ES6 features
"mocha": true // allow "describe", "it" and friends
}
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ node_js:

before_install: npm install -g grunt-cli

script: grunt travis && ./scripts/post-coverage.sh
script: grunt travis && ./scripts/lint.sh && ./scripts/post-coverage.sh
5 changes: 4 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ module.exports = function(grunt) {
"reactify",
{
harmony: true,
stripTypes: true
stripTypes: true,
reactOptions: {
nonStrictEs6module: true
}
}
]
],
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"type": "git",
"url": "https://github.com/danvk/pileup.js.git"
},
"scripts": {
"lint": "./scripts/lint.sh",
"test": "grunt test"
},
"author": "Dan Vanderkam",
"license": "Apache2",
"bugs": {
Expand Down Expand Up @@ -39,12 +43,13 @@
"grunt-jscoverage": "^0.1.3",
"grunt-mocha-phantomjs": ">=0.6.1",
"grunt-mocha-test": "^0.12.7",
"jsxhint": "git://github.com/danvk/JSXHint#nonStrictEs6module",
"lcov-parse": "0.0.9",
"mocha": "^2.1.0",
"mocha-lcov-reporter": ">=0.0.2",
"parse-data-uri": "^0.2.0",
"react-tools": "^0.13.1",
"reactify": "^1.0.0",
"reactify": "danvk/reactify",
"sinon": "^1.12.2",
"source-map": "^0.3.0"
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
./node_modules/.bin/jsxhint --es6module --harmony 'src/**/*.js' 'test/**/*.js'
4 changes: 2 additions & 2 deletions src/BigBed.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function attachContigToBedRows(beds, contigMap) {
// Internal function for fetching features by block.
function fetchFeaturesByBlock(contigRange, header, cirTree, remoteFile): Array<BedBlock> {
var blocks = findOverlappingBlocks(header, cirTree, contigRange);
if (blocks.length == 0) {
if (blocks.length === 0) {
return Q.when([]);
}

Expand Down Expand Up @@ -240,7 +240,7 @@ class BigBed {
(header, cirTree, contigMap) => {
var contigIx = getContigId(contigMap, range.contig);
if (contigIx === null) {
throw `Invalid contig ${contig}`;
throw `Invalid contig ${range.contig}`;
}
var indexRange = new ContigInterval(contigIx, range.start(), range.stop());
return fetchFeaturesByBlock(indexRange, header, cirTree, this.remoteFile)
Expand Down
2 changes: 1 addition & 1 deletion src/BigBedDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function createBigBedDataSource(remoteSource: BigBed): BigBedSource {
var genes: {[key:string]: Gene} = {};

// Ranges for which we have complete information -- no need to hit network.
var coveredRanges: Array<ContigInterval<string>> = []
var coveredRanges: Array<ContigInterval<string>> = [];

function addGene(newGene) {
if (!genes[newGene.id]) {
Expand Down
1 change: 1 addition & 0 deletions src/ContigInterval.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* @flow */
'use strict';

var Interval = require('./Interval');

Expand Down
1 change: 1 addition & 0 deletions src/Controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Controls for zooming to particular ranges of the genome.
* @flow
*/
'use strict';

var React = require('react'),
types = require('./types'),
Expand Down
9 changes: 5 additions & 4 deletions src/GeneTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Visualization of genes, including exons and coding regions.
* @flow
*/
'use strict';

var React = require('react/addons'),
_ = require('underscore'),
d3 = require('d3'),
Expand Down Expand Up @@ -39,7 +41,7 @@ var NonEmptyGeneTrack = React.createClass({
.append('svg');

// These define the left/right arrow patterns for sense/antisense genes.
var defs = svg.append('defs')
var defs = svg.append('defs');
defs.append('pattern')
.attr({
'id': 'antisense',
Expand Down Expand Up @@ -95,7 +97,6 @@ var NonEmptyGeneTrack = React.createClass({
},
updateVisualization: function() {
var div = this.getDOMNode(),
range = this.props.range,
width = div.offsetWidth,
height = div.offsetHeight,
svg = d3.select(div).select('svg');
Expand Down Expand Up @@ -127,7 +128,7 @@ var NonEmptyGeneTrack = React.createClass({
.map(x => [x, g.position.start()]))
.enter()
.append('rect')
.attr('class', 'exon')
.attr('class', 'exon');

// The gene name goes in the center of the gene, modulo boundary effects.
var textCenterX = g => {
Expand Down Expand Up @@ -182,7 +183,7 @@ var NonEmptyGeneTrack = React.createClass({

var EmptyTrack = React.createClass({
render: function() {
return <div className="genes empty">Zoom in to see genes</div>
return <div className="genes empty">Zoom in to see genes</div>;
}
});

Expand Down
3 changes: 2 additions & 1 deletion src/GenomeTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* A track which displays a reference genome.
* @flow
*/
'use strict';

var React = require('react/addons'),
_ = require('underscore'),
Expand Down Expand Up @@ -160,7 +161,7 @@ var NonEmptyGenomeTrack = React.createClass({

var EmptyTrack = React.createClass({
render: function() {
return <div className="reference empty">Zoom in to see bases</div>
return <div className="reference empty">Zoom in to see bases</div>;
}
});

Expand Down
4 changes: 3 additions & 1 deletion src/RemoteFile.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/** @flow */

/**
* RemoteFile is a representation of a file on a remote server which can be
* fetched in chunks, e.g. using a Range request.
* @flow
*/
'use strict';

var Q = require('q');

Expand Down
12 changes: 5 additions & 7 deletions src/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
* Root of the React component tree.
* @flow
*/
'use strict';

var React = require('react'),
ContigInterval = require('./ContigInterval'),
Controls = require('./Controls'),
GenomeTrack = require('./GenomeTrack'),
GeneTrack = require('./GeneTrack'),
// TODO: make this an "import type" when react-tools 0.13.0 is out.
TwoBitDataSource = require('./TwoBitDataSource'),
types = require('./types');
GeneTrack = require('./GeneTrack');


var Root = React.createClass({
Expand All @@ -24,15 +22,15 @@ var Root = React.createClass({
range: (null: ?GenomeRange),
basePairs: (null: any),
genes: ([]: Array<any>) // TODO import Gene type
}
};
},
componentDidMount: function() {
// Note: flow is unable to infer this type through `this.propTypes`.
var source = this.props.referenceSource;
source.needContigs();

source.on('contigs', () => { this.update() })
.on('newdata', () => { this.update() })
.on('newdata', () => { this.update() });

source.on('contigs', () => {
// this is here to facilitate faster iteration
Expand All @@ -44,7 +42,7 @@ var Root = React.createClass({
});

var geneSource = this.props.geneSource;
source.on('newdata', () => { this.update() });
geneSource.on('newdata', () => { this.update() });

this.update();
},
Expand Down
2 changes: 1 addition & 1 deletion src/TwoBit.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class TwoBit {
return this.header.then(header => {
var maybeSeq = _.findWhere(header.sequences, {name: contig}) ||
_.findWhere(header.sequences, {name: 'chr' + contig});
if (maybeSeq == null) {
if (maybeSeq === null || maybeSeq === undefined) {
throw 'Invalid contig: ' + contig;
}
var seq = maybeSeq; // for flow, see facebook/flow#266
Expand Down
8 changes: 4 additions & 4 deletions src/TwoBitDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ var Events = require('backbone').Events,
Q = require('q'),
_ = require('underscore');

// TODO: make this an "import type" when react-tools 0.13.0 is out.
var TwoBit = require('./TwoBit'),
ContigInterval = require('./ContigInterval');
var ContigInterval = require('./ContigInterval');

import type * as TwoBit from './TwoBit';


// Requests for 2bit ranges are expanded to begin & end at multiples of this
Expand All @@ -50,7 +50,7 @@ type TwoBitSource = {
function expandRange(range) {
var roundDown = x => x - x % BASE_PAIRS_PER_FETCH;
var newStart = Math.max(1, roundDown(range.start())),
newStop = roundDown(range.stop() + BASE_PAIRS_PER_FETCH - 1)
newStop = roundDown(range.stop() + BASE_PAIRS_PER_FETCH - 1);

return new ContigInterval(range.contig, newStart, newStop);
}
Expand Down
1 change: 1 addition & 0 deletions src/bedtools.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* @flow */
'use strict';

var _ = require('underscore');
var Interval = require('./Interval');
Expand Down
3 changes: 1 addition & 2 deletions src/formats/bbi.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

'use strict';

var jBinary = require('jbinary'),
{typeAtOffset} = require('./helpers');
var {typeAtOffset} = require('./helpers');

var TYPE_SET = {
'jBinary.littleEndian': true,
Expand Down
4 changes: 3 additions & 1 deletion src/formats/helpers.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/**
* Helpers for specifying file formats using jBinary.
*/
'use strict';

var jBinary = require('jbinary');

// Read a jBinary type at an offset in the buffer specified by another field.
function typeAtOffset(typeName, offsetFieldName) {
return jBinary.Template({
baseType: typeName,
read: function(context) {
if (+context[offsetFieldName] == 0) {
if (+context[offsetFieldName] === 0) {
return null;
} else {
return this.binary.read(this.baseType, +context[offsetFieldName]);
Expand Down
2 changes: 0 additions & 2 deletions src/formats/twoBitTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

'use strict';

var jBinary = require('jbinary');

var TYPE_SET = {
'jBinary.littleEndian': true,

Expand Down
10 changes: 5 additions & 5 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
/* @flow */
'use strict';

var React = require('react'),
TwoBit = require('./TwoBit'),
BigBed = require('./BigBed'),
Root = require('./Root'),
createTwoBitDataSource = require('./TwoBitDataSource'),
createBigBedDataSource = require('./BigBedDataSource');

var startMs = Date.now();
// var genome = new TwoBit('http://www.biodalliance.org/datasets/hg19.2bit');
var genome = new TwoBit('/hg19.2bit');
var dataSource = createTwoBitDataSource(genome);

var ensembl = new BigBed('/ensGene.bb');
var ensemblDataSource = createBigBedDataSource(ensembl);

var root = React.render(<Root referenceSource={dataSource}
geneSource={ensemblDataSource} />,
document.getElementById('root'));
React.render(<Root referenceSource={dataSource}
geneSource={ensemblDataSource} />,
document.getElementById('root'));

window.ensembl = ensembl;
window.genome = genome;
2 changes: 2 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Common types used in many React components.
* @flow
*/
'use strict';

var React = require('react');

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Grab-bag of utility functions.
* @flow
*/

'use strict';

// Compare two tuples of equal length. Is t1 <= t2?
// TODO: make this tupleLessOrEqual<T> -- it works with strings or booleans, too.
Expand Down
5 changes: 5 additions & 0 deletions test/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../.jshintrc",

"expr": true // chai assertions look like expressions to jshint
}
9 changes: 4 additions & 5 deletions test/BigBed-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
var chai = require('chai');
var expect = chai.expect;
var assert = chai.assert;

var Q = require('q');
var BigBed = require('../src/BigBed');
Expand Down Expand Up @@ -31,13 +31,13 @@ describe('BigBed', function() {
expect(features[1].stop).to.equal(151079365);

var rest0 = features[0].rest.split('\t');
expect(rest0).to.have.length(6)
expect(rest0).to.have.length(6);
expect(rest0[0]).to.equal('MID_BLUE');
expect(rest0[2]).to.equal('-');
expect(rest0[5]).to.equal('0,0,128');

var rest1 = features[1].rest.split('\t');
expect(rest1).to.have.length(6)
expect(rest1).to.have.length(6);
expect(rest1[0]).to.equal('VIOLET_RED1');
expect(rest1[2]).to.equal('-');
expect(rest1[5]).to.equal('255,62,150');
Expand All @@ -50,8 +50,7 @@ describe('BigBed', function() {
// The matches looks like this:
// chrX 151071196 151072363 RED
// chrX 151094536 151095703 PeachPuff
var red = [151071196, 151072362], // note: stop is inclusive
peachpuff = [151094536, 151095702];
var red = [151071196, 151072362]; // note: stop is inclusive

var bb = getTestBigBed();
var expectN = n => features => {
Expand Down
Loading