diff --git a/.github/workflows/tests_matlab.yml b/.github/workflows/tests_matlab.yml new file mode 100644 index 00000000..636fa742 --- /dev/null +++ b/.github/workflows/tests_matlab.yml @@ -0,0 +1,170 @@ +--- +name: tests matlab + +# Uses the cron schedule for github actions +# +# https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#scheduled-events +# +# ┌───────────── minute (0 - 59) +# │ ┌───────────── hour (0 - 23) +# │ │ ┌───────────── day of the month (1 - 31) +# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) +# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) +# │ │ │ │ │ +# │ │ │ │ │ +# │ │ │ │ │ +# * * * * * + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + schedule: + - cron: 0 0 1,15 * * + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + + test: + + if: github.repository_owner == 'cpp-lln-lab' + + strategy: + matrix: + test_type: [system] + script: [moae, facerep, fmriprep] + os: [ubuntu-latest, macos-latest, windows-latest] + include: + - test_type: unit + os: ubuntu-latest + - test_type: unit + os: macos-latest + - test_type: unit + os: windows-latest + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + + - name: ${{ matrix.test_type }} test + if: matrix.test_type == 'system' + run: echo ${{ matrix.test_type }} test ${{ matrix.script }} + + - name: Install dependencies + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get -y -qq update + sudo apt-get -y install unzip wget + + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Clone bidspm + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install validators + run: make install + + - name: Install SPM + run: | + git clone https://github.com/spm/spm12.git --depth 1 + + - name: Copy Macs toolbox to SPM inputs_folder on unix + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: cp -rv lib/MACS spm12/toolbox/MACS + - name: Copy Macs toolbox to SPM inputs_folder on windows + if: matrix.os == 'windows-latest' + run: Copy-Item -Recurse -Verbose -Path ".\lib\MACS" -Destination ".\spm12\toolbox\MACS" + + - name: Get moae fmriprep data from OSF on unix + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: | + mkdir -p demos/MoAE/inputs/ + cd demos/MoAE/inputs/ + wget https://osf.io/vufjs/download + unzip download + mv moae_fmriprep fmriprep + - name: Get moae fmriprep data from OSF on windows + if: matrix.os == 'windows-latest' + run: | + New-Item -ItemType Directory -Path ".\demos\MoAE\inputs\" -Force + Set-Location -Path ".\demos\MoAE\inputs\" + Invoke-WebRequest -Uri "https://osf.io/vufjs/download" -OutFile "download" + Expand-Archive -Path ".\download" -DestinationPath ".\" + Rename-Item -Path ".\moae_fmriprep" -NewName "fmriprep" + + - name: Prepare test data unix + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: | + cd tests + make data + - name: Prepare test data windows + if: matrix.os == 'windows-latest' + run: | + cd tests + make create_dummy_dataset + make bids_examples + Invoke-WebRequest -Uri "https://files.de-1.osf.io/v1/resources/3vufp/providers/osfstorage/62ab741be6f3ec09a7e48d13/?zip=" -OutFile "moae_spm12.zip" + New-Item -ItemType Directory -Path "data/MoAE/derivatives/spm12" -Force + Expand-Archive -Path "./moae_spm12.zip" -DestinationPath "./data/MoAE/derivatives/spm12" + + - name: Install Moxunit and MOcov + run: | + git clone https://github.com/MOxUnit/MOxUnit.git --depth 1 + git clone https://github.com/MOcov/MOcov.git --depth 1 + + - name: Install MATLAB + uses: matlab-actions/setup-matlab@v1.2.4 + with: + release: R2022b + + - name: Run unit tests MATLAB + if: matrix.test_type == 'unit' + uses: matlab-actions/run-command@v1.1.3 + with: + command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run tests_matlab; + + - name: Check unit tests + if: matrix.test_type == 'unit' && ( matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' ) + run: grep -q 0 test_report.log || { echo "Some tests failed. Check the 'Run tests' step to know which ones." >&2; exit 1; } + - name: Check logs windows + if: matrix.test_type == 'unit' && matrix.os == 'windows-latest' + run: | + if (-not (Get-Content test_report.log | Select-String -Pattern "0")) { + throw "Some tests failed. Check the 'Run tests' step to know which ones." + } + + - name: Code coverage matlab + if: matrix.test_type == 'unit' && ( matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' ) + uses: codecov/codecov-action@v3 + with: + file: coverage.xml + flags: ${{ matrix.os }}_matlab-${{ matrix.version }} + name: codecov-matlab + fail_ci_if_error: false + # token: ${{ secrets.CODECOV_TOKEN }} # not required but might help API rate limits + + + - name: Run system tests MATLAB ${{ matrix.script }} + if: matrix.test_type == 'system' + uses: matlab-actions/run-command@v1.1.3 + with: + command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run system_tests_${{ matrix.script }}; diff --git a/.github/workflows/tests.yml b/.github/workflows/tests_octave.yml similarity index 74% rename from .github/workflows/tests.yml rename to .github/workflows/tests_octave.yml index c2c0bf1e..3ebd6688 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests_octave.yml @@ -1,5 +1,5 @@ --- -name: tests +name: tests octave # Uses the cron schedule for github actions # @@ -43,21 +43,17 @@ jobs: strategy: matrix: - platform: [matlab, octave] test_type: [system] script: [moae, facerep, fmriprep] include: - test_type: unit - platform: matlab - - test_type: unit - platform: octave fail-fast: false steps: - - name: ${{ matrix.platform }} - ${{ matrix.test_type }} test + - name: ${{ matrix.test_type }} test if: matrix.test_type == 'system' - run: echo ${{ matrix.platform }} ${{ matrix.test_type }} test ${{ matrix.script }} + run: echo ${{ matrix.test_type }} test ${{ matrix.script }} - name: Install dependencies run: | @@ -109,7 +105,6 @@ jobs: git clone https://github.com/MOcov/MOcov.git --depth 1 - name: Install octave - if: matrix.platform == 'octave' run: | sudo apt-get -y -qq update sudo apt-get -y install \ @@ -124,7 +119,6 @@ jobs: make -C MOcov install - name: Compile SPM - if: matrix.platform == 'octave' run: | make -C spm12/src PLATFORM=octave distclean make -C spm12/src PLATFORM=octave @@ -132,48 +126,30 @@ jobs: octave $OCTFLAGS --eval "addpath(fullfile(pwd, 'spm12')); savepath();" - name: Run unit tests Octave - if: matrix.platform == 'octave' && matrix.test_type == 'unit' + if: matrix.test_type == 'unit' run: | octave $OCTFLAGS --eval "addpath(fullfile(pwd, 'tests', 'utils')); savepath();" octave $OCTFLAGS --eval "bidspm(); cd demos/MoAE; download_moae_ds(true);" cd .github/workflows octave $OCTFLAGS --eval "tests_octave;" - - name: Install MATLAB - if: matrix.platform == 'matlab' - uses: matlab-actions/setup-matlab@v1.2.4 - with: - release: R2020a - - - name: Run unit tests MATLAB - if: matrix.platform == 'matlab' && matrix.test_type == 'unit' - uses: matlab-actions/run-command@v1.1.3 - with: - command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run tests_matlab; - - name: Check unit tests if: matrix.test_type == 'unit' run: | cat test_report.log | grep 0 - - name: Code coverage ${{ matrix.platform }} + - name: Code coverage if: matrix.test_type == 'unit' uses: codecov/codecov-action@v3 with: file: coverage.xml - flags: ${{ matrix.platform }} - name: codecov-${{ matrix.platform }} + flags: octave + name: codecov-octave fail_ci_if_error: false # token: ${{ secrets.CODECOV_TOKEN }} # not required but might help API rate limits - name: Run system tests octave ${{ matrix.script }} - if: matrix.platform == 'octave' && matrix.test_type == 'system' + if: matrix.test_type == 'system' run: | cd /home/runner/work/bidspm/bidspm/.github/workflows octave $OCTFLAGS --eval "run system_tests_${{ matrix.script }};" - - - name: Run system tests MATLAB ${{ matrix.script }} - if: matrix.platform == 'matlab' && matrix.test_type == 'system' - uses: matlab-actions/run-command@v1.1.3 - with: - command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run system_tests_${{ matrix.script }}; diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 633148a1..674cba9d 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -31,9 +31,3 @@ jobs: use-quiet-mode: yes use-verbose-mode: yes config-file: .github/workflows/mlc_config.json - - codespell: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: codespell-project/actions-codespell@master diff --git a/bidspm.m b/bidspm.m index 539059ab..8c1d2d53 100644 --- a/bidspm.m +++ b/bidspm.m @@ -586,11 +586,16 @@ function run_tests() folderToCover = fullfile(pwd, 'src'); testFolder = fullfile(pwd, 'tests', subfolder); - success = moxunit_runtests(testFolder, ... - '-verbose', '-recursive', '-with_coverage', ... - '-cover', folderToCover, ... - '-cover_xml_file', 'coverage.xml', ... - '-cover_html_dir', fullfile(pwd, 'coverage_html')); + if ispc + success = moxunit_runtests(testFolder, ... + '-verbose', '-recursive'); + else + success = moxunit_runtests(testFolder, ... + '-verbose', '-recursive', '-with_coverage', ... + '-cover', folderToCover, ... + '-cover_xml_file', 'coverage.xml', ... + '-cover_html_dir', fullfile(pwd, 'coverage_html')); + end if success system('echo 0 > test_report.log'); diff --git a/demos/MoAE/test_moae.m b/demos/MoAE/test_moae.m index 54b22c36..a8b0bc53 100644 --- a/demos/MoAE/test_moae.m +++ b/demos/MoAE/test_moae.m @@ -51,7 +51,8 @@ %% preproc bids_dir = fullfile(WD, 'inputs', 'raw'); - output_dir = fullfile(WD, 'outputs', 'derivatives'); + output_dir = fullfile(tempname, 'outputs', 'derivatives'); + mkdir(output_dir); bidspm(bids_dir, output_dir, 'subject', ... 'participant_label', {'01'}, ... @@ -83,8 +84,6 @@ cd(WD); - rmdir(fullfile(WD, 'outputs', 'derivatives'), 's'); - % with Octave running more n-1 loop in CI is fine % but not running crashes with a segmentation fault % /home/runner/work/_temp/fb8e9d58-fa9f-4f93-8c96-387973f3632e.sh: line 2: diff --git a/demos/openneuro/Makefile b/demos/openneuro/Makefile index 4573cdf6..cb4417bd 100644 --- a/demos/openneuro/Makefile +++ b/demos/openneuro/Makefile @@ -43,8 +43,7 @@ data_ds001734: data_ds002799: mkdir -p inputs cd inputs && datalad install ///openneuro/ds002799 - cd inputs/ds002799/derivatives/fmriprep - datalad get sub-292/*/func/*MNI152NLin2009cAsym* - datalad get sub-292/*/func/*tsv - datalad get sub-30[27]/*/func/*MNI152NLin2009cAsym* - datalad get sub-30[27]/*/func/*tsv + datalad get -d inputs/ds002799 inputs/ds002799/derivatives/fmriprep/sub-292/*/func/*MNI152NLin2009cAsym* + datalad get -d inputs/ds002799 inputs/ds002799/derivatives/fmriprep/sub-292/*/func/*tsv + datalad get -d inputs/ds002799 inputs/ds002799/derivatives/fmriprep/sub-30[27]/*/func/*MNI152NLin2009cAsym* + datalad get -d inputs/ds002799 inputs/ds002799/derivatives/fmriprep/sub-30[27]/*/func/*tsv diff --git a/lib/CPP_ROI b/lib/CPP_ROI index d7726c09..3e5dbad2 160000 --- a/lib/CPP_ROI +++ b/lib/CPP_ROI @@ -1 +1 @@ -Subproject commit d7726c096586ad822579799c87463c9cfc17f432 +Subproject commit 3e5dbad29cdef05e68d6793278b8e86b3f2a2718 diff --git a/lib/bids-matlab b/lib/bids-matlab index 786b562a..287109a8 160000 --- a/lib/bids-matlab +++ b/lib/bids-matlab @@ -1 +1 @@ -Subproject commit 786b562ac6275683e5d52205ea31f06c3812d312 +Subproject commit 287109a8981ec913de32c295c31ff2bcd063ea3c diff --git a/lib/octache b/lib/octache index 12eca8da..99c970e3 160000 --- a/lib/octache +++ b/lib/octache @@ -1 +1 @@ -Subproject commit 12eca8da76633aae6b547ca399c60ed984bd3b4c +Subproject commit 99c970e362392c77eef10c2e917c7d90e8ad78f8 diff --git a/lib/riksneurotools b/lib/riksneurotools index 41f76e8e..20e7205a 160000 --- a/lib/riksneurotools +++ b/lib/riksneurotools @@ -1 +1 @@ -Subproject commit 41f76e8e2e0a00c1a1a699ac7515aa6f4b65d940 +Subproject commit 20e7205a9fc8951aaf4ecb73f2ee54a565a493f3 diff --git a/lib/spm_2_bids b/lib/spm_2_bids index 5a9bf746..64edd37d 160000 --- a/lib/spm_2_bids +++ b/lib/spm_2_bids @@ -1 +1 @@ -Subproject commit 5a9bf746248a264cbb486b4eb6885a94cb0df900 +Subproject commit 64edd37de4a70ed554cc6f57d3c32e64efa97244 diff --git a/requirements_doc.txt b/requirements_doc.txt index 5b3709f1..72f54ba8 100644 --- a/requirements_doc.txt +++ b/requirements_doc.txt @@ -8,3 +8,4 @@ sphinx_rtd_theme sphinxcontrib-bibtex sphinxcontrib-matlabdomain sphinxcontrib-mermaid +urllib3==1.26.15 diff --git a/src/IO/loadAndCheckOptions.m b/src/IO/loadAndCheckOptions.m index 628db9a8..4b62c5d7 100644 --- a/src/IO/loadAndCheckOptions.m +++ b/src/IO/loadAndCheckOptions.m @@ -42,7 +42,7 @@ % finds most recent option file if size(optionJsonFile, 1) > 1 containsDate = cellfun(@any, regexp(cellstr(optionJsonFile), ... - '^.*/[0-9]{4}-[0-9]{2}-[0-9]{2}T.*\.json')); + '^.*[0-9]{4}-[0-9]{2}-[0-9]{2}T.*\.json')); if any(containsDate) optionJsonFile = optionJsonFile(containsDate, :); optionJsonFile = sortrows(optionJsonFile); diff --git a/src/QA/anatQA.m b/src/QA/anatQA.m index 8d64319c..404e087c 100644 --- a/src/QA/anatQA.m +++ b/src/QA/anatQA.m @@ -148,10 +148,11 @@ Bmax = sqrt(sum(data(:).^2)); try % should work most of the time, possibly throwing warnings (cf Joost Kuijer) - json.EFC = real(nansum((data(:) ./ Bmax) .* log(data(:) ./ Bmax))); + tmp = (data(:) ./ Bmax) .* log(data(:) ./ Bmax); catch - json.EFC = real(nansum((data(:) ./ Bmax) .* abs(log(data(:) ./ Bmax)))); + tmp = (data(:) ./ Bmax) .* abs(log(data(:) ./ Bmax)); end + json.EFC = real(bids.internal.nansum(tmp)); end diff --git a/src/QA/computeRobustOutliers.m b/src/QA/computeRobustOutliers.m index 9754f9d4..f4d87ad7 100644 --- a/src/QA/computeRobustOutliers.m +++ b/src/QA/computeRobustOutliers.m @@ -72,6 +72,15 @@ end if strcmpi(outlierType, 's-outliers') + + if isempty(which('chi2inv')) + logger('WARNING', 'chi2inv function required to compute s-outliers.', ... + 'filename', mfilename, ... + 'id', 'missingChi2inv'); + outliers = false(size(timeSeries)); + return + end + k = sqrt(chi2inv(0.975, 1)); for p = size(timeSeries, 2):-1:1 tmp = timeSeries(:, p); diff --git a/src/stats/subject_level/convertOnsetTsvToMat.m b/src/stats/subject_level/convertOnsetTsvToMat.m index a0dc5df5..3d3cd555 100644 --- a/src/stats/subject_level/convertOnsetTsvToMat.m +++ b/src/stats/subject_level/convertOnsetTsvToMat.m @@ -51,10 +51,25 @@ % (C) Copyright 2019 bidspm developers + REQUIRED_COLUMNS = {'onset', 'duration'}; + [pth, file, ext] = spm_fileparts(tsvFile); tsv.file = validationInputFile(pth, [file, ext]); tsv.content = bids.util.tsvread(tsv.file); + for i = 1:numel(REQUIRED_COLUMNS) + if ~isfield(tsv.content, REQUIRED_COLUMNS{i}) + msg = sprintf(['''%s'' column is missing from file: %s', ... + '\nAvailable columns are: %s'], ... + REQUIRED_COLUMNS{i}, ... + tsv.file, ... + bids.internal.create_unordered_list(fieldnames(tsv.content))); + logger('ERROR', msg, ... + 'filename', mfilename(), ... + 'id', 'missingTrialypeColumn'); + end + end + if ~all(isnumeric(tsv.content.onset)) msg = sprintf('%s\n%s', 'Onset column contains non numeric values in file:', tsv.file); diff --git a/src/stats/subject_level/getEventsData.m b/src/stats/subject_level/getEventsData.m index d32fd03a..fb542cc3 100644 --- a/src/stats/subject_level/getEventsData.m +++ b/src/stats/subject_level/getEventsData.m @@ -11,6 +11,16 @@ content = bids.util.tsvread(tsvFile); + if ~isfield(content, 'trial_type') + msg = sprintf(['''trial_type'' column is missing from file: %s', ... + '\nAvailable columns are: %s'], ... + tsvFile, ... + bids.internal.create_unordered_list(fieldnames(content))); + logger('ERROR', msg, ... + 'filename', mfilename(), ... + 'id', 'missingTrialypeColumn'); + end + conditions = unique(content.trial_type); if ~isempty(modelFile) diff --git a/src/utils/computeTsnr.m b/src/utils/computeTsnr.m index b761315c..4b6a2db8 100755 --- a/src/utils/computeTsnr.m +++ b/src/utils/computeTsnr.m @@ -109,3 +109,17 @@ outData = data - X(:, 2:end) * b(2:end, :); end + +function y = nanmean(varargin) + + if bids.internal.is_octave() + data = varargin{1}(:); + nanIdx = isnan(data); + y = mean(data(~nanIdx)); + return + end + + narginchk(1, 2); + y = mean(varargin{:}, 'omitnan'); + +end diff --git a/tests/Makefile b/tests/Makefile index 5b2e2bce..f642a785 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -9,12 +9,16 @@ clean_local: rm -rf data/derivatives/bidspm-stats/group rm -rf data/derivatives/bidspm-*/jobs -data: clean +create_dummy_dataset: clean sh createDummyDataSet.sh + +bids_examples: rm -rf bids-examples/ git clone https://github.com/bids-standard/bids-examples.git --depth 1 cp bids-examples/synthetic/dataset_description.json bids-examples/synthetic/derivatives/fmriprep touch bids-examples/.gitkeep + +data: create_dummy_dataset bids_examples wget --quiet -O moae_spm12.zip https://files.de-1.osf.io/v1/resources/3vufp/providers/osfstorage/62ab741be6f3ec09a7e48d13/?zip= mkdir -p data/MoAE/derivatives/spm12 unzip -d ./data/MoAE/derivatives/spm12 moae_spm12.zip diff --git a/tests/tests_unit/IO/test_addGitIgnore.m b/tests/tests_unit/IO/test_addGitIgnore.m index 7744bd5f..46af5b5b 100644 --- a/tests/tests_unit/IO/test_addGitIgnore.m +++ b/tests/tests_unit/IO/test_addGitIgnore.m @@ -1,6 +1,5 @@ -% (C) Copyright 2020 bidspm developers - function test_suite = test_addGitIgnore %#ok<*STOUT> + % (C) Copyright 2020 bidspm developers try % assignment of 'localfunctions' is necessary in Matlab >= 2016 test_functions = localfunctions(); %#ok<*NASGU> catch % no problem; early Matlab versions can use initTestSuite fine @@ -10,44 +9,38 @@ function test_addGitIgnore_basic() - if exist(fullfile(pwd, '.gitignore'), 'file') - delete(fullfile(pwd, '.gitignore')); - end + pth = tempName(); - addGitIgnore(pwd); + addGitIgnore(pth); - assertEqual(exist(fullfile(pwd, '.gitignore'), 'file'), 2); + assertEqual(exist(fullfile(pth, '.gitignore'), 'file'), 2); - fid = fopen(fullfile(pwd, '.gitignore'), 'r'); + fid = fopen(fullfile(pth, '.gitignore'), 'r'); c = fread(fid, Inf, 'uint8=>char')'; assertEqual(strfind(c, '.DS_store'), 1); fclose(fid); - delete(fullfile(pwd, '.gitignore')); - end function test_addGitIgnore_already_present() - if exist(fullfile(pwd, '.gitignore'), 'file') - delete(fullfile(pwd, '.gitignore')); - end - fid = fopen(fullfile(pwd, '.gitignore'), 'w'); + pth = tempName(); + + fid = fopen(fullfile(pth, '.gitignore'), 'w'); fprintf(fid, 'foo\n'); fprintf(fid, '.DS_store\n'); fclose(fid); - addGitIgnore(pwd); + addGitIgnore(pth); - fid = fopen(fullfile(pwd, '.gitignore'), 'r'); + fid = fopen(fullfile(pth, '.gitignore'), 'r'); c = fread(fid, Inf, 'uint8=>char')'; assertEqual(numel(strfind(c, '.DS_store')), 1); fclose(fid); - delete(fullfile(pwd, '.gitignore')); end function test_addGitIgnore_append() @@ -56,21 +49,22 @@ function test_addGitIgnore_append() return end - if exist(fullfile(pwd, '.gitignore'), 'file') - delete(fullfile(pwd, '.gitignore')); + if ispc || ismac + return end - fid = fopen(fullfile(pwd, '.gitignore'), 'w'); + pth = tempName(); + + fid = fopen(fullfile(pth, '.gitignore'), 'w'); fprintf(fid, 'foo\n'); fprintf(fid, 'bar\n'); fclose(fid); - addGitIgnore(pwd); + addGitIgnore(pth); - fid = fopen(fullfile(pwd, '.gitignore'), 'r'); + fid = fopen(fullfile(pth, '.gitignore'), 'r'); c = fread(fid, Inf, 'uint8=>char')'; assert(strfind(c, '.DS_store') > 0); fclose(fid); - delete(fullfile(pwd, '.gitignore')); end diff --git a/tests/tests_unit/IO/test_saveSpmScript.m b/tests/tests_unit/IO/test_saveSpmScript.m index 046386d2..bde5470b 100644 --- a/tests/tests_unit/IO/test_saveSpmScript.m +++ b/tests/tests_unit/IO/test_saveSpmScript.m @@ -30,6 +30,9 @@ function test_saveSpmScript_basic() fid1 = fopen(expectedContent, 'r'); expectedContent = fscanf(fid1, '%s'); fclose(fid1); + if ispc + expectedContent = strrep('/', '\'); + end fid2 = fopen(outputFilename, 'r'); actualContent = fscanf(fid2, '%s'); diff --git a/tests/utils/tempName.m b/tests/utils/tempName.m new file mode 100644 index 00000000..3b250840 --- /dev/null +++ b/tests/utils/tempName.m @@ -0,0 +1,11 @@ +function pth = tempName() + % + % Creates a temporary directory and returns its fullpath + % + + % (C) Copyright 2023 bidspm developers + + pth = tempname(); + mkdir(pth); + +end