Very interesting project. I think the best option you have is to write a separate function to run the tests and use a unique prefix for the whole variable inside this function to avoid name conflict. Here is my attempt:
function [PREFIX_b varargout] = testContext(PREFIX_src, PREFIX_srcOutput) %# TESTCONTEXT Executes the source code and tests for %# equality against the expected output %# %# Input: %# PREFIX_src - source to execute, cellarry of statements %# PREFIX_srcOutput - output to expect, cellarray of output of each statement %# %# Output: %# PREFIX_b - true/false for success/failure of test %# note that the output is strtrim()'ed then strcmp()'ed %# varargout{1} - variable names assigned in this confined context %# varargout{2} - variable values assigned %# %# Example 1: %# source = { 'I = 5+33;' 'I' }; %# output = { [], ['I =' char(10) ' 38'] }; %# b = testContext(source, output); %# %# Example 2: %# source = { 'I = 5+33; J = 2;' 'K = 1;' 'disp(I+J+K)' }; %# output = { [], [], '41' }; %# [b varNames varValues] = testContext(source, output); %# %# See also: eval evalc %# PREFIX_b = true; try %# for each statement for PREFIX_i=1:numel(PREFIX_src) %# evaluate PREFIX_output = evalc( PREFIX_src{PREFIX_i} ); PREFIX_output = strtrim(PREFIX_output); %# trim whitespaces %# compare output if ~isempty( PREFIX_srcOutput{PREFIX_i} ) if ~strcmp(PREFIX_output,PREFIX_srcOutput{PREFIX_i}) PREFIX_b = false; return end end end if nargout > 1 %# list created variables in this context %#clear ans PREFIX_vars = whos('-regexp', '^(?!PREFIX_).*'); %# java regex negative lookahead varargout{1} = { PREFIX_vars.name }; if nargout > 2 %# return those variables varargout{2} = cell(1,numel(PREFIX_vars)); for PREFIX_i=1:numel(PREFIX_vars) [~,varargout{2}{PREFIX_i}] = evalc( PREFIX_vars(PREFIX_i).name ); end end end catch ME warning(ME.identifier, ME.message) PREFIX_b = false; varargout{1} = {}; varargout{2} = {}; end end
I assume that you can parse the m file to restore examples for testing, where you have each statement along with its expected output.
As an example, consider this simple test built into the function header:
I = 5 + 33; J = 2*I; disp(I+J)
Since only the last statement has an output, we test it as:
source = {'I = 5 + 33;' 'J = 2*I;' 'disp(I+J)'}; output = {[], [], '114'}; [b varNames varValues] = testContext(source, output)
results:
b = 1 varNames = 'I' 'J' varValues = [38] [76]
Indicates whether the test that failed has passed. Optionally, the function returns a list of variables created in this context, along with its values.