function test_suite = test_match
% tests for cosmo_match
%
% #   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_match_()
    % helper function to convert numeric to logical array
    b=@(x)logical(x);

    % basic numeric stuff
    assertEqual(cosmo_match(5:-1:1,[2 3]),b([0,0,1,1,0]));
    assertEqual(cosmo_match((5:-1:1)',[2 3]),b([0,0,1,1,0])');

    % basic strings
    assertEqual(cosmo_match({'a','b','c'},{'b','c','d','e','b'}),...
                                                        b([0 1 1]));
    assertEqual(cosmo_match({'b','c','d','e','b'},{'a','b','c'}),...
                                                        b([1 1 0 0 1]));

    assertEqual(cosmo_match({'a','b','c'}',{'b','c','d','e','b'}),...
                                                        b([0 1 1]'));
    assertEqual(cosmo_match({'b','c','d','e','b'}',{'a','b','c'}),...
                                                        b([1 1 0 0 1]'));

    assertEqual(cosmo_match({'aaa','aa','a','aa'},{'a'}),b([0 0 1 0]));
    assertEqual(cosmo_match({'aaa','aa','a','aa'},'a'),b([0 0 1 0]));

    assertEqual(cosmo_match({'aaa','aa','a','aa'},{'aa'}),b([0 1 0 1]));
    assertEqual(cosmo_match({'aaa','aa','a','aa'},{'a','aaa'}),...
                                                           b([1 0 1 0]));

    % multiple inputs
    assertEqual(cosmo_match(1:5,[2 5],6:10,7),b([0 1 0 0 0]));
    assertEqual(cosmo_match(1:5,[2 5],6:10,6),b([0 0 0 0 0]));
    assertEqual(cosmo_match(1:5,1:10,6:10,7:9),b([0 1 1 1 0]));
    assertEqual(cosmo_match(1:5,1:10,6:10,7:9,2:6,4:5),b([0 0 1 1 0]));

    assertEqual(cosmo_match({'a','b','c'},'b',{'d','e','f'},{'f','e'}),...
                                                    b([0 1 0]));


    % empty inputs ok if types match
    assertEqual(cosmo_match({},''),b([]));
    assertEqual(cosmo_match([],[]),b([]));

    assertExceptionThrown(@()cosmo_match({},[]),'');
    assertExceptionThrown(@()cosmo_match([],{}),'');

    % can use a single string
    assertEqual(cosmo_match({'b','c','d','e','b'},'b'),b([1 0 0 0 1]));

    % can use function handles
    assertEqual(cosmo_match(1:4,@(x)mod(x,2)==0),b([0 1 0 1]));
    assertEqual(cosmo_match({'b','c','d','c'},@(x)x=='c'),b([0 1 0 1]));


    % cannot deal with logical arrays
    assertExceptionThrown(@()cosmo_match(5:-1:1,b([0,0,1,1,0])),'');

    % first argument cannot be a string
    assertExceptionThrown(@()cosmo_match('',''),'');
    assertExceptionThrown(@()cosmo_match('x',''),'');

    % no mixed datatypes
    assertExceptionThrown(@()cosmo_match(1,''),'');
    assertExceptionThrown(@()cosmo_match({'x'},1),'');
    assertExceptionThrown(@()cosmo_match({1,2},''),'');
    assertExceptionThrown(@()cosmo_match('',{1,2}),'');

    assertExceptionThrown(@()cosmo_match(['x'],1),'');

    assertExceptionThrown(@()cosmo_match({'x',1},''),'');
    assertExceptionThrown(@()cosmo_match({'x',1},[]),'');
    assertExceptionThrown(@()cosmo_match({'x',1},'x'),'');
    assertExceptionThrown(@()cosmo_match({'x',1},1),'');

    % no support for 2D arrays
    assertExceptionThrown(@()cosmo_match(eye(2),1),'');
    assertExceptionThrown(@()cosmo_match(cell(2),1),'');

    % no structs
    assertExceptionThrown(@()cosmo_match(struct(),[]),'');
    assertExceptionThrown(@()cosmo_match(struct(),''),'');
    assertExceptionThrown(@()cosmo_match([],struct()),'');
    assertExceptionThrown(@()cosmo_match({},struct()),'');

    % needs even number of arguments
    assertExceptionThrown(@()cosmo_match({'a'}),'');
    assertExceptionThrown(@()cosmo_match({'a'},{'b'},{'c'}),'');
    assertExceptionThrown(@()cosmo_match({'a'},{'b'},{'c'},1,2),'');

    % multiple inputs must have the same size of output
    assertExceptionThrown(@()cosmo_match(1:3,3,6:9,9),'');
    assertExceptionThrown(@()cosmo_match({'a','b'},{'a'},{'c'}',{'c'}),'');

    % odd elements must be cell string ro numeric
    assertExceptionThrown(@()cosmo_match('a','b','a','c',{'c'}),'');



    % function handle has to return boolean output
    assertExceptionThrown(@()cosmo_match(1:4,@(x)x+1),'');
