function test_suite=test_align
% tests for cosmo_align
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_align_basics
    x=cosmo_synthetic_dataset('type','meeg','size','big');
    y=cosmo_slice(x,x.fa.chan<=6,2);
    orig_ds=cosmo_dim_transpose(y,'time');

    [nsamples,nfeatures]=size(orig_ds.samples);

    ds1=cosmo_slice(orig_ds,randperm(nsamples));
    ds2=cosmo_slice(orig_ds,randperm(nsamples));

    [mp,pm]=cosmo_align({ds1.sa.targets,ds1.sa.chunks,ds1.sa.time},...
                            {ds2.sa.targets,ds2.sa.chunks,ds2.sa.time});
    assertEqual(cosmo_slice(ds1,mp),ds2);
    assertEqual(cosmo_slice(ds2,pm),ds1);

    [mp,pm]=cosmo_align([2 3 4],[4 2 3]);
    assertEqual(mp,[3 1 2]);
    assertEqual(pm,[2 3 1]);


    [mp,pm]=cosmo_align({{'b','c','c'},[3 2 3]},...
                            {{'c','b','c'},[3 3 2]});
    assertEqual(mp,[3 1 2]);
    assertEqual(pm,[2 3 1]);

    % test structs
    p=struct();
    p.x={'b','c','c'};
    p.y=[3 2 3];
    q=struct();
    q.y=[3 3 2];
    q.x={'c','b','c'};
    [mp,pm]=cosmo_align(p,q);
    assertEqual(mp,[3 1 2]);
    assertEqual(pm,[2 3 1]);

    % test NaN
    [mp,pm]=cosmo_align([2 NaN 4],[4 2 NaN]);
    assertEqual(mp,[3 1 2]);
    assertEqual(pm,[2 3 1]);



    % test exceptions
    ds_small=cosmo_slice(ds1,1:nsamples-1);
    aet=@(varargin)assertExceptionThrown(@()...
                    cosmo_align(varargin{:}),'');
    aet(ds1,ds2);
    aet([2 3 4 3],[4 2 3 4]);
    aet([2 3 4 3],[4 2 3 4]);
    aet([2 3 4 3],[4 2 3]);
    aet([2 3 4],{[2,3,4],[2,3,4]});

    aet([2 3 NaN NaN],[2 3 NaN Inf]);
    aet([2 NaN 3],[4 2 NaN]);

    aet(struct,struct('a',1));
    aet(struct('a',1),1);

    aet({'b','c','d','d'},{'d','b','c','d'});


function test_align_multiple_nans
    n_rows_half=20+ceil(rand()*20);
    x=ceil(rand(n_rows_half*2,2)*sqrt(n_rows_half));
    rp=randperm(2*n_rows_half);

    rp1=rp(1:n_rows_half);
    rp2=rp(n_rows_half+(1:n_rows_half));

    % half of the rows become NaN
    x(rp1,1)=NaN;
    x(rp1,2)=1:n_rows_half;
    x(rp2,1)=1:n_rows_half;
    x(rp2,2)=1:n_rows_half;

    rp2=randperm(n_rows_half*2);
    y=x(rp2,:);

    assertExceptionThrown(@()cosmo_align(...
                            {x(:,1),x(:,2)},{y(:,1),y(:,2)}),'');

