From b93e75dd3343ba36e944c2b13f3bb4f75f54410a Mon Sep 17 00:00:00 2001 From: "Colin B. Macdonald" Date: Thu, 21 Mar 2019 02:10:06 -0700 Subject: [PATCH] try methods(foo) to determine if foo is an object Use a try-catch block with the methods call. If it has methods it must be a class. This allows refactoring the object identification code a bit. Fixes a few bugs. Fixes #199. Fixes #200. Fixes #211. Related to Issue #196. --- inst/private/doctest_collect.m | 41 ++++++++++++++++++---------------- test/bist.m | 11 ++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/inst/private/doctest_collect.m b/inst/private/doctest_collect.m index a668ba7..aad06c4 100644 --- a/inst/private/doctest_collect.m +++ b/inst/private/doctest_collect.m @@ -30,33 +30,36 @@ elseif (exist (what) == 3) % .oct/.mex [~, what, ~] = fileparts (what); % strip extension if present type = 'function'; % then access like any function - elseif (exist(what, 'file') && ~exist(what, 'dir')) || exist(what, 'builtin') - if (exist(['@' what], 'dir')) - % special case, e.g., @logical is class, logical is builtin - type = 'class'; + else + type = 'unknown'; + end + + %% Let's see if its a class by checking if methods returns + % What about classdef in oct file above? Should we do this even if + % type is 'octfile'? + if (strcmp (type, 'unknown')) + if (~ isempty (what) && strcmp (what(1), '@')) + temp = what(2:end); else - type = 'function'; + temp = what; end - elseif (strcmp(what(1), '@')) - % comes after 'file' above for "doctest @class/method" - type = 'class'; - elseif (exist(what, 'dir')) - type = 'dir'; - elseif exist(what) == 2 || exist(what) == 103 - % Notes: - % * exist('@class', 'dir') only works if pwd is the parent of - % '@class', having it in the path is not sufficient. - % * Return 2 on Octave 3.8 and 103 on Octave 4. - type = 'class'; - else - % classdef classes are not detected by any of the above try - temp = methods(what); + temp = methods(temp); type = 'class'; catch type = 'unknown'; end end + + if (strcmp (type, 'unknown')) + if (exist(what, 'dir')) + type = 'dir'; + elseif (exist(what, 'file') || exist(what, 'builtin')) + type = 'function'; + else + type = 'unknown'; + end + end else % Matlab if (strcmp(what(1), '@')) && ~isempty(methods(what(2:end))) % covers "doctest @class", but not "doctest @class/method" diff --git a/test/bist.m b/test/bist.m index ac3c8a6..cfc0d3e 100644 --- a/test/bist.m +++ b/test/bist.m @@ -15,11 +15,9 @@ function bist() %!assert (~ doctest ('there_is_no_such_file', '-quiet')) -%!assert (~ doctest ({'doctest', 'there_is_no_such_file'}, '-quiet')) +%!assert (~ doctest ('@there_is_no_such_class', '-quiet')) -%!error -%! % TODO: maybe this should be EXTRACTION_ERROR, not raise an error... -%! doctest @there_is_no_such_class -quiet +%!assert (~ doctest ({'doctest', 'there_is_no_such_file'}, '-quiet')) %!test %! [n, t] = doctest ('doctest', '-quiet'); @@ -67,8 +65,7 @@ function bist() %! assert (nump == 5 && numt == 5) %! assert (summ.num_targets == 4) -%!xtest -%! % Currently cannot even run +%!test %! % https://github.com/catch22/octave-doctest/issues/199 %! [nump, numt, summ] = doctest ('@classdef_infile/disp'); %! assert (nump >= 0) @@ -88,7 +85,7 @@ function bist() %! assert (nump == 4 && numt == 4) %! assert (summ.num_targets == 3) -%!xtest +%!test %! % monkey-patching methods to existing builtin-objects %! [nump, numt, summ1] = doctest ('logical'); %! % First, there is (at least) the "logical" builtin