--- tests_orig.tst 2015-11-13 21:18:10.140916799 +1100 +++ tests_new.tst 2015-11-13 21:19:56.339169116 +1100 @@ -1,101 +1,118 @@ %!test %! b = [10:10:100]; %! b = [b; 8*b/5]; %! str = sprintf ("%g miles/hr = %g kilometers/hr\n", b); %! fmt = "%f miles/hr = %f kilometers/hr"; %! c = textscan (str, fmt); -%! assert (b(1,:)', c{1}, 1e-5); -%! assert (b(2,:)', c{2}, 1e-5); +%! assert (c{1}, b(1,:)', 1e-5); +%! assert (c{2}, b(2,:)', 1e-5); +### Get "observed" and "expected" the right way around %!test -%! str = "13, 72, NA, str1, 25\r\n// Middle line\r\n36, na, 05, str3, 6"; -%! a = textscan (str, "%d %n %f %s %n", "delimiter", ",","treatAsEmpty", {"NA", "na"},"commentStyle", "//"); +%! str = "13, -, NA, str1, -25\r\n// Middle line\r\n36, na, 05, str3, 6"; +%! a = textscan (str, "%d %n %f %s %n", "delimiter", ",", +%! "treatAsEmpty", {"NA", "na", "-"},"commentStyle", "//"); %! assert (a{1}, int32 ([13; 36])); -%! assert (a{2}, [72; NaN]); +%! assert (a{2}, [NaN; NaN]); %! assert (a{3}, [NaN; 5]); %! assert (a{4}, {"str1"; "str3"}); -%! assert (a{5}, [25; 6]); +%! assert (a{5}, [-25; 6]); +### Extra test: treat-as-empty a valid prefix to a number -%!test -%! ## No delimiters at all besides EOL. Skip fields, even empty fields -%! str = "Text1Text2Text\nTextText4Text\nText57Text"; -%! c = textscan (str, "Text%*dText%dText"); -%! assert (c{1}, int32 ([2; 4; 0])); +#%!test +#%! ## No delimiters at all besides EOL. Skip fields, even empty fields +#%! str = "Text1Text2Text\nTextText4Text\nText57Text"; +#%! c = textscan (str, "Text%*dText%dText"); +#%! assert (c{1}, int32 ([2; 4; 0])); +### A literal after a conversion is not a delimiter. We now have multi-char delims ## Test input validation -%!error textscan (single (4)) -%!error textscan ({4}) +%!error textscan (single (40)) +%!error textscan ({40}) +### I was getting false successes since file ID 4 was open ## Whitespace test (bug #37333) using delimiter ";" %!test %! tc = []; %! tc{1, 1} = "C:/code;"; %! tc{1, end+1} = "C:/code/meas;"; %! tc{1, end+1} = " C:/code/sim;"; %! tc{1, end+1} = "C:/code/utils;"; %! string = [tc{:}]; %! c = textscan (string, "%s", "delimiter", ";"); -%! for k = 1:numel (c{1}) +%! for k = 1:max (numel (c{1}), numel (tc)) %! lh = c{1}{k}; %! rh = tc{k}; %! rh(rh == ";") = ""; %! rh = strtrim (rh); %! assert (strcmp (lh, rh)); %! end +### The old test failed to complain of empty output ## Test reading from a real file %!test %! f = tempname (); %! fid = fopen (f, "w+"); %! d = rand (1, 4); -%! fprintf (fid, " %f %f %f %f ", d); +%! fprintf (fid, " %f %f /* comment */ %f %f ", d); %! fseek (fid, 0, "bof"); -%! A = textscan (fid, "%f %f"); +%! A = textscan (fid, "%f %f", "CommentStyle", {"/*", "*/"}); +%! E = feof (fid); %! fclose (fid); %! unlink (f); %! assert (A{1}, [d(1); d(3)], 1e-6); %! assert (A{2}, [d(2); d(4)], 1e-6); +%! assert (E); +### Additional testing: comments and correct reportinf of EOF %!test %! ## TreatAsEmpty %! C = textscan ("1,2,3,NN,5,6\n", "%d%d%d%f", "delimiter", ",", "TreatAsEmpty", "NN"); -%! assert (C{3}, int32 (3)); -%! assert (C{4}, NaN); +%! assert (C{3}(1), int32 (3)); +%! assert (C{4}(1), NaN); +### Matlab's dependence on whether the file ends with EOL is more bug than feature; +### my textscan always emits vectors of equal length ## Bug #42528 %!test %! assert (textscan ("1i", ""){1}, 0+1i); -%! assert (cell2mat (textscan ("3, 2-4i, NaN\n -i, 1, 23.4+2.2i", "")), [3+0i, 2-4i, NaN+0i; 0-i, 1+0i, 23.4+2.2i]); +%! assert (cell2mat (textscan ("3, 2-4i, NaN\n -i, 1, 23.4+2.2i\n 1+1 1+1j", "", "delimiter", ",")), [3+0i, 2-4i, NaN+0i; 0-i, 1+0i, 23.4+2.2i; 1 1 1+1i]); +### By default, ',' is not a delimiter (for Matlab compatibility) ## MultipleDelimsAsOne %!test %! str = "11, 12, 13,, 15\n21,, 23, 24, 25\n,, 33, 34, 35"; %! C = textscan (str, "%f %f %f %f", "delimiter", ",", "multipledelimsasone", 1, "endofline", "\n"); -%! assert (C{1}', [11, 21, NaN]); -%! assert (C{2}', [12, 23, 33]); -%! assert (C{3}', [13, 24, 34]); -%! assert (C{4}', [15, 25, 35]); - -## Allow cuddling %sliteral but warn it is ambiguous -%!test -%! C = textscan ("abcxyz51\nxyz83\n##xyz101", "%s xyz %d"); -%! assert (C{1}([1 3]), {"abc"; "##"}); -%! assert (isempty (C{1}{2}), true); -%! assert (C{2}, int32([51; 83; 101])); - -## Test for false positives in check for non-supported format specifiers -%!test -%! assert (textscan ("Total: 32.5 % (of cm values)", "Total: %f % (of cm values)"){1}, 32.5, 1e-5); +%! assert (C{1}', [11, 21, 33]); +%! assert (C{2}', [12, 23, 34]); +%! assert (C{3}', [13, 24, 35]); +%! assert (C{4}', [15, 25, NaN]); +### Matlab's MultipleDelimtersAsOne merges leading delimiters with newlines + +### Allow cuddling %sliteral but warn it is ambiguous +#%!test +#%! C = textscan ("abcxyz51\nxyz83\n##xyz101", "%s xyz %d"); +#%! assert (C{1}([1 3]), {"abc"; "##"}); +#%! assert (isempty (C{1}{2}), true); +#%! assert (C{2}, int32([51; 83; 101])); +### Literals are not delimiters. We now have multi-char delimiters + +### Test for false positives in check for non-supported format specifiers +#%!test +#%! assert (textscan ("Total: 32.5 % (of cm values)", "Total: %f %% (of cm values)"){1}, 32.5, 1e-5); +### Correctly gives error "'% ' is not a valid format specifier" for single %. ## Test various forms of string format specifiers (bug #45712) %!test %! str = "14 :1 z:2 z:3 z:5 z:11"; %! C = textscan (str, "%f %s %*s %3s %*3s %f", "delimiter", ":"); -%! assert ({a, b, c, d}, {14, {"1 z"}, {"3 z"}, 11}); +%! assert (C, {14, {"1 z"}, {"3 z"}, 11}); +### (Presumably output syntax of another function) -%% [..] and [^..] crossing delimiters +%% [..] and [^..] containing delimiters %!test %! cr = "ab cd efguv wx1Any\na ce gx yz2Trailing\n 3Junk"; %! C = textscan (cr, "%[ abcdefg] %*[^0123456789] %s", "delimiter", " \n", "whitespace", ""); -%! assert (C{1}, {"abcdefg"; "aceg"; ""}); +%! assert (C{1}, {"ab cd efg"; "a ce g"; " "}); %! assert (C{2}, {"1Any"; "2Trailing"; "3Junk"}); +### Implementation decision: all chars in [...] are "valid" characters