I've just come up with a better answer to this question.  If I was a
C/C++ programmer this would have been obvious to me before, and it
solves a bunch of annoyances for me at once.

#ifndef UTIL_H
#define UTIL_H

#include <string>
#include <stdio.h>
#include <stdarg.h>

std::string stringf(const char * format_str, ...) {
  va_list arg_list;
  char * c_string;
  va_start(arg_list, format_str);
  vasprintf(&c_string, format_str, arg_list);
  std::string answer = std::string(c_string);
  free(c_string);
  va_end(arg_list);
  return answer;
}

namespace {
  int tests = 0;

  int next_test () {
    return ++tests;
  }

  int current_test () {
    return tests;
  }
}

void ok (bool is_ok, const char * description, ...) {
  std::string status
    = stringf("%s %d", is_ok ? "ok" : "not ok", next_test());

  va_list arg_list;
  char * c_string;
  va_start(arg_list, description);
  vasprintf(&c_string, description, arg_list);
  va_end(arg_list);
  printf("%s: %s\n", status.c_str(), c_string);
  free(c_string);
}

void all_done () {
  printf("1..%d\n", current_test());
}

#endif

On Tue, Apr 16, 2013 at 6:36 AM, Ben Tilly <bti...@gmail.com> wrote:
> On Tue, Apr 16, 2013 at 4:02 AM, David Cantrell <da...@cantrell.org.uk> wrote:
>> On 15/04/2013 19:35, Ben Tilly wrote:
>>
>>> I'm writing some C++ at the moment that fits into the first group
>>> (performance-critical code).  For unit testing I've been emitting TAP
>>> protocol and testing it with prove, but are there better approaches?
>>>
>>> I get a test file with a lot of code that looks like this:
>>>
>>>    printf(
>>>      "%s %d: Some useful description and maybe a number %d\n",
>>>      (expected_value == test_value) ? "ok" : "not ok", ++tests,
>>>      some_useful_debugging_info
>>>    );
>>
>>
>> How about abusing the pre-processor to build a strangely familiar-looking
>> mini-language for testing:
>>
>> #define OK(result, text) printf("%s %d %s\n", (result ? "ok" : "not ok"),
>> test_number++, text); if(!(result)) { all_gone_buggerup = 1; }
>> #define DONE_TESTING() printf("%s\n", all_gone_buggerup ? "FAILED" :
>> "PASSED"); if(all_gone_buggerup) { return 1; } else { return 0; }
>>
>> obviously you also need to declare and initialise test_number and
>> all_gone_buggerup too.
>>
>> You can then write:
>>
>> int main(void) {
>>   int test_number = 0;
>>   int all_gone_buggerup = 0;
>>   OK(1 == 1, "it works!");
>>   OK(2 == 1, "oh no it doesn't");
>>
>>   DONE_TESTING();
>> }
>
> You missed the significant fact that I am passing information into the
> description in further parameters.  That's essential for me, not a
> nice to have.  It allows me to do things like have potentially dubious
> values appear directly in my test output.  (I caught a subtle bug due
> to seeing that output just last night!)

_______________________________________________
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to