-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Find tests in .oct files #179
Conversation
@mtmiller This seems to work. I have not added tests because I don't think we want compiled code in this project. Re: mex files: At least in Matlab, I think they are documented in a separate m-file (https://www.mathworks.com/help/matlab/matlab_external/using-help-files-with-mex-files.html). I believe that would work with this fix, but have not tested. |
"help meh.oct" doesn't work so strip the ".oct" if specified. This makes `doctest .` work. If both meh.oct and meh.m are present, "help meh" will get the .oct file; this does the same. `doctest meh.m` will explicitly test the .m file. This may work for mex files although I haven't tested that. Fixes #178.
74197e5
to
d1e4466
Compare
Yeah, works for me with my limited testing of directories of oct files. This doesn't fix all of #178, though. It should also be possible to get a list of secondary functions defined in an oct file that has multiple DEFUNs, each with their own doc strings. |
`doctest foo.oct` will test the function `foo` itself as well as any other functions defined in `foo.oct` and exposted in the autoload map. On the other hand, `doctest foo` will test only the function `foo`. Fixes #178.
type = 'octfile'; | ||
elseif (exist (what) == 3) % .oct/.mex | ||
[~, what, ~] = fileparts (what); % strip extension if present | ||
type = 'function'; % then access like any function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block (% .oct/.mex
) matches:
doctest foo
(rather thandoctest foo.oct
). I don't think its necessary for this (a later block will DTRT) but it doesn't hurt, and maybe makes clearer the expected difference betweendoctest foo.oct
anddoctest foo
.doctest bar.mex
anddoctest bar
: I haven't tested any .mex stuff yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I like this distinction between doctest func
and doctest func.oct
. I didn't see a clean way to do it when I was making my changes.
@mtmiller what do you think? I wonder if we should make some test cases for this: they could be optional and not part of the usual test run (as they need to be compiled) but they'd be there to help anyone refactoring this code in the future. |
I agree that it would be good to have test cases that are run as part of the test suite on Travis, especially since the rules regarding which tests are picked up (and in which order) seem to be a bit subtle from what I understand. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I think this is a much better approach than my recursive hack.
I think we can further improve it to also allow doctesting a .oct file anywhere in the load path, either like doctest foo.oct
or doctest /path/to/foo.oct
.
Thanks for working on this!
type = 'octfile'; | ||
elseif (exist (what) == 3) % .oct/.mex | ||
[~, what, ~] = fileparts (what); % strip extension if present | ||
type = 'function'; % then access like any function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I like this distinction between doctest func
and doctest func.oct
. I didn't see a clean way to do it when I was making my changes.
@@ -135,6 +141,8 @@ | |||
targets = [target]; | |||
elseif strcmp(type, 'class') | |||
targets = collect_targets_class(what, depth); | |||
elseif strcmp (type, 'octfile') | |||
targets = collect_targets_octfile (what, depth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is way nicer than my recursive approach. I didn't read enough of the code to see how to build up the targets list, I just saw the way directories were handled and followed that logic. I like this a lot.
inst/private/doctest_collect.m
Outdated
targets = [target]; | ||
|
||
% octfile may have many fcns in it: find them using the autoload map | ||
A = fullfile (pwd, file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works in the limited case where foo.oct
is in the current working directory. IOW, exactly when it was called from doctest somedir
and doctest
already did a chdir
. What if we use which
or file_in_loadpath
to get the full file name of [basename '.oct']
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just use the match-only-the-filename approach from your PR? Maybe that's good enough for now. Do you think many people have a generic utils.oct
or similar lying around if different directories?
There is some overlap here with the discussion in #87 about classes and whether only "locally" defined methods should be tested or all methods (such as those from superclasses defined elsewhere).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably good enough for a start if you'd rather stay simple and just use the basename. I really don't think non-developers have their own personal .oct files floating around. The much more likely case of the same .oct file is multiple copies in different directories, maybe with a pkg load
and with a manual addpath
, which should be ok.
I searched the entire Debian archive for any files ending with .oct, and I found 226 unique file names, no duplicates, which doesn't say anything about third-party or personal projects, but at least no well-known projects are using names like common.oct
or main.oct
.
I = find (strcmp (files, A)); | ||
if (~ isempty (I)) | ||
% indicate that octfile has other fcns, and indent those targets | ||
targets(1).name = [targets(1).name ':']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, I like the idea of labeling the function with its .oct file.
User could be testing any .oct file in the load path, so remove pwd.
Hey, sorry if you were waiting on me. This fell off my radar, but looks good to me. |
Fell off mine too, I'll merge this for now. Testing of this is the other PR, still not sure about how we want organize that, esp. for packagers. |
"help meh.oct" doesn't work so strip the ".oct" if specified. This
makes
doctest .
work. If both meh.oct and meh.m are present,"help meh" will get the .oct file; this does the same.
doctest meh.m
will explicitly test the .m file. This may work for mex files although
I haven't tested that.