<?xml version="1.0" encoding="UTF-8"?>
<!--
 *
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2010 - 2011 - DIGITEO - Michael Baudin
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="assert_checkerror" xml:lang="en">
    <refnamediv>
        <refname>assert_checkerror</refname>
        <refpurpose>Check that an instruction produces the expected
            error.
        </refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>
            flag = assert_checkerror ( instr , expectedmsg )
            flag = assert_checkerror ( instr , expectedmsg , expectederrnb )
            flag = assert_checkerror ( instr , expectedmsg , expectederrnb , a1, ... )
            [flag,errmsg] = assert_checkerror ( ... )
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Parameters</title>
        <variablelist>
            <varlistentry>
                <term>instr:</term>
                <listitem>
                    <para>a 1-by-1 matrix of strings, an expression to evaluate</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>expectedmsg :</term>
                <listitem>
                    <para>a string or a string vector, the error message to be
                        produced
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>expectederrnb :</term>
                <listitem>
                    <para>a 1-by-1 matrix of doubles, integer values, the error number
                        (default expectederrnb=[]).
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>a1 :</term>
                <listitem>
                    <para>an extra localization argument, passed to the
                        <literal>msprintf</literal> function.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>flag :</term>
                <listitem>
                    <para>a 1-by-1 matrix of boolean, %t if the correct error message
                        was produced, %f if not
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>errmsg :</term>
                <listitem>
                    <para>a 1-by-1 matrix of strings, the error message. If flag==%t,
                        then errormsg=="". If flag==%f, then errmsg contains the error
                        message.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>If the expression does not generate an error, then
            <literal>assert_checkerror</literal> generates an error. Performs silently
            if the evaluated expression generates the expected error message.
        </para>
        <para>
            If the error message <literal>expectedmsg</literal> is provided and
            is not the empty matrix <literal>[]</literal>, we check that the generated
            error number matches the expected one. If the error number
            <literal>expectederrnb</literal> is provided and is not the empty matrix
            <literal>[]</literal>, we check that the generated error number matches
            the expected one. If the error message <literal>expectedmsg</literal> and
            the error number <literal>expectederrnb</literal> cannot be equal to the
            empty matrix <literal>[]</literal> at the same time: at least one of them
            must be provided.
        </para>
        <para>The string matching is strict string equality: no pattern or regular
            expression can be used.
        </para>
        <para>If the error message is not expected or the error number is not
            expected,
            <itemizedlist>
                <listitem>
                    <para>if the errmsg output variable is not used, an error is
                        generated,
                    </para>
                </listitem>
                <listitem>
                    <para>if the errmsg output variable is used, no error is
                        generated.
                    </para>
                </listitem>
            </itemizedlist>
        </para>
        <para>The goal of this function is to enable the tester to check the error
            cases in a simplified framework. Checking the error messages of a function
            has the following advantages:
            <itemizedlist>
                <listitem>
                    <para>it checks that the correct error is generated when
                        needed,
                    </para>
                </listitem>
                <listitem>
                    <para>it checks that the error message is correctly
                        formatted,
                    </para>
                </listitem>
                <listitem>
                    <para>it checks that the error message is correctly
                        localized.
                    </para>
                </listitem>
            </itemizedlist>
        </para>
        <para>The expected message can be a localized message. In this case, the
            message is compared with the output of the <literal>gettext</literal>
            function, and depends on the local language. The extra argument
            <literal>a1</literal> can be used for this purpose, for example to format
            the localized message. All the extra arguments <literal>a1</literal>,
            <literal>a2</literal>, ... are automatically passed to the
            <literal>msprintf</literal> function before being compared to the computed
            error message.
        </para>
    </refsection>
    <refsection>
        <title>Examples</title>
        <para>We give several examples of using the
            <literal>assert_checkerror</literal> function. We first have to define a
            function to be tested.
        </para>
        <para>
            The following function <literal>f</literal> generates an error when
            the number of input arguments in wrong or the type of <literal>x</literal>
            is wrong.
        </para>
        <programlisting role="example"><![CDATA[
function y = f(x)
    [lhs, rhs] = argn()
    if ( rhs <> 1 ) then
        lstr = gettext("%s: Wrong number of input argument: %d expected.\n")
        errmsg = msprintf ( lstr , "f" , 1 )
        error(errmsg)
    end
    if ( typeof(x) <> "constant" ) then
        lstr = gettext("%s: Wrong type for argument #%d: Matrix expected.\n")
        errmsg = msprintf ( lstr , "f" , 1 )
        error(errmsg,123456789)
    end
    y = x
endfunction
        ]]></programlisting>
        <para>Our task is to check the error messages produced by this function.
            The two following tests pass: the error message is the expected one. We
            let <literal>assert_checkerror</literal> manage the localization, by
            providing only the localized message and the extra parameter
            <literal>"f"</literal> (the name of the function) and <literal>1</literal>
            (the index of the input argument). These two extra parameters are used by
            <literal>assert_checkerror</literal> to format the message and to convert
            the "%s" and "%d" formats into their actual values.
        </para>
        <programlisting role="example"><![CDATA[
lcl1 = "%s: Wrong number of input argument: %d expected.\n";
assert_checkerror ( "y = f()" , lcl1 , [] , "f" , 1);

lcl2 = "%s: Wrong type for argument #%d: Matrix expected.\n";
assert_checkerror ( "y = f(""a"")" , lcl2 , [] , "f" , 1);
        ]]></programlisting>
        <para>On the other hand, if we make the assumption that the current locale
            language is english, we could as well use the following statement. But
            this is not a recommended practice, since the test will fail if the
            current locale is French, for example.
        </para>
        <programlisting role="example"><![CDATA[
assert_checkerror ( "y = f()" , "f: Wrong number of input argument: 1 expected." );
        ]]></programlisting>
        <para>In the following test, we also check the error number.</para>
        <programlisting role="example"><![CDATA[
lcl1="%s: Wrong number of input argument: %d expected.\n";
assert_checkerror ( "y=f()" , lcl1 , 10000     , "f" , 1);

lcl2 = "%s: Wrong type for argument #%d: Matrix expected.\n";
assert_checkerror ( "y=f(""a"")" , lcl2 , 123456789 , "f" , 1);
        ]]></programlisting>
        <para>The two following tests fail.</para>
        <programlisting role="example"><![CDATA[
assert_checkerror ( "y = f()" , "oups" );

msg1 = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "f", 1);
assert_checkerror ( "y = f()" , msg1 , 12 );
        ]]></programlisting>
        <para>When errmsg is given as output argument, no error is generated, as
            in the following example. Notice the content of the
            <literal>flag</literal> and <literal>errmsg</literal> variables.
        </para>
        <programlisting role="example"><![CDATA[
// A test which pass: flag is %t, errmsg is empty
msg1 = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "f", 1);
[flag, errmsg] = assert_checkerror ( "y = f()" , msg1 )

// A test which fail: flag is %f, errmsg is not empty
[flag, errmsg] = assert_checkerror ( "y = f()" , "oups" )
        ]]></programlisting>
        <para>The messages in the two following tests are localized, so that they
            can work whatever the current language is. Instead of using the extra
            parameter <literal>a1</literal>, we directly localize the message, which
            is less short, but is a perfectly valid code.
        </para>
        <programlisting role="example"><![CDATA[
msg1 = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "f", 1);
assert_checkerror ( "y = f()" , msg1 );

msg2 = msprintf(gettext("%s: Wrong type for argument #%d: Matrix expected.\n"), "f", 1);
assert_checkerror ( "y = f(""a"")" , msg2 );
        ]]></programlisting>
        <para>It may happen that we want to just test the error number, but not
            the error message. The following script just checks that the generated
            error number is 123456789 when the first argument is not a matrix of
            doubles: we do not check the error message.
        </para>
        <programlisting role="example"><![CDATA[
assert_checkerror("f(""foo"")", [], 123456789);
        ]]></programlisting>
    </refsection>
    <refsection>
        <title>History</title>
        <revhistory>
            <revision>
                <revnumber>5.4.0</revnumber>
                <revdescription>Function introduced</revdescription>
            </revision>
        </revhistory>
    </refsection>
</refentry>
