From 1f3b1aee7fb27624904f1aa2080b6e40b56a8b7a Mon Sep 17 00:00:00 2001 From: Kay Robbins <1189050+VisLab@users.noreply.github.com> Date: Sat, 25 Jan 2025 06:49:49 -0600 Subject: [PATCH] Fixed the date-time value issue confused with namespace --- .../{class_regex.json => classRegex.json} | 0 src/parser/tagConverter.js | 1 - src/parser/tokenizer.js | 7 +++--- src/schema/parser.js | 2 +- tests/stringParserTests.spec.js | 2 +- tests/tagParserTests.spec.js | 4 ++-- tests/testData/splitterTests.data.js | 10 ++++++++ tests/testData/stringParserTests.data.js | 12 ++++++++++ tests/testData/tagParserTests.data.js | 23 ++++++++++++++++++- tests/testData/tokenizerTests.data.js | 8 +++++++ tests/tokenizerTests.spec.js | 2 +- 11 files changed, 61 insertions(+), 10 deletions(-) rename src/data/json/{class_regex.json => classRegex.json} (100%) diff --git a/src/data/json/class_regex.json b/src/data/json/classRegex.json similarity index 100% rename from src/data/json/class_regex.json rename to src/data/json/classRegex.json diff --git a/src/parser/tagConverter.js b/src/parser/tagConverter.js index 59f12fa6..3ca9260d 100644 --- a/src/parser/tagConverter.js +++ b/src/parser/tagConverter.js @@ -63,7 +63,6 @@ export default class TagConverter { constructor(tagSpec, hedSchemas) { this.hedSchemas = hedSchemas this.tagMapping = hedSchemas.getSchema(tagSpec.library).entries.tags - this.tagSpec = tagSpec this.tagString = tagSpec.tag this.tagLevels = this.tagString.split('/') diff --git a/src/parser/tokenizer.js b/src/parser/tokenizer.js index 0b501a9c..1ddfedae 100644 --- a/src/parser/tokenizer.js +++ b/src/parser/tokenizer.js @@ -320,9 +320,10 @@ export class HedStringTokenizer { } handleColon(i) { - if (this.state.librarySchema || this.state.currentToken.trim().includes(CHARACTERS.BLANK)) { - this.state.currentToken += CHARACTERS.COLON // If colon has not been seen, it is a library. Ignore other colons. - } else if (/[^A-Za-z]/.test(this.state.currentToken.trim())) { + const trimmed = this.state.currentToken.trim() + if (this.state.librarySchema || trimmed.includes(CHARACTERS.BLANK) || trimmed.includes(CHARACTERS.SLASH)) { + this.state.currentToken += CHARACTERS.COLON // If colon has been seen or is part of a value. + } else if (/[^A-Za-z]/.test(trimmed)) { this.pushIssue('invalidTagPrefix', i) // Prefix not alphabetic Ex: "1a:xxx" } else { const lib = this.state.currentToken.trimStart() diff --git a/src/schema/parser.js b/src/schema/parser.js index aea399e8..f741ae93 100644 --- a/src/schema/parser.js +++ b/src/schema/parser.js @@ -24,7 +24,7 @@ import { } from './entries' import { IssueError } from '../issues/issues' -import classRegex from '../data/json/class_regex.json' +import classRegex from '../data/json/classRegex.json' const lc = (str) => str.toLowerCase() diff --git a/tests/stringParserTests.spec.js b/tests/stringParserTests.spec.js index a5ddefcc..b2625b89 100644 --- a/tests/stringParserTests.spec.js +++ b/tests/stringParserTests.spec.js @@ -12,7 +12,7 @@ import { shouldRun, getHedString } from './testUtilities' const skipMap = new Map() const runAll = true -const runMap = new Map([['special-tag-group-tests', ['duration-with-group']]]) +const runMap = new Map([['valid-value-tags', ['date-time-value-tag']]]) describe('Null schema objects should cause parsing to bail', () => { it('Should not proceed if no schema and valid string', () => { diff --git a/tests/tagParserTests.spec.js b/tests/tagParserTests.spec.js index 09dee799..0ebd6baa 100644 --- a/tests/tagParserTests.spec.js +++ b/tests/tagParserTests.spec.js @@ -13,7 +13,7 @@ import { SchemaValueTag } from '../src/schema/entries' // Ability to select individual tests to run const skipMap = new Map() const runAll = true -const runMap = new Map([['special-tag-group-tests', ['def-expand-tag-not-in-group']]]) +const runMap = new Map([['name-space-tests', ['valid-date-time']]]) describe('TagSpec converter tests using JSON tests', () => { const schemaMap = new Map([['8.3.0', undefined]]) @@ -53,7 +53,7 @@ describe('TagSpec converter tests using JSON tests', () => { if (test.takesValue) { assert.instanceOf(tag._schemaTag, SchemaValueTag, `${header}: tag should be a takes value tag`) } else { - assert.notInstanceOf(tag._schemaTag, SchemaValueTag, `${header}: tag should be a takes value tag`) + assert.notInstanceOf(tag._schemaTag, SchemaValueTag, `${header}: tag should not be a takes value tag`) } } diff --git a/tests/testData/splitterTests.data.js b/tests/testData/splitterTests.data.js index 4a9b7c60..7d83d103 100644 --- a/tests/testData/splitterTests.data.js +++ b/tests/testData/splitterTests.data.js @@ -43,6 +43,16 @@ export const splitterTestData = [ errors: [], warnings: [], }, + { + testname: 'date-time-value-string', + explanation: '"Creation-date/2009-04-09T12:04:14" is a an empty string', + schemaVersion: '8.3.0', + stringIn: 'Creation-date/2009-04-09T12:04:14', + allGroupTagCount: [0], + allSubgroupCount: 0, + errors: [], + warnings: [], + }, ], }, ] diff --git a/tests/testData/stringParserTests.data.js b/tests/testData/stringParserTests.data.js index f80b6fb6..e37a9f1a 100644 --- a/tests/testData/stringParserTests.data.js +++ b/tests/testData/stringParserTests.data.js @@ -144,6 +144,18 @@ export const parseTestData = [ errors: [], warnings: [], }, + { + testname: 'date-time-value-tag', + explanation: '"Label" does not have to take a value"', + schemaVersion: '8.3.0', + stringIn: 'Creation-date/2009-04-09T12:04:14', + stringLong: 'Property/Informational-property/Metadata/Creation-date/2009-04-09T12:04:14', + stringShort: 'Creation-date/2009-04-09T12:04:14', + placeholdersAllowed: false, + definitionsAllowed: false, + errors: [], + warnings: [], + }, ], }, { diff --git a/tests/testData/tagParserTests.data.js b/tests/testData/tagParserTests.data.js index 92007e7a..241686e8 100644 --- a/tests/testData/tagParserTests.data.js +++ b/tests/testData/tagParserTests.data.js @@ -1,5 +1,5 @@ import { generateIssue } from '../../src/issues/issues' -import { ColumnSpliceSpec, GroupSpec, TagSpec } from '../../src/parser/tokenizer' +import { TagSpec } from '../../src/parser/tokenizer' export const parsedHedTagTests = [ { @@ -504,4 +504,25 @@ export const parsedHedTagTests = [ }, ], }, + { + name: 'name-space-tests', + description: 'tests with colons in various places', + warning: false, + tests: [ + { + testname: 'valid-date-time', + explanation: '"Creation-date/2009-04-09T12:04:14" is valid and no namespace.', + schemaVersion: '8.3.0', + tagPrefix: null, + fullString: 'Creation-date/2009-04-09T12:04:14', + tagSpec: new TagSpec('Creation-date/2009-04-09T12:04:14', 0, 33, ''), + tagLong: 'Property/Informational-property/Metadata/Creation-date/2009-04-09T12:04:14', + tagShort: 'Creation-date/2009-04-09T12:04:14', + formattedTag: 'property/informational-property/metadata/creation-date/2009-04-09t12:04:14', + canonicalTag: 'Property/Informational-property/Metadata/Creation-date/2009-04-09T12:04:14', + takesValue: true, + error: null, + }, + ], + }, ] diff --git a/tests/testData/tokenizerTests.data.js b/tests/testData/tokenizerTests.data.js index 2440a4d3..e1244278 100644 --- a/tests/testData/tokenizerTests.data.js +++ b/tests/testData/tokenizerTests.data.js @@ -63,6 +63,14 @@ export const tokenizerTests = [ groupSpec: new GroupSpec(0, 5, []), errors: [], }, + { + testname: 'tag-with-date-time', + string: 'Creation-date/2009-04-09T12:04:14', + explanation: 'Creation-date/2009-04-09T12:04:14" has a date-time value', + tagSpecs: [new TagSpec('Creation-date/2009-04-09T12:04:14', 0, 33, '')], + groupSpec: new GroupSpec(0, 33, []), + errors: [], + }, { testname: 'tag-with-multiple-colons', string: 'xy:wz x:y', diff --git a/tests/tokenizerTests.spec.js b/tests/tokenizerTests.spec.js index 3a498754..43ded67a 100644 --- a/tests/tokenizerTests.spec.js +++ b/tests/tokenizerTests.spec.js @@ -9,7 +9,7 @@ import { tokenizerTests } from './testData/tokenizerTests.data' // Ability to select individual tests to run const skipMap = new Map() const runAll = true -const runMap = new Map([['valid-placeholders', []]]) +const runMap = new Map([['valid-single-tags', ['tag-with-date-time']]]) describe('Tokenizer validation using JSON tests', () => { beforeAll(async () => {})