How to correctly handle errors when using boost::filesystem? - c++

first, here is some code:
class A
{
public:
A()
{
//...
readTheFile(mySpecialPath);
//...
}
A(boost::filesystem::path path)
{
//...
readTheFile(path);
//...
}
protected:
void readTheFile(boost::filesystem::path path)
{
//First, check whether path exists e.g. by
//using boost::filesystem::exists(path).
//But how to propagate an error to the main function?
}
//...
};
int main(int argc, char **argv)
{
A myClass;
//Some more code which should not be run when A::readTheFile fails
}
What is a good solution to let the main function know that A::readTheFile could not open the file? I want to terminate the execution when opening the file fails.
Many thanks in advance!

Have readTheFile() throw an exception:
protected:
void readTheFile(boost::filesystem::path path)
{
//First, check whether path exists e.g. by
//using boost::filesystem::exists(path).
//But how to propagate an error to the main function?
if (/*some-failure-occurred*/)
{
throw std::runtime_error("Failed to read file: " + path);
}
}
...
int main()
{
try
{
A myObj;
//Some more code which should not be run when A::readTheFile fails
}
catch (const std::runtime_error& e)
{
std::cerr << e.what() << "\n";
}
return 0;
}

Related

how to export function's result to text file in C++?

int main()
{
shape a; //make class
ostream out;
out.open("test.txt"); // make file
out<< a.draw(); // std::ostream << void error
// draw() { cout<<"ddd"<<endl; }
out.close();
}
I want to wirte draw() in to file.
can you help me?
You have two options.
1: Pass the stream to the function and write to that instead of std::cout
void draw(std::ostream& os) { os << "ddd\n"; }
int main()
{
std::ofstream s("test.txt");
draw(s);
}
2: Return the result instead of writing it
std::string draw() { return "ddd\n"; }
int main()
{
std::ofstream s("test.txt");
s << draw();
}

GMock test fixture crashes on Windows

