Fixed redirected standard streams being leaked by cr_(assert|expect)_std(out|err)

This commit is contained in:
Snaipe 2016-03-05 15:51:50 +01:00
parent de5ec40466
commit c5b4ca27d7
4 changed files with 95 additions and 22 deletions

View file

@ -27,6 +27,15 @@
# include "common.h"
# include "assert.h"
CR_BEGIN_C_API
CR_API int cr_stdout_match_file(CR_STDN FILE* ref);
CR_API int cr_stdout_match_str(const char* ref);
CR_API int cr_stderr_match_file(CR_STDN FILE* ref);
CR_API int cr_stderr_match_str(const char* ref);
CR_END_C_API
# define cr_assert_redir_op_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
@ -67,5 +76,44 @@
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
# define cr_assert_redir_unop_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Str)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
(CR_STR(File), Str), \
__VA_ARGS__ \
))
# define cr_assert_redir_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
# define cr_assert_redir_f_unop_(Fail, Fun, Op, File, Ref, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Ref)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_MATCH, \
(CR_STR(File), CR_STR(Ref)), \
__VA_ARGS__ \
))
# define cr_assert_redir_f_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_f_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#endif /* !CRITERION_INTERNAL_REDIRECT_H_ */

View file

@ -24,15 +24,15 @@
#ifndef CRITERION_REDIRECT_H_
# define CRITERION_REDIRECT_H_
# include "internal/common.h"
# include "internal/redirect.h"
# ifdef __cplusplus
# include <cstdio>
# else
# include <stdio.h>
# endif
# include "internal/common.h"
# include "internal/redirect.h"
CR_BEGIN_C_API
/**
@ -112,29 +112,29 @@ CR_END_C_API
# define cr_assert_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, !=, __VA_ARGS__))
# define cr_expect_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, __VA_ARGS__))
# define cr_assert_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, ==, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_expect_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, ==, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_assert_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
# define cr_expect_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
# define cr_assert_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, !=, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_expect_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, !=, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_assert_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
# define cr_expect_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
# define cr_assert_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, ==, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_expect_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, ==, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_assert_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
# define cr_expect_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
# define cr_assert_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, !=, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_expect_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, !=, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_assert_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
# define cr_expect_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
# define cr_assert_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, ==, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_expect_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, ==, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_assert_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
# define cr_expect_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
# define cr_assert_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, !=, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_expect_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, cr_get_redirected_stdout(), __VA_ARGS__))
# define cr_assert_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
# define cr_expect_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
# define cr_assert_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, ==, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_expect_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, ==, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_assert_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
# define cr_expect_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
# define cr_assert_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, !=, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_expect_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, cr_get_redirected_stderr(), __VA_ARGS__))
# define cr_assert_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
# define cr_expect_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
# ifdef __cplusplus
# include "internal/stream.hxx"

View file

@ -54,3 +54,31 @@ int cr_file_match_file(FILE* f, FILE* ref) {
return matches;
}
int cr_stdout_match_file(FILE* ref) {
FILE *f = cr_get_redirected_stdout();
int res = cr_file_match_file(f, ref);
fclose(f);
return res;
}
int cr_stdout_match_str(const char* ref) {
FILE *f = cr_get_redirected_stdout();
int res = cr_file_match_str(f, ref);
fclose(f);
return res;
}
int cr_stderr_match_file(FILE* ref) {
FILE *f = cr_get_redirected_stderr();
int res = cr_file_match_file(f, ref);
fclose(f);
return res;
}
int cr_stderr_match_str(const char* ref) {
FILE *f = cr_get_redirected_stderr();
int res = cr_file_match_str(f, ref);
fclose(f);
return res;
}

View file

@ -65,7 +65,6 @@ Test(redirect, stdout_) {
std::cout << "Foo" << std::flush;
cr_expect_stdout_eq_str("Foo");
cr_expect_stdout_neq_str("Bar");
}
Test(redirect, stderr_) {
@ -74,7 +73,6 @@ Test(redirect, stderr_) {
std::cerr << "Foo" << std::flush;
cr_expect_stderr_eq_str("Foo");
cr_expect_stderr_neq_str("Bar");
}
Test(redirect, stdin_) {
@ -86,5 +84,4 @@ Test(redirect, stdin_) {
std::cin >> read;
cr_expect_eq(read, "Foo");
cr_expect_neq(read, "Bar");
}