From 6a6d327b71544118e05664c918b154de459ffb0d Mon Sep 17 00:00:00 2001 From: Kay Robbins <1189050+VisLab@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:23:18 -0500 Subject: [PATCH] Fixed issue with top-level tag used in splice --- src/bids/types/json.js | 30 ++++---- src/bids/validator/tsvValidator.js | 1 + src/parser/parsedHedString.js | 7 ++ src/parser/parser.js | 20 ++++-- src/parser/reservedChecker.js | 24 +++++-- tests/bidsTests.spec.js | 2 +- tests/stringParserTests.spec.js | 3 +- tests/testData/bidsTests.data.js | 84 ++++++++++++++++++++++ tests/testData/stringParserTests.data.js | 91 ++++++++++++++++++++++++ 9 files changed, 232 insertions(+), 30 deletions(-) diff --git a/src/bids/types/json.js b/src/bids/types/json.js index f4a2db78..873c61df 100644 --- a/src/bids/types/json.js +++ b/src/bids/types/json.js @@ -217,7 +217,7 @@ export class BidsSidecar extends BidsJsonFile { this.parsedHedData.set(name, sidecarKey.parsedCategoryMap) } } - this.#generateSidecarColumnSpliceMap() + this._generateSidecarColumnSpliceMap() return [errors, warnings] } @@ -226,33 +226,33 @@ export class BidsSidecar extends BidsJsonFile { * * @private */ - #generateSidecarColumnSpliceMap() { + _generateSidecarColumnSpliceMap() { this.columnSpliceMapping = new Map() this.columnSpliceReferences = new Set() for (const [sidecarKey, hedData] of this.parsedHedData) { if (hedData instanceof ParsedHedString) { - this.#parseValueSplice(sidecarKey, hedData) + this._(sidecarKey, hedData) } else if (hedData instanceof Map) { - this.#parseCategorySplice(sidecarKey, hedData) + this._parseCategorySplice(sidecarKey, hedData) } else if (hedData) { IssueError.generateAndThrowInternalError('Unexpected type found in sidecar parsedHedData map.') } } } - #parseValueSplice(sidecarKey, hedData) { + _(sidecarKey, hedData) { if (hedData.columnSplices.length > 0) { - const keyReferences = this.#processColumnSplices(new Set(), hedData.columnSplices) + const keyReferences = this._processColumnSplices(new Set(), hedData.columnSplices) this.columnSpliceMapping.set(sidecarKey, keyReferences) } } - #parseCategorySplice(sidecarKey, hedData) { + _parseCategorySplice(sidecarKey, hedData) { let keyReferences = null for (const valueString of hedData.values()) { if (valueString?.columnSplices.length > 0) { - keyReferences = this.#processColumnSplices(keyReferences, valueString.columnSplices) + keyReferences = this._processColumnSplices(keyReferences, valueString.columnSplices) } } if (keyReferences instanceof Set) { @@ -267,7 +267,7 @@ export class BidsSidecar extends BidsJsonFile { * @returns {Set} * @private */ - #processColumnSplices(keyReferences, columnSplices) { + _processColumnSplices(keyReferences, columnSplices) { keyReferences ??= new Set() for (const columnSplice of columnSplices) { keyReferences.add(columnSplice.originalTag) @@ -358,9 +358,9 @@ export class BidsSidecarKey { */ parseHed(hedSchemas) { if (this.isValueKey) { - return this.#parseValueString(hedSchemas) + return this._parseValueString(hedSchemas) } - return this.#parseCategory(hedSchemas) + return this._parseCategory(hedSchemas) } /** @@ -373,8 +373,8 @@ export class BidsSidecarKey { * @returns {Array} - [Issue[], Issue[]] - Errors due for the value. * @private */ - #parseValueString(hedSchemas) { - const [parsedString, errorIssues, warningIssues] = parseHedString(this.valueString, hedSchemas, false, true) + _parseValueString(hedSchemas) { + const [parsedString, errorIssues, warningIssues] = parseHedString(this.valueString, hedSchemas, false, true, false) this.parsedValueString = parsedString return [errorIssues, warningIssues] } @@ -385,7 +385,7 @@ export class BidsSidecarKey { * @returns {Array} - Array[Issue[], Issue[]] A list of error issues and warning issues. * @private */ - #parseCategory(hedSchemas) { + _parseCategory(hedSchemas) { this.parsedCategoryMap = new Map() const errors = [] const warnings = [] @@ -399,7 +399,7 @@ export class BidsSidecarKey { file: this.sidecar?.file?.relativePath, }) } - const [parsedString, errorIssues, warningIssues] = parseHedString(string, hedSchemas, true, true) + const [parsedString, errorIssues, warningIssues] = parseHedString(string, hedSchemas, true, true, false) this.parsedCategoryMap.set(value, parsedString) warnings.push(...warningIssues) errors.push(...errorIssues) diff --git a/src/bids/validator/tsvValidator.js b/src/bids/validator/tsvValidator.js index 3bbb5296..96bc4722 100644 --- a/src/bids/validator/tsvValidator.js +++ b/src/bids/validator/tsvValidator.js @@ -353,6 +353,7 @@ export class BidsHedTsvParser { this.hedSchemas, false, false, + true, ) element.parsedHedString = parsedHedString errors.push(...BidsHedIssue.fromHedIssues(errorIssues, this.tsvFile.file, { tsvLine: element.tsvLine })) diff --git a/src/parser/parsedHedString.js b/src/parser/parsedHedString.js index ed23abaa..43300a42 100644 --- a/src/parser/parsedHedString.js +++ b/src/parser/parsedHedString.js @@ -13,36 +13,43 @@ export class ParsedHedString { * @type {string} */ hedString + /** * The parsed substring data in unfiltered form. * @type {ParsedHedSubstring[]} */ parseTree + /** * The tag groups in the string (top-level). * @type {ParsedHedGroup[]} */ tagGroups + /** * All the top-level tags in the string. * @type {ParsedHedTag[]} */ topLevelTags + /** * All the tags in the string at all levels * @type {ParsedHedTag[]} */ tags + /** * All the column splices in the string at all levels. * @type {ParsedHedColumnSplice[]} */ columnSplices + /** * The tags in the top-level tag groups in the string, split into arrays. * @type {ParsedHedTag[][]} */ topLevelGroupTags + /** * The top-level definition tag groups in the string. * @type {ParsedHedGroup[]} diff --git a/src/parser/parser.js b/src/parser/parser.js index ec88cfd5..87f85ef7 100644 --- a/src/parser/parser.js +++ b/src/parser/parser.js @@ -50,11 +50,12 @@ class HedStringParser { /** * Parse a full HED string. * + * @param {boolean} fullValidation - True if full full validation should be performed -- with assemploy * ###Note: now separates errors and warnings for easier handling. * * @returns {Array} - [ParsedHedString|null, Issue[], Issue[]] representing the parsed HED string and any parsing issues. */ - parse() { + parse(fullValidation) { if (this.hedString === null || this.hedString === undefined) { return [null, [generateIssue('invalidTagString', {})], []] } @@ -89,7 +90,7 @@ class HedStringParser { } // Check the other reserved tags requirements - const checkIssues = ReservedChecker.getInstance().checkHedString(parsedString) + const checkIssues = ReservedChecker.getInstance().checkHedString(parsedString, fullValidation) if (checkIssues.length > 0) { return [null, checkIssues, []] } @@ -182,10 +183,11 @@ class HedStringParser { * @param {Schemas} hedSchemas - The collection of HED schemas. * @param {boolean} definitionsAllowed - True if definitions are allowed. * @param {boolean} placeholdersAllowed - True if placeholders are allowed. + * @param {boolean} fullValidation - True if full validation is required. * @returns {Array} - [ParsedHedString, Issue[], Issue[]] representing the parsed HED string and any issues found. */ -export function parseHedString(hedString, hedSchemas, definitionsAllowed, placeholdersAllowed) { - return new HedStringParser(hedString, hedSchemas, definitionsAllowed, placeholdersAllowed).parse() +export function parseHedString(hedString, hedSchemas, definitionsAllowed, placeholdersAllowed, fullValidation) { + return new HedStringParser(hedString, hedSchemas, definitionsAllowed, placeholdersAllowed).parse(fullValidation) } /** @@ -199,6 +201,12 @@ export function parseHedString(hedString, hedSchemas, definitionsAllowed, placeh * @param {boolean} placeholdersAllowed - True if placeholders are allowed * @returns {Array} - [ParsedHedString[], Issue[], Issue[]] representing the parsed HED strings and any issues found. */ -export function parseHedStrings(hedStrings, hedSchemas, definitionsAllowed, placeholdersAllowed) { - return HedStringParser.parseHedStrings(hedStrings, hedSchemas, definitionsAllowed, placeholdersAllowed) +export function parseHedStrings(hedStrings, hedSchemas, definitionsAllowed, placeholdersAllowed, fullValidation) { + return HedStringParser.parseHedStrings( + hedStrings, + hedSchemas, + definitionsAllowed, + placeholdersAllowed, + fullValidation, + ) } diff --git a/src/parser/reservedChecker.js b/src/parser/reservedChecker.js index e51a1d39..1cc4b28e 100644 --- a/src/parser/reservedChecker.js +++ b/src/parser/reservedChecker.js @@ -45,12 +45,13 @@ export class ReservedChecker { * Perform syntactical checks on the provided HED string to detect violations. * * @param {ParsedHedString} hedString - The HED string to be checked. + * @param {boolean} fullValidation - If true, perform full validation; otherwise, perform a quick check. * @returns {Issue[]} - An array of issues if violations are found otherwise, an empty array. */ - checkHedString(hedString) { + checkHedString(hedString, fullValidation) { const checks = [ () => this.checkUnique(hedString), - () => this.checkTagGroupLevels(hedString), + () => this.checkTagGroupLevels(hedString, fullValidation), () => this.checkTopGroupRequirements(hedString), () => this.checkNonTopGroups(hedString), ] @@ -85,9 +86,10 @@ export class ReservedChecker { * Check whether tags are not in groups -- or top-level groups as required * * @param {ParsedHedString} hedString - The HED string to be checked for reserved tag syntax. + * @param {boolean} fullValidation - If true, perform full validation; otherwise, perform a quick check. * @returns {Issue[]} An array of `Issue` objects if there are violations; otherwise, an empty array. */ - checkTagGroupLevels(hedString) { + checkTagGroupLevels(hedString, fullValidation) { const issues = [] const topGroupTags = hedString.topLevelGroupTags.flat() @@ -98,14 +100,22 @@ export class ReservedChecker { return } - // If this is a top tag group tag, we know it isn't in a top tag group. - if (ReservedChecker.hasTopLevelTagGroupAttribute(tag)) { - issues.push(generateIssue('invalidTopLevelTagGroupTag', { tag: tag.originalTag, string: hedString.hedString })) + // This is a top-level tag group tag that is in a lower level or ungrouped top level + if ( + ReservedChecker.hasTopLevelTagGroupAttribute(tag) && + (!hedString.topLevelTags.includes(tag) || fullValidation) + ) { + issues.push( + generateIssue('invalidTopLevelTagGroupTag', { + tag: tag.originalTag, + string: hedString.hedString, + }), + ) return } // In final form --- if not in a group (not just a top group) but has the group tag attribute - if (hedString.topLevelTags.includes(tag) && ReservedChecker.hasGroupAttribute(tag)) { + if (hedString.topLevelTags.includes(tag) && ReservedChecker.hasGroupAttribute(tag) && fullValidation) { issues.push(generateIssue('missingTagGroup', { tag: tag.originalTag, string: hedString.hedString })) } }) diff --git a/tests/bidsTests.spec.js b/tests/bidsTests.spec.js index 5efd1b7e..fae1fd77 100644 --- a/tests/bidsTests.spec.js +++ b/tests/bidsTests.spec.js @@ -14,7 +14,7 @@ import { DefinitionManager } from '../src/parser/definitionManager' //const skipMap = new Map([['definition-tests', ['invalid-missing-definition-for-def', 'invalid-nested-definition']]]) const skipMap = new Map() const runAll = true -const runMap = new Map([['curly-brace-tests', ['valid-curly-brace-in-sidecar-with-value-splice']]]) +const runMap = new Map([['curly-brace-tests', ['splice-of-top-level-tag']]]) describe('BIDS validation', () => { const schemaMap = new Map([['8.3.0', undefined]]) diff --git a/tests/stringParserTests.spec.js b/tests/stringParserTests.spec.js index b680fbe5..9fa3d9f6 100644 --- a/tests/stringParserTests.spec.js +++ b/tests/stringParserTests.spec.js @@ -13,7 +13,7 @@ import { shouldRun, getHedString } from './testUtilities' const skipMap = new Map() const runAll = true //const runMap = new Map([['valid-tags', ['single-tag-extension']]]) -const runMap = new Map([['valid-tags', ['deprecated-tag']]]) +const runMap = new Map([['special-tag-group-tests', ['event-context-in-subgroup']]]) describe('Null schema objects should cause parsing to bail', () => { it('Should not proceed if no schema and valid string', () => { @@ -82,6 +82,7 @@ describe('Parse HED string tests', () => { thisSchema, test.definitionsAllowed, test.placeholdersAllowed, + test.fullValidation, ) } catch (error) { issues = [error.issue] diff --git a/tests/testData/bidsTests.data.js b/tests/testData/bidsTests.data.js index d1a78ff8..3355e785 100644 --- a/tests/testData/bidsTests.data.js +++ b/tests/testData/bidsTests.data.js @@ -596,6 +596,90 @@ export const bidsTestData = [ tsvErrors: [], comboErrors: [], }, + { + testname: 'splice-of-top-level-tag', + explanation: 'A top-level tag group tag is part of a splice', + schemaVersion: '8.3.0', + definitions: ['(Definition/Acc/#, (Acceleration/# m-per-s^2, Red))', '(Definition/MyColor, (Label/Pie))'], + sidecar: { + duration: { + HED: 'Duration/#', + }, + event_code: { + HED: { + face: '({duration}, ((Red, Blue), {ball_type}))', + ball: '{ball_type}, Black', + }, + }, + ball_type: { + Description: 'Has description with HED', + HED: 'Label/#', + }, + }, + eventsString: 'onset\tduration\tevent_code\tball_type\n' + '19\t6\tball\tbig-one\n25\t5\tface\tother-one\n', + sidecarErrors: [], + tsvErrors: [], + comboErrors: [], + }, + { + testname: 'bad-splice-of-top-level-tag', + explanation: 'A top-level tag group tag is part of a splice but is invalid', + schemaVersion: '8.3.0', + definitions: ['(Definition/Acc/#, (Acceleration/# m-per-s^2, Red))', '(Definition/MyColor, (Label/Pie))'], + sidecar: { + duration: { + HED: '(Duration/#, (Red, Blue))', + }, + event_code: { + HED: { + face: '({duration}, ((Red, Blue), {ball_type}))', + ball: '{ball_type}, Black', + }, + }, + ball_type: { + Description: 'Has description with HED', + HED: 'Label/#', + }, + }, + eventsString: 'onset\tduration\tevent_code\tball_type\n' + '19\t6\tball\tbig-one\n25\t5\tface\tother-one\n', + sidecarErrors: [], + tsvErrors: [], + comboErrors: [ + BidsHedIssue.fromHedIssue( + generateIssue('invalidTopLevelTagGroupTag', { + tag: 'Duration/5', + string: '((Duration/5, (Red, Blue)), ((Red, Blue), Label/other-one))', + }), + { path: 'bad-splice-of-top-level-tag.tsv', relativePath: 'bad-splice-of-top-level-tag.tsv' }, + { tsvLine: 3 }, + ), + ], + }, + { + testname: 'splice-of-non-top-level-tag', + explanation: 'A top-level tag group tag is part of a splice', + schemaVersion: '8.3.0', + definitions: ['(Definition/Acc/#, (Acceleration/# m-per-s^2, Red))', '(Definition/MyColor, (Label/Pie))'], + sidecar: { + duration: { + HED: 'Parameter-value/#', + }, + event_code: { + HED: { + face: '({duration}, ((Red, Blue), {ball_type}))', + ball: '{ball_type}, Black', + }, + }, + ball_type: { + Description: 'Has description with HED', + HED: 'Label/#', + }, + }, + eventsString: 'onset\tduration\tevent_code\tball_type\n' + '19\t6\tball\tbig-one\n25\t5\tface\tother-one\n', + sidecarErrors: [], + tsvErrors: [], + comboErrors: [], + }, { testname: 'valid-curly-brace-in-sidecar-with-tsv-n/a', explanation: 'Valid curly brace in sidecar and valid tsv with n/a', diff --git a/tests/testData/stringParserTests.data.js b/tests/testData/stringParserTests.data.js index aacca3c9..44ec3dc7 100644 --- a/tests/testData/stringParserTests.data.js +++ b/tests/testData/stringParserTests.data.js @@ -14,6 +14,7 @@ export const parseTestData = [ stringShort: 'Event', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -26,6 +27,7 @@ export const parseTestData = [ stringShort: 'Sensory-event', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -38,6 +40,7 @@ export const parseTestData = [ stringShort: 'Geometric-object', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -50,6 +53,7 @@ export const parseTestData = [ stringShort: 'Geometric-object', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -62,6 +66,7 @@ export const parseTestData = [ stringShort: 'Geometric-object', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -74,6 +79,7 @@ export const parseTestData = [ stringShort: 'Environmental-sound/Unique-value', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('extendedTag', { @@ -91,6 +97,7 @@ export const parseTestData = [ stringShort: 'Item/Junk1, Item/Junk2', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('extendedTag', { string: 'Item/Junk1, Item/Junk2', tags: '[Item/Junk1, Item/Junk2]' }), @@ -105,6 +112,7 @@ export const parseTestData = [ stringShort: 'Environmental-sound/Unique-value/Junk', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('extendedTag', { @@ -122,6 +130,7 @@ export const parseTestData = [ stringShort: 'Environmental-sound/Unique-value/Junk', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('extendedTag', { @@ -140,6 +149,7 @@ export const parseTestData = [ stringShort: 'Agent-action, Gentalia', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [generateIssue('deprecatedTag', { string: 'Agent-action, Gentalia', tags: '[Gentalia]' })], }, @@ -153,6 +163,7 @@ export const parseTestData = [ stringShort: 'Agent-action, Gentalia, (Item, Gentalia)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('deprecatedTag', { @@ -176,6 +187,7 @@ export const parseTestData = [ stringShort: 'Age/15', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -188,6 +200,7 @@ export const parseTestData = [ stringShort: 'Age', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -200,6 +213,7 @@ export const parseTestData = [ stringShort: 'Label', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -212,6 +226,7 @@ export const parseTestData = [ stringShort: 'Creation-date/2009-04-09T12:04:14', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -231,6 +246,7 @@ export const parseTestData = [ stringShort: '(Train/Maglev, Age/15, RGB-red/0.5), Operate', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [ generateIssue('extendedTag', { string: '(Train/Maglev,Age/15,RGB-red/0.5),Operate', tags: '[Train/Maglev]' }), @@ -246,6 +262,7 @@ export const parseTestData = [ stringShort: '(Time-value/20 ms), Operate', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -264,6 +281,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidParentNode', { tag: 'Event', parentTag: 'Item/Sound' })], warnings: [], }, @@ -276,6 +294,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidParentNode', { parentTag: 'Item/Sound/Environmental-sound', tag: 'Event' })], warnings: [], }, @@ -288,6 +307,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidParentNode', { parentTag: 'Item/Sound', tag: 'Event' })], warnings: [], }, @@ -300,6 +320,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidTag', { tag: 'Junk/Item/Sound/Event/Sensory-event/Environmental-sound' })], warnings: [], }, @@ -312,6 +333,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidTag', { tag: 'Junk' })], warnings: [], }, @@ -324,6 +346,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidTag', { tag: 'Junk/Blech' })], warnings: [], }, @@ -337,6 +360,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidParentNode', { parentTag: 'Item/Object/Junk', tag: 'Geometric-object' })], warnings: [], }, @@ -349,6 +373,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidExtension', { parentTag: 'Event/Agent-action', tag: 'Baloney' })], warnings: [], }, @@ -368,6 +393,7 @@ export const parseTestData = [ stringShort: 'Label/#, Red', placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -381,6 +407,7 @@ export const parseTestData = [ stringShort: 'Time-value/# ms, Red', placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -393,6 +420,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidExtension', { tag: '#', parentTag: 'Object' })], warnings: [], }, @@ -405,6 +433,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidExtension', { parentTag: 'Object/Thingie', tag: '#' })], warnings: [], }, @@ -417,6 +446,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidPlaceholder', { index: '13', string: 'Label/#/Blech, Red', tag: 'Label/#/Blech' }), ], @@ -431,6 +461,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidPlaceholder', { index: '8', string: 'Label/##, Red', tag: 'Label/##' })], warnings: [], }, @@ -449,6 +480,7 @@ export const parseTestData = [ stringShort: 'Age/5', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -461,6 +493,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('childRequired', { tag: 'Duration' })], warnings: [], }, @@ -474,6 +507,7 @@ export const parseTestData = [ stringShort: '(Time-value/20 ms), Operate', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -492,6 +526,7 @@ export const parseTestData = [ stringShort: 'Age, Operate', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -504,6 +539,7 @@ export const parseTestData = [ stringShort: '', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -517,6 +553,7 @@ export const parseTestData = [ stringShort: 'Red, (Blue, Green)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -530,6 +567,7 @@ export const parseTestData = [ stringShort: 'Red, (Blue, (Green))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -542,6 +580,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidTagString', {})], warnings: [], }, @@ -554,6 +593,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidTagString', {})], warnings: [], }, @@ -568,6 +608,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('duplicateTag', { tags: '[((((Black,Purple),Blue,Orange)),Green,White)]', @@ -592,6 +633,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidTopLevelTagGroupTag', { tag: 'Definition/Green1', @@ -609,6 +651,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('missingTagGroup', { tag: 'Definition/Green1', @@ -626,6 +669,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionGroupStructure', { tagGroup: '(Definition/IllegalSibling, Train, (Circle))', @@ -644,6 +688,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionForbidden', { tagGroup: '(Definition/DefNested, (Def/Nested, (Red, Blue, (Def/Blech)), Triangle))', @@ -662,6 +707,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionForbidden', { tagGroup: '(Definition/NestedDefinition, (Touchscreen, (Definition/InnerDefinition, (Square))))', @@ -697,6 +743,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionGroupStructure', { tagGroup: '(Definition/Apple, Definition/Banana, (Blue))', @@ -714,6 +761,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidTopLevelTagGroupTag', { tag: 'Event-context', @@ -731,6 +779,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('missingTagGroup', { tag: 'Def-expand/Green1', string: 'Def-expand/Green1, (Red, Blue)' }), ], @@ -745,6 +794,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionGroupStructure', { tagGroup: '(Def-expand/Acc/5.4, (Acceleration/5.4 m-per-s^2, Red), Blue)', @@ -763,6 +813,7 @@ export const parseTestData = [ stringShort: '(Agent-action, (Def-expand/Blech, (Item, Sensory-event)))', placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [], warnings: [], }, @@ -777,6 +828,7 @@ export const parseTestData = [ stringShort: 'Item, (Event, Object, (Item, (Def-expand/Blech, (Agent-action, Item))))', placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [], warnings: [], }, @@ -790,6 +842,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidDefinitionForbidden', { tag: 'Def-expand/Blech', @@ -808,6 +861,7 @@ export const parseTestData = [ stringShort: '(Def-expand/Acc/4.5, (Acceleration/4.5, Red))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -820,6 +874,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('missingTagGroup', { string: 'Def-expand/Acc/4.5, (Acceleration/4.5 m-per-s^2, Red)', @@ -837,6 +892,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('missingTagGroup', { string: 'Def-expand/Acc/4.5, (Acceleration/4.5 m-per-s^2, Red)', @@ -860,6 +916,7 @@ export const parseTestData = [ stringShort: '(Event-context, (Item))', placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [], warnings: [], }, @@ -872,6 +929,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('invalidTopLevelTagGroupTag', { tag: 'Event-context', @@ -889,6 +947,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('multipleUniqueTags', { tag: 'Event-context', @@ -906,6 +965,7 @@ export const parseTestData = [ stringShort: '(Duration/10, (Event))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -918,6 +978,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('invalidNumberOfSubgroups', { string: '(Duration/10)', tag: 'Duration/10' })], warnings: [], }, @@ -931,6 +992,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidNumberOfSubgroups', { string: '(Duration/10, ({event_code}))', tag: 'Duration/10' }), ], @@ -946,6 +1008,7 @@ export const parseTestData = [ stringShort: '(Delay/5, Duration/10, (Event))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -960,6 +1023,7 @@ export const parseTestData = [ stringShort: '(Delay/5, Duration/10, (Event, {event_code}))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -972,6 +1036,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('tooManyGroupTopTags', { string: '(Delay/5, (Def-expand/MyColor, (Label/Pie)))' })], warnings: [], }, @@ -985,6 +1050,7 @@ export const parseTestData = [ stringShort: '(Delay/5, Duration/10, (Event))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -998,6 +1064,7 @@ export const parseTestData = [ stringShort: 'Label/1, (Def/Acc/3.5), (Item-count/2, Label/1)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1011,6 +1078,7 @@ export const parseTestData = [ stringShort: '(Def/MyColor, Onset)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1024,6 +1092,7 @@ export const parseTestData = [ stringShort: '((Def-expand/MyColor, (Label/Pie)), Onset)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1037,6 +1106,7 @@ export const parseTestData = [ stringShort: '(Onset, (Def-expand/MyColor, (Label/Pie)), (Red))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1049,6 +1119,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('temporalWithWrongNumberDefs', { tagGroup: '(Onset, Delay/5 s)', tag: 'Onset' })], warnings: [], }, @@ -1061,6 +1132,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidGroupTopTags', { string: '(Def/MyColor, Onset, Offset)', @@ -1079,6 +1151,7 @@ export const parseTestData = [ stringShort: '(Delay/5.0 s, Onset, Def/MyColor)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1093,6 +1166,7 @@ export const parseTestData = [ stringShort: '(Delay/5.0 s, Onset, (Def-expand/MyColor, (Label/Pie)))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1107,6 +1181,7 @@ export const parseTestData = [ stringShort: '(Delay/5.0 s, Onset, (Def-expand/MyColor, (Label/Pie)), (Item))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1120,6 +1195,7 @@ export const parseTestData = [ stringShort: '(Def/MyColor, Inset)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1133,6 +1209,7 @@ export const parseTestData = [ stringShort: '(Inset, Delay/5 s, Def/myDef)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1145,6 +1222,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('temporalWithWrongNumberDefs', { tagGroup: '(Inset, Delay/5 s)', tag: 'Inset' })], warnings: [], }, @@ -1158,6 +1236,7 @@ export const parseTestData = [ stringShort: '(Inset, Delay/5 s, Def/myDef)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1170,6 +1249,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidGroupTopTags', { string: '((Def-expand/MyColor, (Label/Pie)), Inset, Blue)', @@ -1188,6 +1268,7 @@ export const parseTestData = [ stringShort: '(Inset, Def/myDef, (Def/Blech, Item))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1201,6 +1282,7 @@ export const parseTestData = [ stringShort: '(Inset, (Def-expand/myDef), (Def/Blech, Item))', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1214,6 +1296,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidDefinitionForbidden', { tagGroup: '(Def-expand/myDef, (Item,(Def/Temp)))', @@ -1231,6 +1314,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('temporalWithWrongNumberDefs', { tagGroup: '(Offset, Delay/5 s)', tag: 'Offset' })], warnings: [], }, @@ -1243,6 +1327,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [ generateIssue('invalidNumberOfSubgroups', { string: '((Def-expand/MyColor, (Label/Pie)), Offset, (Red))', @@ -1261,6 +1346,7 @@ export const parseTestData = [ stringShort: '(Offset, Delay/5 s, Def/myDef)', placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [], warnings: [], }, @@ -1273,6 +1359,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: false, definitionsAllowed: false, + fullValidation: false, errors: [generateIssue('temporalWithWrongNumberDefs', { tagGroup: '(Offset, Item)', tag: 'Offset' })], warnings: [], }, @@ -1292,6 +1379,7 @@ export const parseTestData = [ stringShort: 'Red, (({event_code}, Blue), Green)', placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [], warnings: [], }, @@ -1304,6 +1392,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [generateIssue('curlyBracesInDefinition', { column: 'event_code', definition: 'Definition/Blech' })], warnings: [], }, @@ -1317,6 +1406,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [ generateIssue('curlyBracesInDefinition', { column: 'event_code', @@ -1335,6 +1425,7 @@ export const parseTestData = [ stringShort: null, placeholdersAllowed: true, definitionsAllowed: true, + fullValidation: false, errors: [generateIssue('curlyBracesInDefinition', { column: 'event_code', definition: 'Def-expand/Blech' })], warnings: [], },