forked from vikshanker/sponge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbyte_stream_test_harness.cc
184 lines (152 loc) · 7.34 KB
/
byte_stream_test_harness.cc
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include "byte_stream_test_harness.hh"
#include <memory>
#include <sstream>
using namespace std;
// ByteStreamTestStep
ByteStreamTestStep::operator std::string() const { return "ByteStreamTestStep"; }
void ByteStreamTestStep::execute(ByteStream &) const {}
ByteStreamTestStep::~ByteStreamTestStep() {}
// ByteStreamExpectationViolation
ByteStreamExpectationViolation::ByteStreamExpectationViolation(const std::string &msg) : std::runtime_error(msg) {}
template <typename T>
ByteStreamExpectationViolation ByteStreamExpectationViolation::property(const std::string &property_name,
const T &expected,
const T &actual) {
return ByteStreamExpectationViolation("The ByteStream should have had " + property_name + " equal to " +
to_string(expected) + " but instead it was " + to_string(actual));
}
// ByteStreamExpectation
ByteStreamExpectation::operator std::string() const { return "Expectation: " + description(); }
std::string ByteStreamExpectation::description() const { return "description missing"; }
void ByteStreamExpectation::execute(ByteStream &) const {}
ByteStreamExpectation::~ByteStreamExpectation() {}
// ByteStreamAction
ByteStreamAction::operator std::string() const { return " Action: " + description(); }
std::string ByteStreamAction::description() const { return "description missing"; }
void ByteStreamAction::execute(ByteStream &) const {}
ByteStreamAction::~ByteStreamAction() {}
ByteStreamTestHarness::ByteStreamTestHarness(const std::string &test_name, const size_t capacity)
: _test_name(test_name), _byte_stream(capacity) {
std::ostringstream ss;
ss << "Initialized with ("
<< "capacity=" << capacity << ")";
_steps_executed.emplace_back(ss.str());
}
void ByteStreamTestHarness::execute(const ByteStreamTestStep &step) {
try {
step.execute(_byte_stream);
_steps_executed.emplace_back(step);
} catch (const ByteStreamExpectationViolation &e) {
std::cerr << "Test Failure on expectation:\n\t" << std::string(step);
std::cerr << "\n\nFailure message:\n\t" << e.what();
std::cerr << "\n\nList of steps that executed successfully:";
for (const std::string &s : _steps_executed) {
std::cerr << "\n\t" << s;
}
std::cerr << std::endl << std::endl;
throw ByteStreamExpectationViolation("The test \"" + _test_name + "\" failed");
} catch (const exception &e) {
std::cerr << "Test Failure on expectation:\n\t" << std::string(step);
std::cerr << "\n\nException:\n\t" << e.what();
std::cerr << "\n\nList of steps that executed successfully:";
for (const std::string &s : _steps_executed) {
std::cerr << "\n\t" << s;
}
std::cerr << std::endl << std::endl;
throw ByteStreamExpectationViolation("The test \"" + _test_name +
"\" caused your implementation to throw an exception!");
}
}
// EndInput
std::string EndInput::description() const { return "end input"; }
void EndInput::execute(ByteStream &bs) const { bs.end_input(); }
// Write
Write::Write(const std::string &data) : _data(data) {}
Write &Write::with_bytes_written(const size_t bytes_written) {
_bytes_written = bytes_written;
return *this;
}
std::string Write::description() const { return "write \"" + _data + "\" to the stream"; }
void Write::execute(ByteStream &bs) const {
auto bytes_written = bs.write(_data);
if (_bytes_written and bytes_written != _bytes_written.value()) {
throw ByteStreamExpectationViolation::property("bytes_written", _bytes_written.value(), bytes_written);
}
}
// Pop
Pop::Pop(const size_t len) : _len(len) {}
std::string Pop::description() const { return "pop " + to_string(_len); }
void Pop::execute(ByteStream &bs) const { bs.pop_output(_len); }
// InputEnded
InputEnded::InputEnded(const bool input_ended) : _input_ended(input_ended) {}
std::string InputEnded::description() const { return "input_ended: " + to_string(_input_ended); }
void InputEnded::execute(ByteStream &bs) const {
auto input_ended = bs.input_ended();
if (input_ended != _input_ended) {
throw ByteStreamExpectationViolation::property("input_ended", _input_ended, input_ended);
}
}
// BufferEmpty
BufferEmpty::BufferEmpty(const bool buffer_empty) : _buffer_empty(buffer_empty) {}
std::string BufferEmpty::description() const { return "buffer_empty: " + to_string(_buffer_empty); }
void BufferEmpty::execute(ByteStream &bs) const {
auto buffer_empty = bs.buffer_empty();
if (buffer_empty != _buffer_empty) {
throw ByteStreamExpectationViolation::property("buffer_empty", _buffer_empty, buffer_empty);
}
}
// Eof
Eof::Eof(const bool eof) : _eof(eof) {}
std::string Eof::description() const { return "eof: " + to_string(_eof); }
void Eof::execute(ByteStream &bs) const {
auto eof = bs.eof();
if (eof != _eof) {
throw ByteStreamExpectationViolation::property("eof", _eof, eof);
}
}
// BufferSize
BufferSize::BufferSize(const size_t buffer_size) : _buffer_size(buffer_size) {}
std::string BufferSize::description() const { return "buffer_size: " + to_string(_buffer_size); }
void BufferSize::execute(ByteStream &bs) const {
auto buffer_size = bs.buffer_size();
if (buffer_size != _buffer_size) {
throw ByteStreamExpectationViolation::property("buffer_size", _buffer_size, buffer_size);
}
}
// RemainingCapacity
RemainingCapacity::RemainingCapacity(const size_t remaining_capacity) : _remaining_capacity(remaining_capacity) {}
std::string RemainingCapacity::description() const { return "remaining_capacity: " + to_string(_remaining_capacity); }
void RemainingCapacity::execute(ByteStream &bs) const {
auto remaining_capacity = bs.remaining_capacity();
if (remaining_capacity != _remaining_capacity) {
throw ByteStreamExpectationViolation::property("remaining_capacity", _remaining_capacity, remaining_capacity);
}
}
// BytesWritten
BytesWritten::BytesWritten(const size_t bytes_written) : _bytes_written(bytes_written) {}
std::string BytesWritten::description() const { return "bytes_written: " + to_string(_bytes_written); }
void BytesWritten::execute(ByteStream &bs) const {
auto bytes_written = bs.bytes_written();
if (bytes_written != _bytes_written) {
throw ByteStreamExpectationViolation::property("bytes_written", _bytes_written, bytes_written);
}
}
// BytesRead
BytesRead::BytesRead(const size_t bytes_read) : _bytes_read(bytes_read) {}
std::string BytesRead::description() const { return "bytes_read: " + to_string(_bytes_read); }
void BytesRead::execute(ByteStream &bs) const {
auto bytes_read = bs.bytes_read();
if (bytes_read != _bytes_read) {
throw ByteStreamExpectationViolation::property("bytes_read", _bytes_read, bytes_read);
}
}
// Peek
Peek::Peek(const std::string &output) : _output(output) {}
std::string Peek::description() const { return "\"" + _output + "\" at the front of the stream"; }
void Peek::execute(ByteStream &bs) const {
auto output = bs.peek_output(_output.size());
if (output != _output) {
throw ByteStreamExpectationViolation("Expected \"" + _output + "\" at the front of the stream, but found \"" +
output + "\"");
}
}