124 lines
3.7 KiB
Matlab
124 lines
3.7 KiB
Matlab
function summary = generateTests(options)
|
|
%GENERATETESTS Generate placeholder tests for class files without tests.
|
|
|
|
arguments
|
|
options.force (1, 1) logical = false
|
|
options.verbose (1, 1) logical = true
|
|
end
|
|
|
|
testsRoot = fileparts(mfilename('fullpath'));
|
|
repoRoot = fileparts(testsRoot);
|
|
classesRoot = fullfile(repoRoot, 'Classes');
|
|
|
|
classFiles = collectMFiles(classesRoot);
|
|
classInfos = struct('className', {}, 'relativeDir', {}, 'classFile', {});
|
|
baseNameCounts = containers.Map('KeyType', 'char', 'ValueType', 'double');
|
|
|
|
for idx = 1:numel(classFiles)
|
|
classFile = fullfile(classFiles(idx).folder, classFiles(idx).name);
|
|
if ~isClassFile(classFile)
|
|
continue
|
|
end
|
|
|
|
[relativeDir, className] = relativeClassInfo(classFile, classesRoot);
|
|
|
|
classInfos(end + 1) = struct( ... %#ok<AGROW>
|
|
'className', className, ...
|
|
'relativeDir', relativeDir, ...
|
|
'classFile', classFile);
|
|
|
|
key = lower(className);
|
|
if isKey(baseNameCounts, key)
|
|
baseNameCounts(key) = baseNameCounts(key) + 1;
|
|
else
|
|
baseNameCounts(key) = 1;
|
|
end
|
|
end
|
|
|
|
generated = 0;
|
|
skippedExisting = 0;
|
|
|
|
for idx = 1:numel(classInfos)
|
|
info = classInfos(idx);
|
|
key = lower(info.className);
|
|
|
|
testClassName = buildTestClassName( ...
|
|
info.className, info.relativeDir, baseNameCounts(key) > 1);
|
|
testDir = fullfile(testsRoot, info.relativeDir);
|
|
testFile = fullfile(testDir, [testClassName, '.m']);
|
|
|
|
if ~options.force
|
|
if isfile(testFile)
|
|
skippedExisting = skippedExisting + 1;
|
|
continue
|
|
end
|
|
end
|
|
|
|
if ~isfolder(testDir)
|
|
mkdir(testDir);
|
|
end
|
|
|
|
createTestFile(testClassName, info.className, info.classFile, testFile);
|
|
generated = generated + 1;
|
|
end
|
|
|
|
summary = struct( ...
|
|
'generated', generated, ...
|
|
'skippedExisting', skippedExisting, ...
|
|
'classCount', numel(classInfos));
|
|
|
|
if options.verbose
|
|
fprintf(['Generated %d placeholder tests, skipped %d existing tests, ', ...
|
|
'tracked %d class files.\n'], ...
|
|
summary.generated, summary.skippedExisting, summary.classCount);
|
|
end
|
|
end
|
|
|
|
function tf = isClassFile(filePath)
|
|
source = fileread(filePath);
|
|
tf = contains(source, 'classdef');
|
|
end
|
|
|
|
function [relativeDir, className] = relativeClassInfo(classFile, classesRoot)
|
|
relativePath = strrep(classFile, [classesRoot, filesep], '');
|
|
[relativeDir, className] = fileparts(relativePath);
|
|
end
|
|
|
|
function testClassName = buildTestClassName(className, relativeDir, hasDuplicateBaseName)
|
|
if ~hasDuplicateBaseName
|
|
testClassName = [className, '_test'];
|
|
else
|
|
if isempty(relativeDir)
|
|
prefix = 'root';
|
|
else
|
|
prefix = regexprep(relativeDir, '[^A-Za-z0-9]+', '_');
|
|
prefix = regexprep(prefix, '^_+|_+$', '');
|
|
end
|
|
|
|
testClassName = [prefix, '_', className, '_test'];
|
|
end
|
|
|
|
if ~isletter(testClassName(1))
|
|
testClassName = ['T_', testClassName];
|
|
end
|
|
end
|
|
|
|
function files = collectMFiles(rootFolder)
|
|
pathString = genpath(rootFolder);
|
|
folders = regexp(pathString, pathsep, 'split');
|
|
folders = folders(~cellfun('isempty', folders));
|
|
|
|
files = dir(fullfile(rootFolder, '*.m'));
|
|
files = files([]); % empty struct with dir() fields
|
|
|
|
for idx = 1:numel(folders)
|
|
currentFiles = dir(fullfile(folders{idx}, '*.m'));
|
|
if isempty(currentFiles)
|
|
continue
|
|
end
|
|
|
|
currentFiles = currentFiles(~[currentFiles.isdir]);
|
|
files = [files; currentFiles]; %#ok<AGROW>
|
|
end
|
|
end
|