1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <istream>
#include <string>
#include <sstream>
#include <gtest/gtest.h>
#ifndef UTIL_UNITTESTS_TEXTDATA_H
#define UTIL_UNITTESTS_TEXTDATA_H 1
/**
* \file textdata.h
* \brief Utilities for tests with text data.
*
* This utility provides convenient helper functions for unit tests using
* textual data.
*/
namespace isc {
namespace util {
namespace unittests {
/// Line-by-line text comparison.
///
/// This templated function takes two standard input streams, extracts
/// strings from them, and compares the two sets of strings line by line.
template <typename EXPECTED_STREAM, typename ACTUAL_STREAM>
void
matchTextData(EXPECTED_STREAM& expected, ACTUAL_STREAM& actual) {
std::string actual_line;
std::string expected_line;
while (std::getline(actual, actual_line), !actual.eof()) {
std::getline(expected, expected_line);
if (expected.eof()) {
FAIL() << "Redundant line in actual output: " << actual_line;
break;
}
if (actual.bad() || actual.fail() ||
expected.bad() || expected.fail()) {
throw std::runtime_error("Unexpected error in data streams");
}
EXPECT_EQ(expected_line, actual_line);
}
while (std::getline(expected, expected_line), !expected.eof()) {
ADD_FAILURE() << "Missing line in actual output: " << expected_line;
}
}
/// Similar to the fully templated version, but takes string for the second
/// (actual) data.
///
/// Due to the nature of textual data, it will often be the case that test
/// data is given as a string object. This shortcut version helps such cases
/// so that the test code doesn't have to create a string stream with the
/// string data just for testing.
template <typename EXPECTED_STREAM>
void
matchTextData(EXPECTED_STREAM& expected, const std::string& actual_text) {
std::istringstream iss(actual_text);
matchTextData(expected, iss);
}
/// Same for the previous version, but the first argument is string.
template <typename ACTUAL_STREAM>
void
matchTextData(const std::string& expected_text, ACTUAL_STREAM& actual) {
std::istringstream iss(expected_text);
matchTextData(iss, actual);
}
/// Same for the previous two, but takes strings for both expected and
/// actual data.
void
matchTextData(const std::string& expected_text,
const std::string& actual_text)
{
std::istringstream expected_is(expected_text);
std::istringstream actual_is(actual_text);
matchTextData(expected_is, actual_is);
}
}
}
}
#endif // UTIL_UNITTESTS_TEXTDATA_H
|