Skip to content

Commit

Permalink
Implementation and basic unit tests for HEDVersion with libraries (#1496
Browse files Browse the repository at this point in the history
)

* Added basic unit tests for HEDVersion with libraries

* Removed commented out code

* Updated the creation of the dataset description object

* Bumped hed-validator version for hed library schema support

* update package-lock.json for hed validator 3.8

Co-authored-by: Stefan Appelhoff <[email protected]>
Co-authored-by: Ross Blair <[email protected]>
  • Loading branch information
3 people authored Aug 31, 2022
1 parent ee7d94c commit 82a3a42
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 43 deletions.
12 changes: 6 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: "monthly"
interval: 'monthly'

- package-ecosystem: "gitsubmodule"
directory: "/"
- package-ecosystem: 'gitsubmodule'
directory: '/'
schedule:
interval: "monthly"
interval: 'monthly'
2 changes: 1 addition & 1 deletion bids-validator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"date-fns": "^2.7.0",
"events": "^3.3.0",
"exifreader": "^4.1.0",
"hed-validator": "^3.7.1",
"hed-validator": "^3.8.0",
"ignore": "^4.0.2",
"is-utf8": "^0.2.1",
"jshint": "^2.9.6",
Expand Down
5 changes: 3 additions & 2 deletions bids-validator/src/files/deno.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const testDir = dirname(testPath)
const testFilename = basename(testPath)
const ignore = new FileIgnoreRulesDeno([])

