classdef objcmp_test < genlib_test
  % Test class for objcmp 
  %
  % [+GenLib General Purpose Library+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved.
  
  methods(Test)
    function test_structcmp(testCase)
      
      fprintf('\nRunning structcmp tests\n\n')
      
      % Define starting point
      S1 = struct('a',1,'b',[1 2],'l',[true,false],'S',struct('s1',1),'t',true,'C',{{1,2}},...
        'char','mychar','myint',int8([1,1]));
      
      % Check equal case
      S2 = S1;
      areequal=structcmp(S1,S2);
      testCase.verifyTrue(areequal);
      
      % Change a value
      S3 = S1; S3.a = 2;
      areequal=structcmp(S1,S3);
      testCase.verifyFalse(areequal);
      
      % add a field
      S4 = S1; S4.c = 2;
      areequal=structcmp(S1,S4);
      testCase.verifyFalse(areequal);
      % Check that ignoring field restores equality
      areequal=structcmp(S1,S4,0,{'c'});
      testCase.verifyTrue(areequal);
      
      % change a cell size
      S5 = S1; S5.C = {1,3,3};
      areequal=structcmp(S1,S5);
      testCase.verifyFalse(areequal);
      
      % change a subfield value
      S5 = S1; S5.S.s1 = 2;
      areequal=structcmp(S1,S5);
      testCase.verifyFalse(areequal);
      % Check that ignoring field restores equality
      areequal=structcmp(S1,S5,0,{'S'});
      testCase.verifyTrue(areequal);
      
      % change add a char
      S6 = S1; S6.char = 'mychab';
      areequal=structcmp(S1,S6);
      testCase.verifyFalse(areequal);
      
      % change value less than tolerance
      S7 = S1; tol=1e-5; S7.a = S1.a-0.1*tol; 
      areequal=structcmp(S1,S7,tol);
      testCase.verifyTrue(areequal==true);
      
      % check value change
      S8 = S1; S8.a = S1.a-1; % change value a lot
      areequal=structcmp(S1,S8,inf);
      testCase.verifyTrue(areequal==true);
      
      % check empty
      S9.A = S1; S10 = S9; S10.A.new=[];
      areequal=structcmp(S9,S10);
      testCase.verifyFalse(areequal);
      
      % check another empty
      S9.A.another = [];
      areequal=structcmp(S9,S10);
      testCase.verifyFalse(areequal);

      % check NaN treatment with non-zero tolerance
      tol = 1e-6;
      S11 = S1; S12 = S1;
      S11.a = [NaN;1]; S12.a = [NaN;1+tol/10];
      areequal=structcmp(S11,S12,tol);
      testCase.verifyTrue(areequal);
      
      % Test structcmp throws expected error
      ahandle = @(a) a+1;
      testCase.verifyError(@() structcmp(S9,ahandle),'GENLIB:STRUCTCMP:NOTSTRUCTURES');
    end
    
    function test_objcmp(testCase)
      %%
      S1.func = @(a,b,c) a+b+c; % anonymous function
      [S10,S11] = deal(S1);
      testCase.verifyTrue(objcmp(S1,S10));
      
      S11.func = @(b,c,a) a+b+c;  % different handles
      testCase.verifyFalse(objcmp(S1,S11));
    end
  end
end
