boost test case for function taking user input - c++

I have a function that takes in user input via std::cin:
std::getline(std::cin, in);
and creates a corresponding data structure by matching it with a regular expression. The function then returns this data structure.
I'm using boost.test and I want to create a unit test to check that the output data type is correct given some inputs. However I don't know how to go about it since the input isn't passed as an argument to the function.
EDIT: Is there a simple way to create a boost test case that feeds the function a string via standard input?

If you have access to the source code of the function that calls std::getline, then the easiest solution is to rewrite it as a wrapper of another function having the same signature and implementation, but taking an additional std::istream& parameter that is used in place of std::cin. For example, if you currently have:
my_struct my_func()
{
//...
std::getline(std::cin, in);
//...
}
Then rewrite like this:
my_struct my_func(std::istream& is);
inline my_struct my_func()
{
return my_func(std::cin);
}
my_struct my_func(std::istream& is)
{
//...
std::getline(is, in);
//...
}
This way, you will be able to test the core functionality of my_func on constructed input sequences by passing std::istringstream objects into my_func(std::istream&).
If you do not have access to the source code of the function that calls std::getline, then one trick that you can use is to replace the standard in descriptor. See this answer for code that replaces the standard out descriptor and modify accordingly.

Related

How to handle file I/O outside of main when redirecting input and output?

A restriction of the program I am working on is that it should be invoked as: ./a.out < input.txt > output.txt. The input of this program should be read from the first file, and the output should be written to the second.
So, this redirects standard input and output from and to these two files. I could simply, from main() for example, call std::cin and std::cout. However, I have a dedicated component which adapts my input from a file to an intermediate structure that I use elsewhere in my program.
In order to build this struct I could #include <iostream> in this component and read with std::cin from input.txt. However, I don't like the idea of including iostream here, and I am not sure how I would test this.
My issue comes from the I/O redirect, if the executable were invoked with filenames as strings, I would do something along the lines of
InputAdapter inputAdapter;
ifstream infile;
infile.open(filename ,std::ios_base::in);
auto structHoldingParsedInput = inputAdapter.adapt(infile);
How can I achieve something similar here?
I would suggest you make your adapter parameters std::istream& and std::ostream& so you can pass in either the standard std::cin/std::cout or files you open yourself like std::ifstream.
A bit like this:
class InputAdapter
{
public:
void adapt(std::istream& in)
{
// code to convert input to output here
return created_object;
}
};
// ...
InputAdapter inputAdapter;
std::ifstream in("input_file");
auto structHoldingParsedInput = inputAdapter.adapt(in);
Now you are coding to streams rather than files you can use any stream, for example the standard input stream:
auto structHoldingParsedInput = inputAdapter.adapt(std::cin);
And, for testing you could use std::istringstream:
std::istringstream test_stream(R"(
put your test data in here
)");
auto structHoldingParsedInput = inputAdapter.adapt(test_stream);

C++ copy_if lambda capturing std::string