Deno.test('Deno implementation of BIDSFile', async t => {
Deno.test('Deno implementation of BIDSFile', async (t) => {
await t.step('implements basic file properties', () => {
const file = new BIDSFileDeno(testDir, testFilename, ignore)
assertEquals(join(testDir, file.path), testPath)
Expand Down Expand Up @@ -45,7 +45,8 @@ Deno.test('Deno implementation of BIDSFile', async t => {
const bomFilename = 'bom-utf16.tsv'
const file = new BIDSFileDeno(bomDir, bomFilename, ignore)
await assertRejects(async () => file.text(), UnicodeDecodeError)
})
},
)
await t.step(
'strips BOM characters when reading UTF-8 via .text()',
async () => {
Expand Down
4 changes: 2 additions & 2 deletions bids-validator/src/files/tsv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export function parseTSV(contents: string) {
const rows: string[][] = normalizeEOL(contents)
.split('\n')
.filter(isContentfulRow)
.map(str => str.split('\t'))
.map((str) => str.split('\t'))
const headers = rows.length ? rows[0] : []

headers.map(x => (columns[x] = []))
headers.map((x) => (columns[x] = []))
for (let i = 1; i < rows.length; i++) {
for (let j = 0; j < headers.length; j++) {
columns[headers[j]].push(rows[i][j])
Expand Down
2 changes: 1 addition & 1 deletion bids-validator/src/tests/local/valid_dataset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { validatePath, formatAssertIssue } from './common.ts'

const PATH = 'tests/data/valid_dataset'

Deno.test('valid_dataset dataset', async t => {
Deno.test('valid_dataset dataset', async (t) => {
const { tree, result } = await validatePath(t, PATH)

await t.step('correctly ignores .bidsignore files', () => {
Expand Down
2 changes: 1 addition & 1 deletion bids-validator/src/tests/local/valid_filenames.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { validatePath, formatAssertIssue } from './common.ts'

const PATH = 'tests/data/valid_filenames'

Deno.test('valid_filenames dataset', async t => {
Deno.test('valid_filenames dataset', async (t) => {
const { tree, result } = await validatePath(t, PATH)

await t.step('correctly ignores .bidsignore files', () => {
Expand Down
2 changes: 1 addition & 1 deletion bids-validator/src/tests/local/valid_headers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { validatePath, formatAssertIssue } from './common.ts'

const PATH = 'tests/data/valid_headers'

Deno.test('valid_headers dataset', async t => {
Deno.test('valid_headers dataset', async (t) => {
const { tree, result } = await validatePath(t, PATH)

await t.step('correctly ignores .bidsignore files', () => {
Expand Down
108 changes: 108 additions & 0 deletions bids-validator/tests/events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,77 @@ describe('Events', function () {
})
})

it('should not throw an issue if a value column is annotated', () => {
const events = [
{
file: { path: '/sub01/sub01_task-test_events.tsv' },
path: '/sub01/sub01_task-test_events.tsv',
contents:
'onset\tduration\ttest\tHED\n' + '7\t3.0\tone\tSpeed/30 mph\n',
},
]
const jsonDictionary = {
'/sub01/sub01_task-test_events.json': {
myCodes: {
test: {
HED: {
one: 'Label/#',
},
},
},
},
'/dataset_description.json': { HEDVersion: '8.0.0' },
}

return validate.Events.validateEvents(
events,
[],
headers,
jsonDictionary,
jsonFiles,
'',
).then((issues) => {
assert.deepStrictEqual(issues, [])
})
})

it('should not throw an issue if a library schema is included', () => {
const events = [
{
file: { path: '/sub01/sub01_task-test_events.tsv' },
path: '/sub01/sub01_task-test_events.tsv',
contents:
'onset\tduration\ttest\tHED\n' + '7\t3.0\tone\tSpeed/30 mph\n',
},
]

const jsonDictionary = {
'/sub01/sub01_task-test_events.json': {
myCodes: {
test: {
HED: {
one: 'ts:Sensory-presentation, Label/#',
},
},
},
},
'/dataset_description.json': {
HEDVersion: ['8.0.0', 'ts:testlib_1.0.2'],
},
}

return validate.Events.validateEvents(
events,
[],
headers,
jsonDictionary,
jsonFiles,
'',
).then((issues) => {
assert.deepStrictEqual(issues, [])
})
})

it('should throw an issue if the HED data is invalid', () => {
const events = [
{
Expand Down Expand Up @@ -218,6 +289,43 @@ describe('Events', function () {
})
})

it('should not throw an issue if multiple library schemas are included', () => {
const events = [
{
file: { path: '/sub01/sub01_task-test_events.tsv' },
path: '/sub01/sub01_task-test_events.tsv',
contents:
'onset\tduration\ttest\tHED\n' + '7\t3.0\tone\tSpeed/30 mph\n',
},
]

const jsonDictionary = {
'/sub01/sub01_task-test_events.json': {
myCodes: {
test: {
HED: {
one: 'ts:Sensory-presentation, Label/#, sc:Sleep-deprivation',
},
},
},
},
'/dataset_description.json': {
HEDVersion: ['8.0.0', 'ts:testlib_1.0.2', 'sc:score_0.0.1'],
},
}

return validate.Events.validateEvents(
events,
[],
headers,
jsonDictionary,
jsonFiles,
'',
).then((issues) => {
assert.deepStrictEqual(issues, [])
})
})

it('should properly issue warnings when appropriate', () => {
const events = [
{
Expand Down
36 changes: 17 additions & 19 deletions bids-validator/validators/events/hed.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import hedValidator from 'hed-validator'
import path from 'path'
import semver from 'semver'
import union from 'lodash/union'
import utils from '../../utils'
import parseTsv from '../tsv/tsvParser'
Expand All @@ -14,14 +12,24 @@ export default function checkHedStrings(events, jsonContents, jsonFiles, dir) {
if (!hedDataExists) {
return Promise.resolve([])
}
const dataset = new hedValidator.validator.BidsDataset(eventData, sidecarData)
const [schemaDefinition, schemaDefinitionIssues] = parseHedVersion(
jsonContents,

const datasetDescription = jsonContents['/dataset_description.json']
const datasetDescriptionData = new hedValidator.validator.BidsJsonFile(
'/dataset_description.json',
datasetDescription,
getSidecarFileObject('/dataset_description.json', jsonFiles),
)
const dataset = new hedValidator.validator.BidsDataset(
eventData,
sidecarData,
datasetDescriptionData,
dir,
)
// New stuff end does parseHedVersion need to be called anymore?
const schemaDefinitionIssues = parseHedVersion(jsonContents)
try {
return hedValidator.validator
.validateBidsDataset(dataset, schemaDefinition)
.validateBidsDataset(dataset)
.then((hedValidationIssues) => {
return schemaDefinitionIssues.concat(
convertHedIssuesToBidsIssues(hedValidationIssues),
Expand Down Expand Up @@ -99,24 +107,14 @@ function sidecarValueHasHed(sidecarValue) {
)
}

function parseHedVersion(jsonContents, dir) {
const schemaDefinition = {}
function parseHedVersion(jsonContents) {
const datasetDescription = jsonContents['/dataset_description.json']
const issues = []

if (!(datasetDescription && datasetDescription.HEDVersion)) {
issues.push(new Issue({ code: 109 }))
} else if (semver.valid(datasetDescription.HEDVersion)) {
schemaDefinition.version = datasetDescription.HEDVersion
return [new Issue({ code: 109 })]
} else {
schemaDefinition.path = path.join(
path.resolve(dir),
'sourcedata',
datasetDescription.HEDVersion,
)
return []
}

return [schemaDefinition, issues]
}

function internalHedValidatorIssue(error) {
Expand Down
4 changes: 2 additions & 2 deletions bids-validator/validators/json/schemas/pet.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
"items": { "type": "number" }
},
"CogAtlasID": { "$ref": "common_definitions.json#/definitions/CogAtlasID" },
"CogPOID": { "$ref": "common_definitions.json#/definitions/CogPOID" },
"CogPOID": { "$ref": "common_definitions.json#/definitions/CogPOID" },
"TaskName": {
"type": "string"
},
Expand All @@ -152,7 +152,7 @@
},
"Instructions": {
"$ref": "common_definitions.json#/definitions/Instructions"
}
}
},
"allOf": [
{
Expand Down
54 changes: 46 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 82a3a42

Please sign in to comment.