<div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> 3) Hard to get a message about what failed if the predicate only succeeds of fails.  I save off results instead of pushing IO into the test harness though.   I felt it made more sense.<br>
<br>
I also don’t like pushing IO through the test cases, but I didn’t accomplish to put test cases into a list. After reading in the reference manual section 8.3, that higher-order terms can cause problems in polymorphic collection types, I gave up my try to collect test cases in a list.<br>
<br></blockquote><div>I'm not using Polymorphism.<br><br><pre><span class="">:-</span> <span class="">type</span> <span class="">test_result</span>
<a name="cl-53"></a>      <span class="">---></span> <span class="">test_result</span><span class="">(</span><span class="">result_test_name</span><span class="">::</span><span class="">string</span><span class="">,</span>
<a name="cl-54"></a>                       <span class="">result_test_disposition</span><span class="">::</span><span class="">test_disposition</span><span class="">).</span>
<a name="cl-55"></a></pre><br><br></div><div>Eventually, I'll want to flesh that out with things like the hostname, startTime, stopTime, etc...  but this is all I needed for no<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
For a simple XML parser, I wrote dozens of test cases like these:<br>
<br>
%% testDCG(TestNo, DCG-predicate, InputToBeParsed, ExpectedResult, !IO)<br>
<br>
testDCG(1, nameStartChar, ":", yes(':'), !IO),<br>
testDCG(2, nameStartChar, "-", no, !IO),<br>
testDCG(3, nameChar, "-", yes('-'), !IO),<br>
testDCG(4, name, "Name", yes("Name"), !IO),<br>
testDCG(5, attValue, "\"AttValue\"", yes("AttValue"), !IO),<br>
testDCG(6, attribute, "attribute=\"Value\"",<br>
    yes({"attribute", "Value"}), !IO),<br>
…<br>
<br>
I don’t understand the syntax of test_case yet. Could you please give me an example, how I can write a list of test cases for different DCG predicates?<br>
<br></blockquote><br></div><div class="gmail_quote">You don't pass in the predicate-under-test as a parameter, instead you build a test predicate and call predicate-under-test from there.<br><br></div><div class="gmail_quote">Below is an example of test cases defined in terms of named predicates, instead of lambdas.   I am currently No Good at DCGs, but I'll write something similar to what I think you're first test does  and hopefully you can figure out how to adapt it.<br></div><div class="gmail_quote"><pre><span class="">:-</span> <span class="">pred</span> <span class="">pass_test</span><span class="">(</span><span class="">test_disposition</span><span class="">::</span><span class="">out</span><span class="">)</span> <span class="">is</span> <span class="">det</span><span class="">.</span>
<a name="cl-13"></a><span class="">pass_test</span><span class="">(</span><span class="">Disposition</span><span class="">)</span> <span class="">:-</span>
<a name="cl-14"></a>      <span class="">Disposition</span> <span class="">=</span> <span class="">pass</span><span class="">.</span>
<a name="cl-15"></a>
<a name="cl-16"></a><span class="">:-</span> <span class="">pred</span> <span class="">fail_test</span><span class="">(</span><span class="">test_disposition</span><span class="">::</span><span class="">out</span><span class="">)</span> <span class="">is</span> <span class="">det</span><span class="">.</span>
<a name="cl-17"></a><span class="">fail_test</span><span class="">(</span><span class="">Disposition</span><span class="">)</span> <span class="">:-</span>
<a name="cl-18"></a>      <span class="">Disposition</span> <span class="">=</span> <span class="">fail</span><span class="">(</span><span class="">"Fail tests aways Fail"</span><span class="">).<br><br></span></pre><pre><span class="">:- pred name_start_test(test_disposition::out) is det.<br>name_start_test(Disposition) :-        <br>         nameStartChar(":someString" OutStartChar),<br>         (<br>          if   OutStartChar = ":" <br>          then Disposition = pass<br>          else Disposition = fail("Expected StartChar to be : But got " ++ OutStartChar ++ " instead"<br>         ).<br></span></pre><pre><span class=""><br><br></span><span class="">TestList</span> <span class="">=</span> <span class="">[</span>
<a name="cl-51"></a>                  <span class="">test_case</span><span class="">(</span><span class="">"PassTest"</span><span class="">,</span> <span class="">pass_test</span><span class="">),</span>
<a name="cl-52"></a>                  <span class="">test_case</span><span class="">(</span><span class="">"FailTest"</span><span class="">,</span> <span class="">fail_test</span><span class="">),<br>                    test_case("NameStartTest), name_start_test)<br>           ]<br></span></pre><br><br></div><div class="gmail_quote">the if...then...else in name_start_test could have been a call to assertions.are_equal instead:<br></div><div class="gmail_quote">name_start_test(Disposition)<br></div><div class="gmail_quote">       nameStartChar(":someString", OutStartChar),<br></div><div class="gmail_quote">       assertions.are_equal(univ(":"), univ(OutStartChar), Disposition).<br></div><div class="gmail_quote"><br><br></div><div class="gmail_quote">Cheers!<br><br></div><div class="gmail_quote">Charles<br></div></div></div>