MatrixBerryCore
StructDispTC.m
Go to the documentation of this file.
1 classdef StructDispTC < mxberry.unittest.TestCase
2  properties (Access=private)
3  testDataRootDir
4  resTmpDir
5  end
6  methods
7  function self = StructDispTC(varargin)
8  self = self@mxberry.unittest.TestCase(varargin{:});
9  [~,className]=mxberry.core.getcallernameext(1);
10  shortClassName=mfilename('classname');
11  self.testDataRootDir=[fileparts(which(className)),...
12  filesep,'TestData',filesep,shortClassName];
13  end
14  end
15  methods (TestMethodSetup)
16  function self = set_up(self)
17  self.resTmpDir=mxberry.test.TmpDataManager.getDirByCallerKey();
18  end
19  end
20  methods (TestMethodTeardown)
21  function self = tear_down(self)
22  mxberry.io.rmdir(self.resTmpDir,'s');
23  end
24  end
25  methods (Test)
26  %
27  function self = test_strucdisp(self)
28  import mxberry.core.struct.strucdisp;
29  S.name='';
30  S.description=[]; %#ok<STRNU>
31  %
32  res=evalc('strucdisp(S)');
33  ind=strfind(res,'name');
34  self.verifyEqual(1,numel(ind));
35  ind=strfind(res,'description');
36  self.verifyEqual(1,numel(ind));
37  end
38  function testStruct2Str(self)
39  import mxberry.core.struct.strucdisp;
40  S.alpha=1;
41  S.beta=2;
42  S.gamma.alpha=1;
43  S.gamma.beta=2;
44  resStr=strucdisp(S);
45  resStr2=mxberry.core.struct.struct2str(S);
46  self.verifyEqual(true,isequal(resStr,resStr2));
47  end
48  function testStrucDispSimpleRegress(self)
49  import mxberry.core.struct.strucdisp;
50  S.alpha=1;
51  S.beta=2;
52  S.gamma.alpha=1;
53  S.gamma.beta=2;
54  expList={'| ';...
55  '|--- gamma';...
56  '| | ';...
57  '| |-- alpha : 1';...
58  '| |--- beta : 2';...
59  '| O';...
60  '| ';...
61  '|-- alpha : 1';...
62  '|--- beta : 2'};
63  check(S,expList);
64  function check(S,expList)
65  import mxberry.core.struct.strucdisp;
66  inpArgList={S,'depth',2,'printValues',true};
67  resStr=evalc('mxberry.core.struct.strucdisp(inpArgList{:})');
68  resStr2=strucdisp(inpArgList{:});
69  self.verifyEqual(true,isequal(resStr,resStr2));
70  resList=textscan(resStr,'%s','delimiter','\n');
71  resList=resList{1};
72  self.verifyEqual(true,isequal(resList,expList));
73  end
74  end
75  function testStrucDispRegress(self)
76  ARG_COMB_LIST={...
77  {'depth',100,'printValues',false,'maxArrayLength',100},...
78  {'depth',100,'printValues',true,'maxArrayLength',100},...
79  {'depth',2,'printValues',true},...
80  {'depth',100,'printValues',true},...
81  {'depth',100,'printValues',false}};
82  %
83  methodName=mxberry.core.getcallernameext(1);
84  inpFileName=[self.testDataRootDir,filesep,[methodName,'_inp.mat']];
85 
86  resMap=mxberry.core.cont.ondisk.HashMapMatXML(...
87  'storageLocationRoot',self.testDataRootDir,...
88  'storageBranchKey',[methodName,'_out'],'storageFormat','mat',...
89  'useHashedPath',false,'useHashedKeys',true);
90  SData=load(inpFileName);
91  structNameList=fieldnames(SData);
92  nFields=length(structNameList);
93  nArgCombs=length(ARG_COMB_LIST);
94  %
95  %resTmpDir=self.resTmpDir;
96  %resFileName=[resTmpDir,filesep,'out.txt'];
97  for iField=1:nFields
98  structName=structNameList{iField};
99  S=SData.(structName);
100  for iArgComb=1:nArgCombs
101  inpArgList=ARG_COMB_LIST{iArgComb};
102  resStr=evalc('mxberry.core.struct.strucdisp(S,inpArgList{:})');
103  inpKey=mxberry.core.hash({S,inpArgList});
104  SRes.S=S;
105  SRes.inpArgList=inpArgList;
106  SRes.resStr=resStr;
107  %
108  %resMap.put(inpKey,SRes);
109  SExpRes=resMap.get(inpKey);
110  [isPos,reportStr]=...
111  mxberry.core.struct.structcompare(SRes,SExpRes);
112  self.verifyEqual(true,isPos,reportStr);
113  end
114  end
115  %
116  end
117  function testGetLeaveList(self)
118  Data=mxberry.core.genteststruct(0);
119  check();
120  Data=struct();
121  Data.alpha(2,1).a=2;
122  Data.alpha(2,4).a=6;
123  check();
124  Data=struct();
125  Data.alpha(1).a=2;
126  Data.alpha(4).a=6;
127  check();
128  Data=struct();
129  Data.alpha(2,1,5).a=2;
130  Data.alpha(2,4,4).a=6;
131  %
132  check();
133  function SRes=check()
134  SRes=checkGetField();
135  compare();
136  SRes=checkValue();
137  compare();
138  %
139  function compare()
140  [isEqual,reportStr]=mxberry.core.struct.structcompare(SRes,Data);
141  self.verifyEqual(true,isEqual,reportStr);
142  self.verifyEqual(true,isequaln(SRes,Data));
143  end
144  function SRes=checkValue()
145  [pathSpecList,valList]=mxberry.core.struct.getleavelist(Data);
146  nPaths=numel(pathSpecList);
147  SRes=struct();
148  for iPath=1:nPaths
149  SRes=setfield(SRes,pathSpecList{iPath}{:},...
150  valList{iPath});
151  end
152  end
153  function SRes=checkGetField()
154  pathSpecList=mxberry.core.struct.getleavelist(Data);
155  nPaths=numel(pathSpecList);
156  SRes=struct();
157  for iPath=1:nPaths
158  SRes=setfield(SRes,pathSpecList{iPath}{:},...
159  getfield(Data,pathSpecList{iPath}{:}));
160  end
161  end
162  end
163  end
164  function test_updateLeaves(self)
165  import mxberry.core.struct.updateleavesext;
166  SData.a.b=1;
167  SRes=updateleavesext(SData,@fTransform);
168  %
169  SExp.a.bb=1;
170  self.verifyEqual(true,isequal(SRes,SExp));
171  %
172  function [val,path]=fTransform(val,path)
173  path{4}=repmat(path{4},1,2);
174  end
175  end
176  function testGetUpdateLeaves(self)
177  checkPathList(mxberry.core.struct.getleavelist(struct()));
178  %
179  SData.a.b=1;
180  SData.a.c=20;
181  SData.b.a.d=1;
182  SData.c=10;
183  SData.d='c';
184  SData.alpha.beta.gamma.theta=2;
185  SData.alpha.beta.gamma.delta='vega';
186  SData.alpha.beta.gamma.delta2=1;
187  %
188  check();
189  SData=struct();
190  check();
191  SData=mxberry.core.genteststruct(0);
192  check();
193  function check()
194  SRes=mxberry.core.struct.updateleaves(SData,@(x,y)x);
195  self.verifyEqual(true,...
196  isequaln(SData,SRes));
197  SRes=mxberry.core.struct.updateleaves(SData,@fMinus);
198  SRes=mxberry.core.struct.updateleaves(SRes,@fMinus);
199  self.verifyEqual(true,...
200  isequaln(SData,SRes));
201  %
202  pathExpList=mxberry.core.struct.getleavelist(SData);
203  pathList={};
204  %
205  mxberry.core.struct.updateleaves(SRes,@storePath);
206  self.verifyEqual(true,isequal(pathList,pathExpList));
207  %
208  function value=storePath(value,subFieldNameList)
209  pathList=[pathList;{subFieldNameList}];
210  end
211  function x=fMinus(x,~)
212  if isnumeric(x)
213  x=-x;
214  end
215  end
216  end
217  function checkPathList(pathList)
218  import mxberry.core.check.lib.iscellofstring;
219  self.verifyEqual(true,iscell(pathList));
220  if ~isempty(pathList)
221  self.verifyEqual(true,...
222  all(cellfun('isclass',pathList,'cell')));
223  self.verifyEqual(true,...
224  iscellofstring([pathList{:}]));
225  end
226  end
227  end
228 
229  function self = testArrays(self)
230  import mxberry.core.struct.strucdisp;
231  S = struct('a', 1);
232  str = evalc('strucdisp(S)');
233  isOk = ~isempty(strfind(str, '1'));
234 
235  S = struct('a', [1 2 3]);
236  str = evalc('strucdisp(S)');
237  isOk = isOk & ~isempty(strfind(str, '[1 2 3]'));
238 
239  S = struct('a', ones(5, 3, 2));
240  str = evalc('strucdisp(S)');
241  isOk = isOk & ~isempty(strfind(str, '[5x3x2 Array]'));
242 
243  self.verifyEqual(isOk, true);
244  end
245  %
246  function self = testLogicalFields(self)
247  import mxberry.core.struct.strucdisp;
248  S = struct('a', false(1, 2));
249  str = evalc('strucdisp(S)');
250  isOk = ~isempty(strfind(str, '[false false]'));
251 
252  S = struct('a', false);
253  str = evalc('strucdisp(S)');
254  isOk = isOk & ~isempty(strfind(str, 'false'));
255 
256  S = struct('a', false(5));
257  str = evalc('strucdisp(S)');
258  isOk = isOk & ~isempty(strfind(str, '[5x5 Logic array]'));
259 
260  self.verifyEqual(isOk, true);
261  end
262 
263  function self = testUpdateRegress(self)
264  import mxberry.core.struct.strucdisp;
265  ARG_COMB_LIST={...
266  {'depth',100,'printValues',false,'maxArrayLength',100},...
267  {'depth',100,'printValues',true,'maxArrayLength',100},...
268  {'depth',2,'printValues',true},...
269  {'depth',100,'printValues',true},...
270  {'depth',100,'printValues',false}};
271  %
272  methodName=mxberry.core.getcallernameext(1);
273 
274  inpResMap=mxberry.core.cont.ondisk.HashMapMatXML(...
275  'storageLocationRoot',self.testDataRootDir,...
276  'storageBranchKey',[methodName '_inp'],'storageFormat','mat',...
277  'useHashedPath',false,'useHashedKeys',true);
278  outResMap=mxberry.core.cont.ondisk.HashMapMatXML(...
279  'storageLocationRoot',self.testDataRootDir,...
280  'storageBranchKey',[methodName '_out'],'storageFormat','mat',...
281  'useHashedPath',false,'useHashedKeys',true);
282  nArgCombs=length(ARG_COMB_LIST);
283  %
284  keyList=inpResMap.getKeyList();
285  nKeys=numel(keyList);
286  for iKey=1:nKeys
287  keyName=keyList{iKey};
288  SDataVec=inpResMap.get(keyName);
289  for iArgComb=1:nArgCombs
290  inpArgList=ARG_COMB_LIST{iArgComb};
291  nElems=numel(SDataVec);
292  stDispObj=mxberry.core.struct.StructDisp(SDataVec(1),...
293  inpArgList{:});
294  for iElem=1:nElems
295  if iElem==1
296  rowIndVec=nan(0,1);
297  colIndVec=nan(0,1);
298  else
299  [rowIndVec,colIndVec]=...
300  stDispObj.update(SDataVec(iElem));
301  end
302  resStr=char(stDispObj);
303  SRes=struct(...
304  'S',{SDataVec(iElem)},...
305  'inpArgList',{inpArgList},...
306  'rowIndVec',{rowIndVec},...
307  'colIndVec',{colIndVec},...
308  'resStr',{resStr});
309  self.verifyEqual(true,isequal(resStr,...
310  strucdisp(SDataVec(iElem),inpArgList{:})));
311  inpKey=mxberry.core.hash({SDataVec(iElem),...
312  inpArgList});
313  %
314  SExpRes=outResMap.get(inpKey);
315  if isunix()&&(iKey==3)
316  %different behavior on Linux
317  SExpRes.resStr=strrep(SExpRes.resStr,...
318  '-1430.13','-1430.12');
319  SExpRes.resStr=strrep(SExpRes.resStr,...
320  '-3102.63','-3102.62');
321  end
322  [isPos,reportStr]=...
323  mxberry.core.struct.structcompare(SRes,SExpRes);
324  self.verifyEqual(true,isPos,reportStr);
325  end
326  end
327  end
328  %
329  end
330  end
331 end
function updateleavesext(in SData, in fUpdateFunc)
UPDATELEAVESEXT applies the specified function to each structure leave value and returns the updated ...
function filesep()
function struct2str(in SInp, in varargin)
STRUCDISP display structure outline.
function getleavelist(in SInp)
GETLEAVELIST generates a list of structure leave paths.
function genteststruct(in inpNum)
function repmat(in inpArray, in varargin)
This class is responsible for displaying structure outline.
Definition: StructDisp.m:4
function iscellofstring(in inpArray)
function rmdir(in dirName, in sFlag)
RMDIR removes a directory (optionally recursively)
function strucdisp(in varargin)
STRUCDISP display structure outline.
function structcompare(in SX, in SY, in absTol, in relTol)
STRUCTCOMPARE compares two structures using the specified tolerance.
function updateleaves(in SData, in fUpdateFunc)
UPDATELEAVES applies the specified function to each structure leave value and returns the updated str...