This is a follow up question from here: C++ - Developing own version of std::count_if?
I have the following function:
// vector for storing the file names that contains sound
std::vector<std::string> FilesContainingSound;
void ContainsSound(const std::unique_ptr<Signal>& s)
{
// Open the Wav file
Wav waveFile = Wav("Samples/" + s->filename_);
// Copy the signal that contains the sufficient energy
std::copy_if(waveFile.Signal().begin(), waveFile.Signal().end(),
FilesContainingSound.begin(), [] (const Signal& s) {
// If the energy bin > threshold then store the
// file name inside FilesContaining
}
}
But to me, I only need to capture the string "filename" inside of the lambda expression, because I'll only be working with this. I just need access to the waveFile.Signal() in order to do the analysis.
Anyone have any suggestions?
EDIT:
std::vector<std::string> FilesContainingSound;
std::copy_if(w.Signal().begin(), w.Signal().end(),
FilesContainingSound.begin(), [&] (const std::unique_ptr<Signal>& file) {
// If the energy bin > threshold then store the
// file name inside FilesContaining
});
You seem to be getting different levels of abstraction confused here. If you're going to work with file names, then you basically want something on this order:
std::vector<std::string> input_files;
std::vector<std::string> files_that_contain_sound;
bool file_contains_sound(std::string const &filename) {
Wav waveFile = Wav("Samples/" + filename);
return binned_energy_greater(waveFile, threshold);
}
std::copy_if(input_files.begin(), input_files.end(),
std::back_inserter(files_that_contain_sound),
file_contains_sound);
For the moment I've put the file_contains_sound in a separate function simply to make its type clear -- since you're dealing with file names, it must take a file name as a string, and return a bool indicating whether that file name is one of the group you want in your result set.
In reality, you almost never really want to implement that as an actual function though--you usually want it to be an object of some class that overloads operator() (and a lambda is an easy way to generate a class like that). The type involved must remain the same though: it still needs to take a file name (string) as a parameter, and return a bool to indicate whether that file name is one you want in your result set. Everything dealing with what's inside the file will happen inside of that function (or something it calls).

check if something was serialized in std::ostream

Is there an easy way to check if something was serialized in stl::ostream. I am looking for something like:
some preparation
// ... a very complex code that may result in adding or not to the stream,
// that I will prefer not to change
check if the stream has something added
Note that this will need to works recursively. Is using register_callback is a good idea or there is easier way?
First the immediate question: register_callback() is intended to deal with appropriate copying and releasing of resources stored in pword() and will have operations only related to that (i.e., copying, assigning, and releasing plus observing std::locale changes). So, no, that won't help you at all.
What you can do, however, is to create a filtering stream buffer which observes if there was a write to the stream, e.g., something like this:
class changedbuf: std::streambuf {
std::streambuf* d_sbuf;
bool d_changed;
int_type overflow(int_type c) {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
this->d_changed = true;
}
return this->d_sbuf->sputc(c);
}
public:
changedbuf(std::streambuf* sbuf): d_sbuf(d_sbuf), d_changed() {}
bool changed() const { return this->d_changed; }
}
You can use this in place of the std::ostream you already have, e.g.:
void f(std::ostream& out) {
changedbuf changedbuf(out.rdbuf());
std::ostream changedout(&changedbuf);
// use changedout instead of out; if you need to use a global objects, you'd
// replace/restore the used stream buffer using the version of rdbuf() taking
// an argument
if (changedbuf.change()) {
std::cout << "there was a change\n";
}
}
A real implementation would actually provide a buffer and deal with proper flushing (i.e., override sync()) and sequence output (i.e., override xsputn()). However, the above version is sufficient as a proof-of-concept.
Others are likely to suggest the use of std::ostringstream. Depending on the amount of data written, this can easily become a performance hog, especially compared to an advanced version of changedbuf which appropriately deals with buffering.
Are you passing the stream into the complex code, or is it globally visible? Can it be any kind of ostream or can you constrain the type to ofstream or ostringstream?
You may be able to use tellp to determine whether the file position has changed since your preparation code, if your ostream type supports it (such as with most fstreams). Or, if you're passing the stream in, you could pass an empty ostringstream in and check that it's not empty when the string is extracted to be printed out.
It's not entirely obvious which solution, if any, would be appropriate for you without knowing more about the context of your code and the specifics of your problem. The best answer may be to return (or set as a by-reference out-parameter) a flag indicating whether the stream was inserted into.

How do you overload operator>> if you are just recreating the ifstream class?

My teacher wanted us to learn the ifstream class and how it works. She gave us homework to create a FileStream wrapper class that is templated to work with anything and can take in anything that's in the file.
I have written everything except I can't get it to compile because I don't know how to write the >> operator and keep getting errors for it. This is what I have so far:
template<class A>
ifstream& operator >>(FileStream<A> fs, A& x){
fs>>x;
return fs;
}
In the main she is using to check our work it is called like this:
FileStream<Word> input;
Word temp; //word is a class we created to manipulate strings in certain ways
while(input>> temp){
cout<<temp<<endl;
}
If anyone could help me out I would be most grateful. I've been working on this for 2 days and I can't get it.
template<class T>
FileStream<T>& operator >> (FileStream<T>& fs, T& value) {
value = fs.readValueFromStream();
return fs;
}
Your method should look something like the above. Highlights:
(Note that I've renamed A to T and x to value. T is the usual name for generic template arguments, and value is a bit more descriptive than x.)
Accepts a FileStream<T>& reference. The & ensures that you work with the original stream object and not a copy.
Returns a FileStream<T>& reference, not an ifstream.
Rather than doing fs>>x in the method, which would just be a recursive call to the very method we're in, you need to write code to actually read an item from the stream and put it into value. This should use some method of your FileStream class. I wrote value = fs.readValueFromStream() but this could be anything.
In this way operator >> serves as syntactic sugar. The real work is done by the value = fs.readValueFromStream() line (or whatever code you actually write there).

implementing simple input stream

I want to write a simple istream object, that would simply transform another istream.
I want to only implement readline (which would read a line from the original stream, would process it, and return the processed line), and have some generic code that upon read would use my read line, cache it, and give the required amount of bytes as output.
Is there any class that would allow me to do that?
For example
struct mystream : istreamByReadLine {
istream& s;
mystream(istream& _s):s(_s){}
virtual string getline() {
string line;
getline(s,line);
f(line);
return line;
}
}
class istreamByReadLine : istream {
... // implementing everything needed to be istream compatible, using my
... // getline() virtual method
}
Have you looked at boost.iostreams? It does most of the grunt work for you (possibly not for your exact use case, but for C++ standard library streams in general).
Are you sure this is the way to go? In similar cases, I've
either defined a class (e.g. Line), with a >> operator which
did what I wanted, and read that, e.g.:
Line line
while ( source >> line ) ...
The class itself can be very simple, with just a std::string
member, and an operator std::string() const function which
returns it. All of the filtering work would be done in the
std::istream& operator>>( std::istream&, Line& dest )
function. Or I've installed a filtering streambuf in front of the
normal streambuf ; Boost iostream has good support for
this.