Skip to content

Commit

Permalink
Add test for subclass of mp_table_subclass.
Browse files Browse the repository at this point in the history
Document limitation of table nesting due to Octave bug.
  • Loading branch information
rdzman committed Dec 23, 2023
1 parent dca9ec4 commit b00a426
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 33 deletions.
21 changes: 13 additions & 8 deletions lib/mp_table_subclass.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@
% The class of the contained table object is either :class:`table` or mp_table
% and is determined by mp_table_class.
%
% .. admonition:: Limitation
% .. admonition:: Limitations
%
% In MATLAB, when nesting an mp_table_subclass object within another
% mp_table_subclass object, one cannot use multi-level indexing directly.
% E.g. If ``T2`` is a variable in ``T1`` and ``x`` is a variable in ``T2``,
% attempting ``x = T1.T2.x`` will result in an error. The indexing must
% be done in multiple steps ``T2 = T1.T2; x = T2.x``. Note: This only
% applies to MATLAB, where the contained table is a :class:`table`. It works
% just fine in Octave, where the contained table is an :class:`mp_table`.
% 1. The Octave bug mentioned above also affects tables that inherit from
% mp_table_subclass. That is, such tables can be nested inside tables
% of type :class:`table` or mp_table, but not inside tables that are
% or inherit from mp_table_subclass.
% 2. In MATLAB, when nesting an mp_table_subclass object within another
% mp_table_subclass object, one cannot use multi-level indexing directly.
% E.g. If ``T2`` is a variable in ``T1`` and ``x`` is a variable in
% ``T2``, attempting ``x = T1.T2.x`` will result in an error. The
% indexing must be done in multiple steps ``T2 = T1.T2; x = T2.x``.
% Note: This only applies to MATLAB, where the contained table is a
% :class:`table`. It works just fine in Octave, where the contained
% table is an :class:`mp_table`.
%
% .. important::
%
Expand Down
16 changes: 16 additions & 0 deletions lib/t/mp_foo_table.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
classdef mp_foo_table < mp_table_subclass

% MATPOWER
% Copyright (c) 2023, Power Systems Engineering Research Center (PSERC)
% by Ray Zimmerman, PSERC Cornell
%
% This file is part of MATPOWER.
% Covered by the 3-clause BSD License (see LICENSE file for details).
% See https://matpower.org for more info.

methods
function obj = mp_foo_table(varargin)
obj@mp_table_subclass(varargin{:});
end
end %% methods
end %% classdef
59 changes: 34 additions & 25 deletions lib/t/t_mp_table.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
end

skip_tests_for_tablicious = 1;
table_classes = {@mp_table, @mp_table_subclass};
class_names = {'mp_table', 'mp_table_subclass'};
table_classes = {@mp_table, @mp_table_subclass, @mp_foo_table};
class_names = {'mp_table', 'mp_table_subclass', 'mp_foo_table'};
if have_feature('table')
table_classes = {@table, table_classes{:}};
class_names = {'table', class_names{:}};
Expand Down Expand Up @@ -71,8 +71,12 @@
t_is(size(T, 2), 6, 12, [t 'sz = size(T, 2)']);
[nr, nz] = size(T);
t_is([nr, nz], [6 6], 12, [t '[nr, nz] = size(T)']);
t_ok(isequal(T.Properties.VariableNames, ...
{'var1', 'var2', 'var3', 'var4', 'Var5', 'var6'}), [t 'VariableNames'] );
if isa(T, 'mp_foo_table')
t_skip(1, 'constructor does not capture var names');
else
t_ok(isequal(T.Properties.VariableNames, ...
{'var1', 'var2', 'var3', 'var4', 'Var5', 'var6'}), [t 'VariableNames'] );
end
t_ok(isempty(T.Properties.RowNames), [t 'RowNames'] );
t_ok(isequal(T.Properties.DimensionNames, {'Row', 'Variables'}), ...
[t 'DimensionNames'] );
Expand Down Expand Up @@ -548,31 +552,36 @@
for k2 = 1:nc
nested_table_class = table_classes{k2};
nstcls = upper(class_names{k2});

t = sprintf('%s . %s : nested tables : ', cls, nstcls);
T1 = nested_table_class([1;2;3],[4;5;6]);
T2 = nested_table_class({'one';'two';'three'},{'four';'five';'six'});
T3 = table_class([10;20;30],{'uno';'dos';'tres'}, T1, T2, ...
'VariableNames', {'v1', 'v2', 'T1', 'T2'});
t_ok(isequal(T3.T1, T1), [t 'T.T1 == T1']);
t_ok(isequal(T3.T2, T2), [t 'T.T2 == T2']);
if have_feature('matlab') && isa(T1, 'mp_table_subclass') && ...
isa(T3, 'mp_table_subclass')
t_skip(4, 'multiple indexing of nested mp_table_subclasses');
else
t_ok(isequal(T3.T1([1;3], :), T1([1;3], :)), [t 'T.T1(ii, :) == T1(ii, :)']);
t_ok(isequal(T3.T2([1;3], :), T2([1;3], :)), [t 'T.T2(ii, :) == T2(ii, :)']);
t_ok(isequal(T3.T1.Var1, T1.Var1), [t 'T.T1.Var1 == T1.Var1']);
t_ok(isequal(T3.T2.Var2([1;3], :), T2.Var2([1;3], :)), [t 'T.T2.Var2(ii) == T.T2.Var2(ii)']);
end
%% check for Octave trouble in subsref
if (skip_oct_tab && isa(T3, 'table')) || skip_oct_tab2
t_skip(2, 'mp_table_subclass does not handle this yet');
if have_feature('octave') && isa(T, 'mp_table_subclass') && ...
isa(T1, 'mp_foo_table')
t_skip(8, 'avoid https://savannah.gnu.org/bugs/index.php?65037');
else
T4 = T3(:, :);
T5 = T3([1;2;3], :);
t_ok(isequal(T3, T4), [t 'T == T(:, :))']);
t_ok(isequal(T3, T5), [t 'T == T(ii, :))']);
T3 = table_class([10;20;30],{'uno';'dos';'tres'}, T1, T2, ...
'VariableNames', {'v1', 'v2', 'T1', 'T2'});
t_ok(isequal(T3.T1, T1), [t 'T.T1 == T1']);
t_ok(isequal(T3.T2, T2), [t 'T.T2 == T2']);
if have_feature('matlab') && isa(T1, 'mp_table_subclass') && ...
isa(T3, 'mp_table_subclass')
t_skip(4, 'multiple indexing of nested mp_table_subclasses');
else
t_ok(isequal(T3.T1([1;3], :), T1([1;3], :)), [t 'T.T1(ii, :) == T1(ii, :)']);
t_ok(isequal(T3.T2([1;3], :), T2([1;3], :)), [t 'T.T2(ii, :) == T2(ii, :)']);
t_ok(isequal(T3.T1.Var1, T1.Var1), [t 'T.T1.Var1 == T1.Var1']);
t_ok(isequal(T3.T2.Var2([1;3], :), T2.Var2([1;3], :)), [t 'T.T2.Var2(ii) == T.T2.Var2(ii)']);
end
%% check for Octave trouble in subsref
if (skip_oct_tab && isa(T3, 'table')) || skip_oct_tab2
t_skip(2, 'mp_table_subclass does not handle this yet');
else
T4 = T3(:, :);
T5 = T3([1;2;3], :);
t_ok(isequal(T3, T4), [t 'T == T(:, :))']);
t_ok(isequal(T3, T5), [t 'T == T(ii, :))']);
end
end
end
end
Expand Down

0 comments on commit b00a426

Please sign in to comment.