Skip to content

Commit 8d8c93e

Browse files
authored
Merge pull request #307 from nellh/quicktest-error-code
Introduce quick test error code to replace 'Invalid' string
2 parents ff3f470 + 22359eb commit 8d8c93e

File tree

6 files changed

+110
-5
lines changed

6 files changed

+110
-5
lines changed

cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module.exports = function (dir, options) {
1212
validate.BIDS(dir, options, function (issues, summary) {
1313
var errors = issues.errors;
1414
var warnings = issues.warnings;
15-
if (issues === 'Invalid') {
15+
if (issues.errors.length === 1 && issues.errors[0].code === '61') {
1616
console.log(colors.red("The directory " + dir + " failed an initial Quick Test. This means the basic names and structure of the files and directories do not comply with BIDS specification. For more info go to http://bids.neuroimaging.io/"));
1717
} else if (issues.config && issues.config.length >= 1) {
1818
console.log(colors.red('Invalid Config File'));

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bids-validator",
3-
"version": "0.22.4",
3+
"version": "0.23.0",
44
"description": "",
55
"main": "index.js",
66
"repository": {
@@ -22,6 +22,7 @@
2222
},
2323
"homepage": "https://github.com/INCF/bids-validator",
2424
"dependencies": {
25+
"ajv": "^4.9.0",
2526
"async": "^2.1.5",
2627
"bytes": "^2.3.0",
2728
"cliff": "^0.1.10",
@@ -30,9 +31,9 @@
3031
"minimatch": "3.0.3",
3132
"nifti-js": "^1.0.0",
3233
"pako": "^1.0.4",
34+
"path": "^0.12.7",
3335
"pluralize": "^3.1.0",
34-
"yargs": "^6.6.0",
35-
"ajv": "^4.9.0"
36+
"yargs": "^6.6.0"
3637
},
3738
"devDependencies": {
3839
"adm-zip": "",

tests/utils/files.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const assert = require('assert');
2+
const after = require('mocha').after;
3+
const utils = require('../../utils');
4+
5+
const setupMocks = () => {
6+
// Mock version of the File API for tests
7+
global.File = function MockFile(data, fileName, options) {
8+
assert(data.hasOwnProperty('length'));
9+
assert.equal(typeof data[0], 'string');
10+
this._data = data;
11+
this._options = options;
12+
this.name = fileName;
13+
};
14+
};
15+
const cleanupMocks = () => {
16+
delete global.File;
17+
};
18+
19+
describe('files utils in nodejs', () => {
20+
describe('FileAPI', () => {
21+
it('should return a mock implementation', () => {
22+
let File = utils.files.FileAPI();
23+
assert(typeof File !== 'undefined');
24+
assert(File.name === 'NodeFile');
25+
});
26+
});
27+
describe('newFile', () => {
28+
it('creates a new File API object', () => {
29+
let file = utils.files.newFile('test-file');
30+
assert.equal(file.name, 'test-file');
31+
});
32+
});
33+
});
34+
35+
describe('files utils in browsers', () => {
36+
before(setupMocks);
37+
after(cleanupMocks);
38+
describe('newFile', () => {
39+
it('creates a new File API object', () => {
40+
const test_file = utils.files.newFile('test-file');
41+
assert(File.prototype.isPrototypeOf(test_file));
42+
});
43+
});
44+
});

utils/files.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ if (typeof window === 'undefined') {
1717
// public API ---------------------------------------------------------------------
1818

1919
var fileUtils = {
20+
FileAPI: FileAPI,
21+
newFile: newFile,
2022
readFile: readFile,
2123
readDir: readDir,
2224
readNiftiHeader: readNiftiHeader,
@@ -273,4 +275,43 @@ function testFile (file, callback) {
273275
});
274276
}
275277

278+
/**
279+
* Simulates some of the browser File API interface.
280+
* https://developer.mozilla.org/en-US/docs/Web/API/File
281+
*
282+
* @param {string[]} parts - file contents as bytes
283+
* @param {string} filename - filename without path info
284+
* @param {Object} properties - unused Blob properties
285+
*/
286+
function NodeFile(parts, filename, properties) {
287+
this.parts = parts;
288+
this.name = filename;
289+
this.properties = properties;
290+
this.size = parts.reduce(function (a, val) {
291+
return a + val.length;
292+
}, 0);
293+
// Unknown defacto mime-type
294+
this.type = 'application/octet-stream';
295+
this.lastModified = 0;
296+
}
297+
298+
/**
299+
* Return a either a mock or real FileAPI if one is available
300+
*/
301+
function FileAPI() {
302+
return typeof File === 'undefined' ? NodeFile: File;
303+
}
304+
305+
/**
306+
* New File
307+
*
308+
* Creates an empty File object
309+
*
310+
* @param {string} filename - the filename without path info
311+
*/
312+
function newFile(filename) {
313+
var File = FileAPI();
314+
return new File([''], filename);
315+
}
316+
276317
module.exports = fileUtils;

utils/issues/list.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,9 @@ module.exports = {
302302
severity: 'error',
303303
reason: 'sform_code and qform_code in the image header are 0. The image/file will be considered invalid or assumed to be in LAS orientation.'
304304
},
305+
61: {
306+
key: 'QUICK_VALIDATION_FAILED',
307+
severity: 'error',
308+
reason: 'Quick validation failed - the general folder structure does not resamble a BIDS dataset. Have you chosen the right folder (with "sub-*/" subfolders)? Check for structural/naming issues and presence of at least one subject.',
309+
}
305310
};

validators/bids.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var async = require('async');
22
var fs = require('fs');
3+
var path = require('path');
34
var utils = require('../utils');
45
var Issue = utils.issues.Issue;
56

@@ -41,7 +42,20 @@ BIDS = {
4142
if (couldBeBIDS) {
4243
self.fullTest(files, callback);
4344
} else {
44-
callback('Invalid');
45+
// Return an error immediately if quickTest fails
46+
var issue = new Issue({
47+
code: 61,
48+
file: utils.files.newFile(path.basename(dir))
49+
});
50+
var summary = {
51+
sessions: [],
52+
subjects: [],
53+
tasks: [],
54+
modalities: [],
55+
totalFiles: Object.keys(files).length,
56+
size: 0
57+
};
58+
callback(utils.issues.format([issue], summary, options));
4559
}
4660
});
4761
});

0 commit comments

Comments
 (0)