Предыстория
Я портирую платформу модульного тестирования QuickCheck на C (см. Рабочий код на странице GitHub). Синтаксис будет таким:
for_all(property, gen1, gen2, gen3 ...);
Где property
- функция для тестирования, например bool is_odd(int)
. gen1
, gen2
и т. Д. - это функции, которые генерируют входные значения для property
. Некоторые генерируют целые числа, некоторые генерируют символы, некоторые генерируют строки и так далее.
for_all
примет функцию с произвольными входами (любое количество аргументов, любые типы аргументов). for_all
запустит генераторы, создав тестовые значения для передачи функции свойств. Например, свойство is_odd
- это функция с типом bool f(int)
. for_all
будет использовать генерацию для создания 100 тестовых случаев. Если свойство возвращает false для любого из них, for_all
распечатает неверные значения тестового примера. В противном случае for_all
напечатает "SUCCESS"
.
Таким образом, for_all
следует использовать va_list
для доступа к генераторам. Как только мы вызываем функции генератора, как передать их функции свойств?
Пример
Если is_odd
имеет тип bool f(int)
, как бы мы реализовали функцию apply()
с таким синтаксисом:
apply(is_odd, generated_values);
Вторичный выпуск
См. SO.
Как мы можем грамотно распечатать произвольные значения неудачного тестового примера? Тестовый пример может быть одним целым числом или двумя символами, или строкой, или некоторой комбинацией вышеперечисленного? Мы не будем знать заранее, использовать ли:
printf("%d %d %d\n", some_int, some_int, some_int);
printf("%c\n" a_character);
printf("%s%s\n", a_string, a_struct_requiring_its_own_printf_function);
a)
вызывать каждый генератор один раз и сразу же получать всю коллекцию сгенерированных значений илиb)
вызывать каждую функцию генератора в цикле для получения последующих значений для проверки? - person julx   schedule 23.09.2011c)
каждый генератор предоставляет последующие значения для определенного аргумента функции. - person julx   schedule 23.09.2011testme(int, char, char)
требуется случайное целое число и два случайных символа. Как только мы выясним, как это сделать, у нас будетfor_all
запускать не один, а 100 тестовых примеров в большом цикле. - person mcandre   schedule 23.09.2011va_list
и последующей передачи списка start в функция печати или обработки какого-либо вида (вы можете использовать типva_list
в качестве параметра функции, позволяя вам обернуть или иным образом возиться с функциями vararg). - person ssube   schedule 23.09.2011for_all(property, gen1, print1, gen2, print2, ...);
для обработки произвольно сложных типов данных (подумайте о деревьях RedBlack). - person mcandre   schedule 23.09.2011