hed-standard/hed-javascript

View on GitHub
bids/validate.js

Summary

Maintainability
A
40 mins
Test Coverage
A
96%
import { buildBidsSchemas } from './schema'
import { BidsHedIssue, BidsIssue } from './types/issues'
import { BidsHedTsvValidator } from './validator/bidsHedTsvValidator'
import { BidsHedSidecarValidator } from './validator/bidsHedSidecarValidator'
import { BidsHedColumnValidator } from './validator/bidsHedColumnValidator'

/**
 * Validate a BIDS dataset.
 *
 * @param {BidsDataset} dataset The BIDS dataset.
 * @param {SchemasSpec} schemaDefinition The version spec for the schema to be loaded.
 * @returns {Promise<BidsIssue[]>} Any issues found.
 */
export async function validateBidsDataset(dataset, schemaDefinition) {
  try {
    const hedSchemas = await buildBidsSchemas(dataset, schemaDefinition)
    const validator = new BidsHedValidator(dataset, hedSchemas)
    try {
      return validator.validateFullDataset()
    } catch (internalError) {
      return BidsIssue.generateInternalErrorPromise(internalError, dataset.datasetDescription.file)
    }
  } catch (schemaIssues) {
    return BidsHedIssue.fromHedIssues(schemaIssues, dataset.datasetDescription.file)
  }
}

/**
 * A validator for HED content in a BIDS dataset.
 */
class BidsHedValidator {
  /**
   * The BIDS dataset being validated.
   * @type {BidsDataset}
   */
  dataset
  /**
   * The HED schema collection being validated against.
   * @type {Schemas}
   */
  hedSchemas
  /**
   * The issues found during validation.
   * @type {BidsHedIssue[]}
   */
  issues

  /**
   * Constructor.
   *
   * @param {BidsDataset} dataset The BIDS dataset being validated.
   * @param {Schemas} hedSchemas The HED schema collection being validated against.
   */
  constructor(dataset, hedSchemas) {
    this.dataset = dataset
    this.hedSchemas = hedSchemas
    this.issues = []
  }

  /**
   * Validate a full BIDS dataset using a HED schema collection.
   *
   * @returns {Promise<BidsIssue[]>} Any issues found.
   */
  async validateFullDataset() {
    const sidecarValidator = new BidsHedSidecarValidator(this.dataset, this.hedSchemas)
    const hedColumnValidator = new BidsHedColumnValidator(this.dataset, this.hedSchemas)
    const sidecarErrorsFound = this._pushIssues(sidecarValidator.validateSidecars())
    const hedColumnErrorsFound = this._pushIssues(hedColumnValidator.validate())
    if (sidecarErrorsFound || hedColumnErrorsFound) {
      return this.issues
    }
    for (const eventFileData of this.dataset.eventData) {
      const tsvValidator = new BidsHedTsvValidator(eventFileData, this.hedSchemas)
      this.issues.push(...tsvValidator.validate())
    }
    return this.issues
  }

  /**
   * Push a list of issues to the validator's issue list.
   *
   * @param {BidsHedIssue[]} issues A list of issues generated by a file type-specific validator.
   * @returns {boolean} Whether any of the issues generated/added were errors as opposed to warnings.
   * @private
   */
  _pushIssues(issues) {
    this.issues.push(...issues)
    return BidsIssue.anyAreErrors(issues)
  }
}