changeset 26759:ad71c8d87cff stable

Overhaul classdef tests (bug #54783, bug #54966, bug #55223). * test/classdef/classdef.tst: Make the test run under Matlab R2018b again. New tests for bug #54783 and bug #55223. New xtest for bug #54966. Fix spelling "correctly". * test/classdef/struct_wrapper.m: Convert unused function to constructor. Otherwise this function does not make sense, maybe forgotten to rename properly. * test/classdef/foo_subsref_subsasgn.m: New classdef test file . * test/classdef/module.mk: Add new classdef test file to build system. * test/bug-55223/*: Include tests to test/classdef. * test/module.mk: Remove test/bug-55223 from build system.
author Kai T. Ohlhus <k.ohlhus@gmail.com>
date Thu, 21 Feb 2019 14:53:30 +0100
parents 17d806c3f7cd
children c97a65af7c4b 8cfe07381fc0
files test/bug-55223/bug-55223.tst test/bug-55223/class_bug55223.m test/bug-55223/module.mk test/classdef/classdef.tst test/classdef/foo_subsref_subsasgn.m test/classdef/module.mk test/classdef/struct_wrapper.m test/module.mk
diffstat 8 files changed, 196 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/test/bug-55223/bug-55223.tst	Thu Feb 21 01:10:20 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-## Copyright (C) 2018 Sébastien Villemot <sebastien@debian.org>
-##
-## 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
-## <https://www.gnu.org/licenses/>.
-
-%!test <*55223>
-%! x = class_bug55223 ();
-%! x{2}(2) = 3;
-%! assert (x{2}(2), 3);
--- a/test/bug-55223/class_bug55223.m	Thu Feb 21 01:10:20 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-classdef class_bug55223<handle
-  properties
-    x
-  endproperties
-
-  methods
-    function obj = class_bug55223 ()
-      obj.x = eye (4);
-    endfunction
-
-    function val = subsref (obj, S)
-      if (length (S) == 2 && S(1).type == "{}" && S(2).type == "()")
-        val = obj.x(S(1).subs{1}, S(2).subs{1});
-      endif
-    endfunction
-
-    function obj = subsasgn (obj, S, val)
-      if (length (S) == 2 && S(1).type == "{}" && S(2).type == "()")
-        obj.x(S(1).subs{1}, S(2).subs{1}) = val;
-      endif
-    endfunction
-  endmethods
-endclassdef
--- a/test/bug-55223/module.mk	Thu Feb 21 01:10:20 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-bug_55223_TEST_FILES = \
-  %reldir%/bug-55223.tst \
-  %reldir%/class_bug55223.m
-
-TEST_FILES += $(bug_55223_TEST_FILES)
--- a/test/classdef/classdef.tst	Thu Feb 21 01:10:20 2019 -0500
+++ b/test/classdef/classdef.tst	Thu Feb 21 14:53:30 2019 +0100
@@ -23,7 +23,7 @@
 %%        in MATLAB to test compatibility.  Don't break that!
 %%
 %%  To Do:  This script tests to ensure that things done correctly work
-%%          corrrectly.  It should also check that things done incorrectly
+%%          correctly.  It should also check that things done incorrectly
 %%          error properly.
 %%
 %%  The classes used for the tests reside in the test/classdef with others
@@ -42,23 +42,23 @@
 %!assert (isempty (q.rate))
 %!assert (isempty (q.principle))
 %!assert (isempty (q.term))
-%!assert (class (p), "foo_value_class")
-%!assert (p.term, 48)
-%!assert (p.rate, 4.0)
-%!assert (p.principle, 50e3)
+%!assert (strcmp (class (p), 'foo_value_class'))
+%!assert (p.term == 48)
+%!assert (p.rate == 4.0)
+%!assert (p.principle == 50e3)
 %!assert (p.amount, amt, eps ())
 %!assert (amount (p), amt, eps ())
 %!xtest <53614>
 %! assert (properties (p), {'rate'; 'term'; 'principle'});
-%!test <42510>
+%!xtest <42510>
 %! assert (methods (p), {'amount'; 'foo_value_class'});
 %!assert (isempty (foo_value_class().rate))
 %!error <property `rate' is not constant> foo_value_class.rate
 
 %%  Static method and Constant Property
-%!assert (foo_static_method_constant_property.radians_per_cycle, 2*pi)
-%!assert (foo_static_method_constant_property().radians_per_cycle, 2*pi)
-%!assert (foo_static_method_constant_property().pie, pi)
+%!assert (foo_static_method_constant_property.radians_per_cycle == 2*pi)
+%!assert (foo_static_method_constant_property().radians_per_cycle == 2*pi)
+%!assert (foo_static_method_constant_property().pie == pi)
 %!error <property `frequency' is not constant> foo_static_method_constant_property.frequency
 %!error <method `cosine' is not static> foo_static_method_constant_property.cosine
 %!test
@@ -70,30 +70,118 @@
 %!test
 %! obj = foo_method_changes_property_size (3);
 %! obj = obj.move_element_to_end (2);
-%! assert (obj.element, [1 3 2]);
+%! assert (isequal (obj.element, [1 3 2]));
 
 %!error <parse error> plist_t1
-%!assert (class (plist_t2), "plist_t2")
-%!assert (class (plist_t3), "plist_t3")
+%!assert (strcmp (class (plist_t2), 'plist_t2'))
+%!assert (strcmp (class (plist_t3), 'plist_t3'))
 
 %!test
 %! obj = struct_wrapper ();
 %! obj{'a'} = 1;
-%! assert (obj{'a'}, 1);
+%! assert (obj{'a'} == 1);
 %! obj{'bc'} = 2;
-%! assert (obj{'bc'}, 2);
-%! assert (obj{'a', 'bc'}, [ 1 2 ]);
+%! assert (obj{'bc'} == 2);
+%! assert (isequal (obj{'a', 'bc'}, [1 2]));
 
 %% Test for meta.class.fromName
 %!test <*51935>
 %! meta.class.fromName ("inputParser");
 
-## Do not change this to "containers.Map()".  This test is intended to
-## ensure that calling a function in a +package directory will work
-## properly.
+%% Do not change this to "containers.Map()".  This test is intended to
+%% ensure that calling a function in a +package directory will work
+%% properly.
 %!test <*51715>
 %! x = containers.Map;
 %! assert (isobject (x));
 
 %!assert <*52096> (isempty (meta.class.fromName ("__nonexi$tent_cl@$$__")))
 %!assert <*52096> (isempty (meta.package.fromName ("__nonexi$tent_p@ck@ge__")))
+
+%% Test overloaded subsref and subsasgn functions.
+%% (bug #54783, bug #54966, and bug #55223)
+%!test <*54783>
+%! obj = foo_subsref_subsasgn (1);
+%! obj(2) = 3;
+%! assert (obj(2) == 3)
+%! assert (obj{2} == 3)
+%! assert (isequal (obj.x, [1 3 3 4]))
+%! obj{2} = 4;
+%! assert (obj(2) == 4)
+%! assert (obj{2} == 4)
+%! assert (isequal (obj.x, [1 4 3 4]))
+%! obj(end) = 6;
+%! assert (obj(end) == 6)
+%! assert (obj{end} == 6)
+%! assert (isequal (obj.x, [1 4 3 6]))
+%! obj{end} = 8;
+%! assert (obj(end) == 8)
+%! assert (obj{end} == 8)
+%! assert (isequal (obj.x, [1 4 3 8]))
+%! obj.x = 1:4;
+%! assert (isequal (obj.x, 1:4))
+%! obj(1:3) = 7:9;
+%! assert (isequal (obj(1:3), 7:9))
+%! assert (isequal (obj.x, [7 8 9 4]))
+%! obj(2:end) = 5:7;
+%! assert (isequal (obj(2:end), 5:7))
+%! assert (isequal (obj.x, [7 5 6 7]))
+
+%!xtest <54966>
+%! obj = foo_subsref_subsasgn (1);
+%! obj{1:3} = 5:7;
+%! assert (isequal ([obj{1:3}], 5:7))
+%! assert (isequal (obj.x, [5 6 7 4]))
+%! obj{2:end} = 7:9;
+%! assert (isequal ([obj{2:end}], 7:9))
+%! assert (isequal (obj.x, [5 7 8 9]))
+
+%!test <*54783>
+%! obj = foo_subsref_subsasgn (1);
+%! obj.x(2) = 3;
+%! assert (obj.x(2) == 3)
+%! assert (obj.x{2} == 3)
+%! assert (isequal (obj.x, [1 3 3 4]))
+%! obj.x{2} = 4;
+%! assert (obj.x(2) == 4)
+%! assert (obj.x{2} == 4)
+%! assert (isequal (obj.x, [1 4 3 4]))
+%! obj.x(end) = 6;
+%! assert (obj.x(end) == 6)
+%! assert (obj.x{end} == 6)
+%! assert (isequal (obj.x, [1 4 3 6]))
+%! obj.x{end} = 8;
+%! assert (obj.x(end) == 8)
+%! assert (obj.x{end} == 8)
+%! assert (isequal (obj.x, [1 4 3 8]))
+%! obj.x = 1:4;
+%! assert (isequal (obj.x, 1:4))
+%! obj.x(1:3) = 7:9;
+%! assert (isequal (obj.x(1:3), 7:9))
+%! assert (isequal (obj.x, [7 8 9 4]))
+%! obj.x(2:end) = 5:7;
+%! assert (isequal (obj.x(2:end), 5:7))
+%! assert (isequal (obj.x, [7 5 6 7]))
+
+%!xtest <54966>
+%! obj = foo_subsref_subsasgn (1);
+%! obj.x{1:3} = 5:7;
+%! assert (isequal ([obj.x{1:3}], 5:7))
+%! assert (isequal (obj.x, [5 6 7 4]))
+%! obj.x{2:end} = 7:9;
+%! assert (isequal ([obj.x{2:end}], 7:9))
+%! assert (isequal (obj.x, [5 7 8 9]))
+
+%!test <*55223>
+%! obj = foo_subsref_subsasgn (2);
+%! obj{2}(2) = 3;
+%! assert (obj{2}(2) == 3);
+%! obj{2}{2} = 4;
+%! assert (obj{2}{2} == 4);
+
+%!xtest <54966>
+%! obj = foo_subsref_subsasgn (2);
+%! obj{1:2}(1:2) = ones (2);
+%! assert (isequal (obj{1:2}(1:2), ones (2)));
+%! obj{3:4}(3:4) = 4 * ones (2);
+%! assert (isequal (obj{3:4}(3:4), 4 * ones (2)));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/foo_subsref_subsasgn.m	Thu Feb 21 14:53:30 2019 +0100
@@ -0,0 +1,88 @@
+classdef foo_subsref_subsasgn < handle
+  properties
+    x
+  end
+
+  methods
+    function obj = foo_subsref_subsasgn (dims)
+      switch (dims)
+        case 1
+          obj.x = 1:4;
+        case 2
+          obj.x = eye (4);
+        otherwise
+          error ('foo_subsref_subsasgn:SyntaxError', ...
+            'foo_subsref_subsasgn: Invalid syntax');
+      end
+    end
+
+    function ind = end (obj, k, n)
+      sz = size (obj.x);
+      if k < n
+        ind = sz(k);
+      else
+        ind = prod (sz(k:end));
+      end
+    end
+
+    function varargout = subsref (obj, S)
+      switch (length (S))
+        case 1
+          if (S(1).type == "()")
+            varargout = {obj.x(S(1).subs{1})};
+          elseif (S(1).type == "{}")
+            % Note in ML R2018b "x{1:3}" expects "nargout == 3".
+            varargout = num2cell (obj.x(S(1).subs{1}));
+          elseif (S(1).type == "." && S(1).subs == 'x')
+            varargout = {obj.x};
+          else
+            error ('foo_subsref_subsasgn:SyntaxError', ...
+              'foo_subsref_subsasgn: Invalid syntax');
+          end
+        case 2
+          % Note in ML R2018b "x(1)(1)" is not allowed.
+          if (S(1).type == "{}" && (S(2).type == "{}" || S(2).type == "()"))
+            varargout = {obj.x(S(1).subs{1}, S(2).subs{1})};
+          elseif (S(1).type == "." && S(1).subs == 'x' ...
+              && (S(2).type == "{}" || S(2).type == "()"))
+            varargout = {obj.x(S(2).subs{1})};
+          else
+            error ('foo_subsref_subsasgn:SyntaxError', ...
+              'foo_subsref_subsasgn: Invalid syntax');
+          end
+        otherwise
+          error ('foo_subsref_subsasgn:SyntaxError', ...
+            'foo_subsref_subsasgn: Invalid syntax');
+      end
+    end
+
+    function obj = subsasgn (obj, S, varargin)
+      switch (length (S))
+        case 1
+          if (S(1).type == "{}" || S(1).type == "()")
+            obj.x(S(1).subs{1}) = varargin{1};
+          elseif (S(1).type == "." && S(1).subs == 'x')
+            obj.x = varargin{1};
+          else
+            error ('foo_subsref_subsasgn:SyntaxError', ...
+              'foo_subsref_subsasgn: Invalid syntax');
+          end
+        case 2
+          % Note in ML R2018b "x(1)(1)" is not allowed.
+          if (S(1).type == "{}" && (S(2).type == "{}" || S(2).type == "()"))
+            obj.x(S(1).subs{1}, S(2).subs{1}) = varargin{1};
+          elseif (S(1).type == "." && S(1).subs == 'x' ...
+              && (S(2).type == "{}" || S(2).type == "()"))
+            obj.x(S(2).subs{1}) = varargin{1};
+          else
+            error ('foo_subsref_subsasgn:SyntaxError', ...
+              'foo_subsref_subsasgn: Invalid syntax');
+          end
+        otherwise
+          error ('foo_subsref_subsasgn:SyntaxError', ...
+            'foo_subsref_subsasgn: Invalid syntax');
+      end
+    end
+
+  end
+end
--- a/test/classdef/module.mk	Thu Feb 21 01:10:20 2019 -0500
+++ b/test/classdef/module.mk	Thu Feb 21 14:53:30 2019 +0100
@@ -2,6 +2,7 @@
   %reldir%/classdef.tst \
   %reldir%/foo_method_changes_property_size.m \
   %reldir%/foo_static_method_constant_property.m \
+  %reldir%/foo_subsref_subsasgn.m \
   %reldir%/foo_value_class.m \
   %reldir%/plist_t1.m \
   %reldir%/plist_t2.m \
--- a/test/classdef/struct_wrapper.m	Thu Feb 21 01:10:20 2019 -0500
+++ b/test/classdef/struct_wrapper.m	Thu Feb 21 14:53:30 2019 +0100
@@ -3,7 +3,7 @@
     s;
   end
   methods
-    function o = assigner ()
+    function o = struct_wrapper ()
       if (nargin == 0)
         o.s = struct ();
       else
--- a/test/module.mk	Thu Feb 21 01:10:20 2019 -0500
+++ b/test/module.mk	Thu Feb 21 14:53:30 2019 +0100
@@ -77,7 +77,6 @@
 include %reldir%/bug-53027/module.mk
 include %reldir%/bug-53468/module.mk
 include %reldir%/bug-54995/module.mk
-include %reldir%/bug-55223/module.mk
 include %reldir%/class-concat/module.mk
 include %reldir%/classdef/module.mk
 include %reldir%/classdef-multiple-inheritance/module.mk