28 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
60 void test_stack_with_objects();
61 void test_stack_with_pointers();
64 byte_array generate_flat(
const char *to_store);
65 byte_array *generate_deep(
const char *to_store);
73void test_stack::CHECK_STACK_RESULT(
outcome retval,
const astring &place)
76 if (retval == common::IS_FULL)
78 else if (retval ==
common::IS_EMPTY)
81 if (retval.
value() || !place) {}
85byte_array test_stack::generate_flat(
const char *to_store)
91byte_array *test_stack::generate_deep(
const char *to_store)
101 for (
int i = 0; i < s.
elements(); i++) {
110 for (
int i = 0; i < s.
elements(); i++) {
116void test_stack::test_stack_with_objects()
118 FUNCDEF(
"test_stack_with_objects");
129 LOG(
"testing the bounded stack first:");
131 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the first line")),
"first push");
132 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the second line")),
"second push");
133 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the final and third")),
"third push");
134 byte_array gend = generate_flat(
"this shouldn't work");
135 ASSERT_EQUAL(bounded_stack.push(gend).value(), common::IS_FULL,
136 "the bounded stack push should catch IS_FULL");
138 LOG(
"pushing worked successfully...");
139 LOG(
"printing the stack in element order");
141 for (
int i = 0; i < bounded_stack.size(); i++) {
144 bounded_stack[i].observe()));
148 LOG(
"now popping the stack all the way back.");
150 int full_size = bounded_stack.size();
151 for (
int j = 0; j < full_size; j++) {
154 bounded_stack.size(), bounded_stack.top().observe()));
157 bounded_stack.acquire_pop(found);
162 "acquire_pop should have right contents at 2");
166 "acquire_pop should have right contents at 1");
170 "acquire_pop should have right contents at 0");
174 ASSERT_EQUAL(bounded_stack.pop().value(), common::IS_EMPTY,
175 "bounded pop should have right outcome");
180 LOG(
"testing the unbounded stack now:");
182 for (
int j = 0; j < 24; j++) {
184 CHECK_STACK_RESULT(unlimited_stack.push(generate_flat(line.s())),
"unbound push");
187 LOG(
"unbounded stack in element order:");
189 for (
int k = 0; k < unlimited_stack.size(); k++) {
195 LOG(
"now popping fresh order:");
197 while (unlimited_stack.size()) {
200 unlimited_stack.size(), unlimited_stack.top().observe()));
202 unlimited_stack.pop();
207 ASSERT_EQUAL(unlimited_stack.pop().value(), common::IS_EMPTY,
208 "unlimited pop should return empty as expected");
211----------------------------------------------\n\
212both types of stack exercises were successful.\n\
213----------------------------------------------");
218 LOG(
"now setting up some simple stacks...");
223 LOG(
"bounded first...");
229 int max = bounder.elements();
230 for (
int i = 0; i < max; i++) {
231 ASSERT_EQUAL(bounder.size(), i,
"the bounder size should be in step with loop");
232 int byte_array_size =
randomizer.inclusive(259, 287);
235 visible.stuff((
char *)to_stuff.access(), visible.length() + 1);
236 for (
int j = visible.length() + 1; j < to_stuff.length(); j++)
237 *(to_stuff.access() + j) =
'\0';
241 outcome ret = bounder.push(to_stuff);
242 ASSERT_EQUAL(ret.
value(), common::OKAY,
"pushing should not fail in simple test");
244 ASSERT_EQUAL(bounder.elements(), bounder.size(),
"bounder set should see size and max same");
252 while (bounder.size()) bounder.pop();
257void test_stack::test_stack_with_pointers()
259 FUNCDEF(
"test_stack_with_pointers")
270 LOG(
"testing the bounded stack first:");
272 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the first line")),
"first push");
273 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the second line")),
"second push");
274 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the final and third")),
"third push");
275 byte_array *gend = generate_deep(
"this shouldn't work");
276 ASSERT_EQUAL(bounded_stack.push(gend).value(), common::IS_FULL,
277 "the bounded stack push should catch IS_FULL");
280 LOG(
"pushing worked successfully...");
281 LOG(
"printing the stack in element order");
283 for (
int i = 0; i < bounded_stack.size(); i++) {
289 LOG(
"now popping the stack all the way back.");
291 int full_size = bounded_stack.size();
292 for (
int j = 0; j < full_size; j++) {
294 LOG(
astring(
astring::SPRINTF,
"pop %d, stack size is %d, has %s", j+1, bounded_stack.size(), bounded_stack.top()->observe()));
297 bounded_stack.acquire_pop(found);
298 ASSERT_TRUE(found,
"acquire_pop test should not return nil");
304 "popping should have right contents at 2");
308 "popping should have right contents at 1");
312 "popping should have right contents at 0");
317 ASSERT_EQUAL(bounded_stack.pop().value(), common::IS_EMPTY,
318 "bounded pop failure in result");
323 LOG(
"testing the unbounded stack now:");
325 for (
int j = 0; j < 24; j++) {
327 CHECK_STACK_RESULT(unlimited_stack.push(generate_deep(line.s())),
"unbound push");
330 LOG(
"unbounded stack in element order:");
332 for (
int k = 0; k < unlimited_stack.size(); k++) {
338 LOG(
"\nnow popping order:");
340 while (unlimited_stack.size()) {
345 unlimited_stack.pop();
353 ASSERT_EQUAL(unlimited_stack.pop().value(), common::IS_EMPTY,
354 "unlimited pop should return empty as expected");
357----------------------------------------------\n\
358both types of stack exercises were successful.\n\
359----------------------------------------------");
364 LOG(
"now setting up some simple stacks...");
369 LOG(
"bounded first...");
374 bounder.elements(), bounder.size()));
376 int max = bounder.elements();
377 for (
int i = 0; i < max; i++) {
378 ASSERT_EQUAL(bounder.size(), i,
"bounder size should remain in step with loop");
379 int byte_array_size =
randomizer.inclusive(259, 287);
382 visible.stuff((
char *)to_stuff->
observe(), visible.length() + 1);
383 for (
int j = visible.length() + 1; j < to_stuff->
length(); j++)
384 *(to_stuff->
access() + j) =
'\0';
385 ASSERT_EQUAL(bounder.push(to_stuff).value(), common::OKAY,
386 "pushing should not fail in bound simple test");
388 ASSERT_EQUAL(bounder.elements(), bounder.size(),
"bounder set must have size and max agree");
396 while (bounder.size()) {
405int test_stack::execute()
407 test_stack_with_objects();
408 test_stack_with_pointers();
409 return final_report();
The application_shell is a base object for console programs.
virtual int execute()=0
< retrieves the command line from the /proc hierarchy on linux.
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
const contents * observe() const
Returns a pointer to the underlying C array of data.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
A very common template for a dynamic array of bytes.
the "common" class defines our common_outcomes.
Outcomes describe the state of completion for an operation.
a platform-independent way to acquire random numbers in a specific range.
An abstraction that represents a stack data structure.
int elements() const
Returns the number of elements used by the stack.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
unsigned char abyte
A fairly important unit which is seldom defined...
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
A dynamic container class that holds any kind of object via pointers.
Useful support functions for unit testing, especially within hoople.
const int test_iterations
#define ASSERT_EQUAL(a, b, test_name)
#define ASSERT_TRUE(a, test_name)