I'm new to using GMock framework. But, I have the following production application productionApp and test application testApp. My production app works perfectly. But the test crashes after executing the first test in the fixture.
class IRegEditor
{
public:
virtual bool Read(int&) = 0;
virtual bool Write(const int&) = 0;
virtual ~IRegEditor() {}
};
class RegEditorImpl : public IRegEditor
{
public:
//use windows registry APIs instead
//read returns values based on current time.
//write fails for odd values.
bool Read(int& i) { if (system_clock::now().time_since_epoch().count() % 2)
return false; else { i = 10; return true; } }
bool Write(const int& j) { if (j % 2) return false; else return true; }
};
class RegEditorMock : public IRegEditor
{
public:
MOCK_METHOD1(Read, bool(int&));
MOCK_METHOD1(Write, bool(const int&));
};
class RegEditTest : public ::testing::Test
{
protected:
virtual void SetUp() {
regEditor.reset(&regMock);
}
std::shared_ptr<IRegEditor> regEditor;
RegEditorMock regMock;
};
class App
{
std::shared_ptr<IRegEditor> regEdit;
public:
//ctor to use in production
App() :regEdit{ std::make_shared<RegEditorImpl>() }
{}
//overloaded ctor to use for unit tests
App(std::shared_ptr<IRegEditor> regEditor) : regEdit{ regEditor }
{}
bool Writer(const int& number)
{
if (regEdit->Write(number))
{ std::cout << "write passed" << std::endl; return true; }
else
{ std::cout << "write failed" << std::endl; return false; }
}
bool Reader(int& number)
{
if (regEdit->Read(number))
{ std::cout << "read passed" << std::endl; return true; }
else { std::cout << "read failed" << std::endl; return false; }
}
};
TEST_F(RegEditTest, writeFails)
{
int number = 1;
EXPECT_CALL(regMock, Write(number)).Times(1).WillOnce(Return(false));
App testApp(regEditor);
EXPECT_FALSE(testApp.Writer(number));
}
TEST_F(RegEditTest, writeSucceeds)
{
int number = 2;
EXPECT_CALL(regMock, Write(number)).Times(1).WillOnce(Return(true));
App testApp(regEditor);
EXPECT_FALSE(testApp.Writer(number));
}
int main(int argc, char** argv) {
// The following line must be executed to initialize Google Mock
// (and Google Test) before running the tests.
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
I get the following error on running the test. Does it have anything to do with GMock library's compiler setting compatibility ?
Unhandled exception at 0x77639D71 (ntdll.dll)
A heap has been corrupted (parameters: 0x7766D8D0).
Then shows that, it is not able to load symbols from wntdll.pdb.
The following production app works as expected
int main()
{
App productionApp;
int num = 9;
productionApp.Reader(num);
productionApp.Writer(num);
std::cin.get();
return 0;
}
One cannot do regEditor.reset(&regMock); this makes regEditor own the local regMock, Now, since regMock has two owners: its automatic storage duration, plus the shared pointer regEditor - memory is corrupted, when the scope ends. This did not have anything to do with GMock or GTest version or compiler settings or compatibility. It was because of my wrong usage of shared_ptr .Thanks to Jarod42 and Angew for the help. Please refer How to use shared_ptr to supply mock object from outside?

How can I check how many `EXPECT_*` calls failed in one test

I have an integration test that is something like:
TEST(foo, test_many_foos) {
foo_builder sut;
sut.set_some_params();
sut.run();
for (const auto foo : sut) {
EXPECT_TRUE(some_check(foo));
}
// TODO: Print a summary of how many EXPECT_TRUEs failed
}
Is there a way that I can print out a summary of the results of all of the EXPECT calls at the end of the test?
You could enhance Google Test using a custom event listener. You can define your own listener class and have it track the number of times an EXPECT_*() call fails per test:
class ExpectListener : public ::testing::EmptyTestEventListener {
int nFailures;
// Called before a test starts.
virtual void OnTestStart(const ::testing::TestInfo& test_info) {
nFailures = 0;
printf("*** Test %s.%s starting.\n",
test_info.test_case_name(),
test_info.name());
}
// Called after a failed assertion or a SUCCEED() invocation.
virtual void OnTestPartResult(const ::testing::TestPartResult& test_part_result) {
if (test_part_result.nonfatally_failed()) {nFailures++;}
printf("%s in %s:%d\n%s\n",
test_part_result.failed() ? "*** Failure" : "Success",
test_part_result.file_name(),
test_part_result.line_number(),
test_part_result.summary());
}
// Called after a test ends.
virtual void OnTestEnd(const ::testing::TestInfo& test_info) {
printf("*** Test %s.%s ending with %d failures.\n",
test_info.test_case_name(),
test_info.name(),
nFailures);
}
};
Now just replace Google Test's default listener with this custom listener:
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners();
delete listeners.Release(listeners.default_result_printer());
listeners.Append(new ExpectListener);
return RUN_ALL_TESTS();
}
You only need to set this up once (in main()); all tests will then track the number of non-fatal failures they've experienced. Of course, you can further customize this listener if you want to tweak the test messages or track more information.
A solution that I came up with (that I'm not entirely happy with) is to do the following:
class stream_counter
{
public:
explicit stream_counter(int *val) : val_(val) {}
void increment_count() const { ++*val_; }
private:
int *val_;
};
std::ostream &operator<<(std::ostream &os, const stream_counter &sc)
{
sc.increment_count();
return os;
}
TEST(foo, test_many_foos) {
foo_builder sut;
sut.set_some_params();
sut.run();
int n_failures = 0;
for (const auto foo : sut) {
EXPECT_TRUE(some_check(foo)) << stream_counter{&n_failures};
}
if(n_failures > 0) {
std::cout << "There were " << n_failures << " failures" << std::endl;
}
}
This abuses the operator << behaviour iof EXPECT_* which allow printing a message to the error stream if the check fails. stream_counter just wraps an integer and increments it if the object is streamed to a std::ostream
Not the cleanest solution, but it does what I want.
TEST(foo, test_many_foos) {
foo_builder sut;
sut.set_some_params();
sut.run();
auto n_failures = 0;
for (const auto foo : sut) {
auto const result = some_check(foo);
EXPECT_TRUE(result);
if (!result) ++n_failures;
}
if(n_failures > 0) {
std::cout << "There were " << n_failures << " failures" << std::endl;
}
}
This, however, means that EXPECT_TRUE() will print something about "result" rather than "some_check(foo)".

Class Creation and use issues

I created a class that represents a packet of information as described on this code:
#ifndef PACKET_H_
#define PACKET_H_
namespace std {
class Packet
{
public:
Packet();
virtual ~Packet();
void initClass();
void setStartP(char);
void setAddFrom(char);
void setAddTo(char);
void setpDataSize(char);
void setpNumber(char);
void setChecksum(char);
void setEndP(char);
void LoadData(char);
char getStartP();
char getAddFrom();
char getAddTo();
char getpDataSize();
char getChecksum();
char getEndP();
char getData();
private:
char pB[261];
char pDataMax;
char pDataIndex;
};
} /* namespace std */
#endif /* PACKET_H_ */
#include "Packet.h"
#include <iostream>
namespace std {
Packet::Packet()
{
pDataIndex = 0;
initClass();
}
Packet::~Packet()
{
delete this;
}
void Packet::setStartP(char startChar)
{
pB[0] = startChar;
cout << "in Set!";
}
void Packet::setAddFrom(char fromChar)
{
}
void Packet::setAddTo(char toChar)
{
}
void Packet::setpDataSize(char dataSizeChar)
{
}
void Packet::setpNumber(char packetNumber)
{
}
void Packet::setChecksum(char checksumChar)
{
}
void Packet::setEndP(char endChar)
{
}
void Packet::LoadData(char dataChar)
{
}
char Packet::getStartP()
{
return pB[0];
cout << "in Get";
}
char Packet::getAddFrom()
{
return pB[1];
}
char Packet::getAddTo()
{
return pB[2];
}
char Packet::getpDataSize()
{
return pB[3];
}
char Packet::getChecksum()
{
return pB[4];
}
char Packet::getEndP()
{
return pB[260];
}
char Packet::getData()
{
return pB[6 + pDataIndex];
}
void Packet::initClass()
{
pDataMax = 254;
pDataIndex = 0;
}
}
At this point i am just testing it so I just implemented two of the methods. When I try to run the program:
#include <iostream>
#include "Packet.h"
using namespace std;
Packet myPacket;
void buildPacket();
int main() {
buildPacket();
return 0;
}
void buildPacket( )
{
char startP = 0x28;
cout << "Setting startP!" << endl;
myPacket.setStartP(startP);
cout << "Getting startP" << endl;
cout << myPacket.getStartP() << endl;
cout << "Done";
}
The code is fine a compile/build time no issues there, it is a run time it falls over. This is really thruowing me, it really is making me doubt what I actually know about class creation and use in C++.
The program will run up to a certain point and then crashes with a windows message. on the console this is as far as it gets before crashing:
Setting startP!
in Set!Getting startP
(
As I can see it it seems to be on deletion that it crashes but not sure why. I looked around for similar issues but can't really find a reason why it is coming up with this, I would be grateful for some help on this one.
Don't call delete this in the destructor. The object is automatically destructed since it goes out of scope, no need for delete.
You can read more about it here: http://en.cppreference.com/w/cpp/language/scope

C++: Calling a function on a returned class

In the following code, my goal was to test the outerFunction(myTest).setPrivateVar(5); line. I'm not sure why, but calling this function doesn't change the privateVar member of myTest to 5, but calling cout << outerFunction(myTest).readPrivateVar properly displays the value 200. Can anybody explain why this is?
#include <iostream>
using namespace std;
class Test {
private:
int privateVar;
public:
void setPrivateVar(int);
int readPrivateVar();
};
void Test::setPrivateVar(int privateVarSet) {
privateVar = privateVarSet;
}
int Test::readPrivateVar() {
return privateVar;
}
Test outerFunction(Test passedTest) {
return passedTest;
}
int main(int argc, char* args[]) {
Test myTest;
myTest.setPrivateVar(200);
cout << myTest.readPrivateVar() << endl;
outerFunction(myTest).setPrivateVar(5);
cout << outerFunction(myTest).readPrivateVar() << endl;
return 0;
}
Output:
200
200
You are making copies here, both when you pass something into the function and when you return it:
Test outerFunction(Test passedTest) {
return passedTest;
}
Modifications to outerFunction(myTest) affect the copy, not the original.
To get the semantics you seem to be after, you need to use references:
Test& outerFunction(Test& passedTest) {
return passedTest;
}