From b14f20e839ba9375ee53df8612501d80d0f1b720 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Fri, 2 Aug 2024 14:52:42 -0400 Subject: [PATCH 1/2] feat: Add exists(..., file) for file-relative paths --- bids-validator/src/schema/expressionLanguage.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bids-validator/src/schema/expressionLanguage.ts b/bids-validator/src/schema/expressionLanguage.ts index d9ff767fa..a501ef4d5 100644 --- a/bids-validator/src/schema/expressionLanguage.ts +++ b/bids-validator/src/schema/expressionLanguage.ts @@ -1,15 +1,17 @@ -function exists(list: string[], rule: string = 'dataset'): number { +import { BIDSContext } from './context.ts' + +function exists(this: BIDSContext, list: string[], rule: string = 'dataset'): number { if (list == null) { return 0 } const prefix: string[] = [] + const fileTree = rule == 'file' ? this.file.parent : this.fileTree // Stimuli and subject-relative paths get prefixes if (rule == 'stimuli') { prefix.push('stimuli') } else if (rule == 'subject') { - // @ts-expect-error prefix.push('sub-' + this.entities.sub) } @@ -28,8 +30,7 @@ function exists(list: string[], rule: string = 'dataset'): number { // dataset, subject and stimuli return list.filter((x) => { const parts = prefix.concat(x.split('/')) - // @ts-expect-error - return this.fileTree.contains(parts) + return fileTree.contains(parts) }).length } } From 5ece19e81a9f2d951cf264ed314fc77e293b0cd6 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Fri, 2 Aug 2024 22:08:12 -0400 Subject: [PATCH 2/2] test(expressions): Test file-relative existence check --- .../src/schema/expressionLanguage.test.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/bids-validator/src/schema/expressionLanguage.test.ts b/bids-validator/src/schema/expressionLanguage.test.ts index 21bd5d454..91ed78215 100644 --- a/bids-validator/src/schema/expressionLanguage.test.ts +++ b/bids-validator/src/schema/expressionLanguage.test.ts @@ -91,8 +91,9 @@ Deno.test('test expression functions', async (t) => { assert(count(['a', 'b', 'a', 'b'], 'a') === 2) assert(count(['a', 'b', 'a', 'b'], 'c') === 0) }) + + const exists = expressionFunctions.exists.bind(context) await t.step('exists(..., "dataset") function', () => { - const exists = expressionFunctions.exists.bind(context) assert(exists([], 'dataset') === 0) assert( exists(['sub-01/ses-01/anat/sub-01_ses-01_T1w.nii.gz'], 'dataset') === 1, @@ -105,7 +106,6 @@ Deno.test('test expression functions', async (t) => { ) }) await t.step('exists(..., "subject") function', () => { - const exists = expressionFunctions.exists.bind(context) assert(exists([], 'subject') === 0) assert(exists(['ses-01/anat/sub-01_ses-01_T1w.nii.gz'], 'subject') === 1) assert( @@ -115,15 +115,19 @@ Deno.test('test expression functions', async (t) => { ) === 1, ) }) + await t.step('exists(..., "file") function', () => { + assert(exists([], 'file') === 0) + assert(exists(['sub-01_ses-01_T1w.nii.gz'], 'file') === 1) + assert(exists(['sub-01_ses-01_T1w.nii.gz', 'sub-01_ses-01_T1w.json'], 'file') === 2) + assert(exists(['sub-01_ses-01_T1w.nii.gz', 'ses-01_T1w.json'], 'file') === 1) + }) await t.step('exists(..., "stimuli") function', () => { - const exists = expressionFunctions.exists.bind(context) assert(exists([], 'stimuli') === 0) assert(exists(['stimfile1.png'], 'stimuli') === 1) assert(exists(['stimfile1.png', 'stimfile2.png'], 'stimuli') === 2) assert(exists(['X.png', 'Y.png'], 'stimuli') === 0) }) await t.step('exists(..., "bids-uri") function', () => { - const exists = expressionFunctions.exists.bind(context) assert(exists([], 'subject') === 0) assert( exists( @@ -140,6 +144,7 @@ Deno.test('test expression functions', async (t) => { // Not yet implemented; currently returns length of array // assert(exists(['bids::sub-01/ses-01/anat/sub-01_ses-01_T1w.nii.gz', 'bids::T2w.json'], 'bids-uri') === 1) }) + await t.step('substr function', () => { const substr = expressionFunctions.substr assert(substr('abc', 0, 1) === 'a')