# HG changeset patch # User Rik # Date 1509323621 25200 # Node ID 068556c5167e9bca5173154c8ba93fe73f3c41f7 # Parent 7dd3ab97ccd5e4f5745647ebad838a66d8f20e27 Add BIST test for clear() function (bug #35881). * test/bug-35881/bug-35881.tst: New tests for clear() function which verify that current function is unaffected. * test/bug-35881/bug35881.m: New test code. * test/bug-35881/module.mk: Add test files to build system. * __run_test_suite__.m: Replace global variables with function variables. Use nested functions to access parent's copy of function variable. Modify function to accept two additional inputs: topsrcdir and topbuilddir. * test/fntests.m: Call __run_test_suite__ with topsrcdir and topbuilddir inputs. * test/module.mk: Add bug-35881 files to build system. diff -r 7dd3ab97ccd5 -r 068556c5167e scripts/testfun/__run_test_suite__.m --- a/scripts/testfun/__run_test_suite__.m Sat Oct 28 18:24:14 2017 -0700 +++ b/scripts/testfun/__run_test_suite__.m Sun Oct 29 17:33:41 2017 -0700 @@ -21,7 +21,7 @@ ## Undocumented internal function. ## @end deftypefn -function [pass, fail, xfail, xbug, skip, rtskip, regress] = __run_test_suite__ (fcndirs, fixedtestdirs) +function [pass, fail, xfail, xbug, skip, rtskip, regress] = __run_test_suite__ (fcndirs, fixedtestdirs, topsrcdir = [], topbuilddir = []) testsdir = __octave_config_info__ ("octtestsdir"); libinterptestdir = fullfile (testsdir, "libinterp"); @@ -32,14 +32,17 @@ fcndirs = { liboctavetestdir, libinterptestdir, fcnfiledir }; fixedtestdirs = { fixedtestdir }; endif - global files_with_no_tests; - global files_with_tests; files_with_no_tests = {}; files_with_tests = {}; ## FIXME: These names don't really make sense if we are running ## tests for an installed copy of Octave. - global topsrcdir = fcnfiledir; - global topbuilddir = testsdir; + if (isempty (topsrcdir)) + topsrcdir = fcnfiledir; + endif + if (isempty (topbuilddir)) + topbuilddir = testsdir; + endif + pso = page_screen_output (); orig_wstate = warning (); logfile = make_absolute_filename ("fntests.log"); @@ -145,6 +148,113 @@ regress = drgrs; endif + + function [dp, dn, dxf, dxb, dsk, drtsk, drgrs] = run_test_dir (fid, d) + + lst = dir (d); + dp = dn = dxf = dxb = dsk = drtsk = drgrs = 0; + for i = 1:length (lst) + nm = lst(i).name; + if (lst(i).isdir + && nm(1) != "." && ! strcmp (nm, "private") && nm(1) != "@") + [p, n, xf, xb, sk, rtsk, rgrs] = run_test_dir (fid, [d, filesep, nm]); + dp += p; + dn += n; + dxf += xf; + dxb += xb; + dsk += sk; + drtsk += rtsk; + drgrs += rgrs; + endif + endfor + + saved_dir = pwd (); + unwind_protect + cd (d); + for i = 1:length (lst) + nm = lst(i).name; + if (length (nm) > 4 && strcmpi (nm((end-3):end), ".tst")) + p = n = xf = xb = sk = rtsk = 0; + ffnm = fullfile (d, nm); + if (has_tests (ffnm)) + print_test_file_name (nm); + [p, n, xf, xb, sk, rtsk, rgrs] = test (nm, "quiet", fid); + print_pass_fail (p, n, xf, xb, sk, rtsk, rgrs); + files_with_tests(end+1) = ffnm; + else + files_with_no_tests(end+1) = ffnm; + endif + dp += p; + dn += n; + dxf += xf; + dxb += xb; + dsk += sk; + drtsk += rtsk; + drgrs += rgrs; + endif + endfor + unwind_protect_cleanup + cd (saved_dir); + end_unwind_protect + + endfunction + + function [dp, dn, dxf, dxb, dsk, drtsk, drgrs] = run_test_script (fid, d) + + lst = dir (d); + dp = dn = dxf = dxb = dsk = drtsk = drgrs = 0; + for i = 1:length (lst) + nm = lst(i).name; + if (lst(i).isdir && nm(1) != ".") + [p, n, xf, xb, sk, rtsk, rgrs] = run_test_script (fid, [d, filesep, nm]); + dp += p; + dn += n; + dxf += xf; + dxb += xb; + dsk += sk; + drtsk += rtsk; + drgrs += rgrs; + endif + endfor + + for i = 1:length (lst) + nm = lst(i).name; + ## Ignore hidden files + if (nm(1) == '.') + continue + endif + f = fullfile (d, nm); + if ((length (nm) > 2 && strcmpi (nm((end-1):end), ".m")) + || (length (nm) > 4 + && ( strcmpi (nm((end-3):end), "-tst") + || strcmpi (nm((end-3):end), ".tst")))) + p = n = xf = xb = 0; + ## Only run if contains %!test, %!assert, %!error, %!fail, or %!warning + if (has_tests (f)) + tmp = strrep (f, [topsrcdir, filesep], ""); + tmp = strrep (tmp, [topbuilddir, filesep], ""); + print_test_file_name (tmp); + [p, n, xf, xb, sk, rtsk, rgrs] = test (f, "quiet", fid); + print_pass_fail (p, n, xf, xb, sk, rtsk, rgrs); + dp += p; + dn += n; + dxf += xf; + dxb += xb; + dsk += sk; + drtsk += rtsk; + drgrs += rgrs; + files_with_tests(end+1) = f; + else + ## To reduce the list length, only mark .cc files that contain + ## DEFUN definitions. + files_with_no_tests(end+1) = f; + endif + endif + endfor + ## printf("%s%s -> passes %d of %d tests\n", ident, d, dp, dn); + + endfunction + endfunction function print_test_file_name (nm) @@ -215,118 +325,6 @@ endfunction -function [dp, dn, dxf, dxb, dsk, drtsk, drgrs] = run_test_dir (fid, d) - global files_with_tests; - global files_with_no_tests; - - lst = dir (d); - dp = dn = dxf = dxb = dsk = drtsk = drgrs = 0; - for i = 1:length (lst) - nm = lst(i).name; - if (lst(i).isdir - && nm(1) != "." && ! strcmp (nm, "private") && nm(1) != "@") - [p, n, xf, xb, sk, rtsk, rgrs] = run_test_dir (fid, [d, filesep, nm]); - dp += p; - dn += n; - dxf += xf; - dxb += xb; - dsk += sk; - drtsk += rtsk; - drgrs += rgrs; - endif - endfor - - saved_dir = pwd (); - unwind_protect - cd (d); - for i = 1:length (lst) - nm = lst(i).name; - if (length (nm) > 4 && strcmpi (nm((end-3):end), ".tst")) - p = n = xf = xb = sk = rtsk = 0; - ffnm = fullfile (d, nm); - if (has_tests (ffnm)) - print_test_file_name (nm); - [p, n, xf, xb, sk, rtsk, rgrs] = test (nm, "quiet", fid); - print_pass_fail (p, n, xf, xb, sk, rtsk, rgrs); - files_with_tests(end+1) = ffnm; - else - files_with_no_tests(end+1) = ffnm; - endif - dp += p; - dn += n; - dxf += xf; - dxb += xb; - dsk += sk; - drtsk += rtsk; - drgrs += rgrs; - endif - endfor - unwind_protect_cleanup - cd (saved_dir); - end_unwind_protect - -endfunction - -function [dp, dn, dxf, dxb, dsk, drtsk, drgrs] = run_test_script (fid, d) - global files_with_tests; - global files_with_no_tests; - global topsrcdir; - global topbuilddir; - - lst = dir (d); - dp = dn = dxf = dxb = dsk = drtsk = drgrs = 0; - for i = 1:length (lst) - nm = lst(i).name; - if (lst(i).isdir && nm(1) != ".") - [p, n, xf, xb, sk, rtsk, rgrs] = run_test_script (fid, [d, filesep, nm]); - dp += p; - dn += n; - dxf += xf; - dxb += xb; - dsk += sk; - drtsk += rtsk; - drgrs += rgrs; - endif - endfor - - for i = 1:length (lst) - nm = lst(i).name; - ## Ignore hidden files - if (nm(1) == '.') - continue - endif - f = fullfile (d, nm); - if ((length (nm) > 2 && strcmpi (nm((end-1):end), ".m")) - || (length (nm) > 4 - && ( strcmpi (nm((end-3):end), "-tst") - || strcmpi (nm((end-3):end), ".tst")))) - p = n = xf = xb = 0; - ## Only run if it contains %!test, %!assert, %!error, %!fail, or %!warning - if (has_tests (f)) - tmp = strrep (f, [topsrcdir, filesep], ""); - tmp = strrep (tmp, [topbuilddir, filesep], ""); - print_test_file_name (tmp); - [p, n, xf, xb, sk, rtsk, rgrs] = test (f, "quiet", fid); - print_pass_fail (p, n, xf, xb, sk, rtsk, rgrs); - dp += p; - dn += n; - dxf += xf; - dxb += xb; - dsk += sk; - drtsk += rtsk; - drgrs += rgrs; - files_with_tests(end+1) = f; - else - ## To reduce the list length, only mark .cc files that contain - ## DEFUN definitions. - files_with_no_tests(end+1) = f; - endif - endif - endfor - ## printf("%s%s -> passes %d of %d tests\n", ident, d, dp, dn); - -endfunction - function n = num_elts_matching_pattern (lst, pat) n = sum (! cellfun ("isempty", regexp (lst, pat, 'once'))); endfunction diff -r 7dd3ab97ccd5 -r 068556c5167e test/bug-35881/bug-35881.tst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-35881/bug-35881.tst Sun Oct 29 17:33:41 2017 -0700 @@ -0,0 +1,32 @@ +## Copyright (C) 2017 Rik Wehbring +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +%!test +%! global _tstvar_; # Final test does "clear all" which removes this var. +%! +%! _tstvar_ = struct ("init1",-1, "a1",-1, "init2",-1, "a2",-1); +%! bug35881 (0); +%! assert (_tstvar_, struct ("init1",true, "a1",1, "init2",false, "a2",1)); +%! clear -f bug35881 +%! +%! _tstvar_ = struct ("init1",-1, "a1",-1, "init2",-1, "a2",-1); +%! bug35881 (1); +%! assert (_tstvar_, struct ("init1",true, "a1",1, "init2",false, "a2",1)); +%! +%! _tstvar_ = struct ("init1",-1, "a1",-1, "init2",-1, "a2",-1); +%! fail ("bug35881 (2)", "'a' undefined near line"); diff -r 7dd3ab97ccd5 -r 068556c5167e test/bug-35881/bug35881.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-35881/bug35881.m Sun Oct 29 17:33:41 2017 -0700 @@ -0,0 +1,60 @@ +function bug35881 (flag = 0) + persistent a; + global _tstvar_; + + if (isempty (a)) + a = 1; + endif + + _tstvar_.init1 = subf (); + _tstvar_.a1 = a; + ##ML:fprintf ('a=%d\n', a); + + switch (flag) + case 0 + clear subf; + case 1 + clear functions; + case 2 + clear all; + endswitch + + _tstvar_.init2 = subf (); + _tstvar_.a2 = a; + ##ML:fprintf ('a=%d\n', a); + ##ML:fprintf ('------\n\n'); +endfunction + +function retval = subf () + persistent x; + + retval = false; + ##ML:fprintf ('subf: '); + if (isempty (x)) + x = 1; + retval = true; + ##ML:fprintf ('INIT, '); + endif + +endfunction + +## Expected results from Matlab 2016A +## Uncomment "##ML:" +#{ +>> clear all; bug35881 (0) +subf: INIT, a=1 +subf: a=1 +------ + +>> clear all; bug35881 (1) +subf: INIT, a=1 +subf: a=1 +------ + +>> clear all; bug35881 (2) +subf: INIT, a=1 +subf: Reference to a cleared variable a. +Error in test_clear_inside_function (line 13) +subf (); fprintf ('a=%d\n', a); +#} + diff -r 7dd3ab97ccd5 -r 068556c5167e test/bug-35881/module.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-35881/module.mk Sun Oct 29 17:33:41 2017 -0700 @@ -0,0 +1,5 @@ +bug_35881_TEST_FILES = \ + %reldir%/bug-35881.tst \ + %reldir%/bug35881.m + +TEST_FILES += $(bug_35881_TEST_FILES) diff -r 7dd3ab97ccd5 -r 068556c5167e test/fntests.m --- a/test/fntests.m Sat Oct 28 18:24:14 2017 -0700 +++ b/test/fntests.m Sun Oct 29 17:33:41 2017 -0700 @@ -18,11 +18,6 @@ clear all; -global files_with_no_tests = {}; -global files_with_tests = {}; -global topsrcdir; -global topbuilddir; - currdir = canonicalize_file_name ("."); debug_on_error (true); @@ -54,4 +49,4 @@ fundirs{end+1} = local_script_tree; endif -__run_test_suite__ (fundirs, testdirs); +__run_test_suite__ (fundirs, testdirs, topsrcdir, topbuilddir); diff -r 7dd3ab97ccd5 -r 068556c5167e test/module.mk --- a/test/module.mk Sat Oct 28 18:24:14 2017 -0700 +++ b/test/module.mk Sun Oct 29 17:33:41 2017 -0700 @@ -47,6 +47,7 @@ DIRSTAMP_FILES += %reldir%/$(octave_dirstamp) include %reldir%/bug-35448/module.mk +include %reldir%/bug-35881/module.mk include %reldir%/bug-36025/module.mk include %reldir%/bug-38236/module.mk include %reldir%/bug-38691/module.mk