How to match a C-style array in Google Mock - c++

Given the following example
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdint.h>
using namespace ::testing;
class Tested
{
public:
virtual void setArray(const uint32_t[3]) {};
};
class Tested_mock: public Tested
{
public:
MOCK_METHOD1(setArray, void(const uint32_t[3]));
};
class TestRunner: public ::testing::Test
{
public:
StrictMock<Tested_mock> t;
};
TEST_F(TestRunner, test)
{
uint32_t a[3] = {1UL, 2UL, 3UL};
EXPECT_CALL(t, setArray(_)).With(ElementsAreArray(a));
t.setArray(a);
}
i don't understand why i'm not able to compile this snippet while changing the argument to uint32_t* works. Does Gmock have a problem with fixed-size-array arguments ?
You could find the compilation output here https://pastebin.com/72b4iYqs

Late to party but I had the same issue.
The problem is that the testing framework also wants to know the size of the actual array to check if it's the same as expected.
In the end I ended up defining my own Matcher that takes the size as an argument:
MATCHER_P2(FixedSizeArrayMatches, expected, elements, "")
{
return memcmp(arg, expected, elements * sizeof(expected[0])) == 0;
}
This can then be used like this:
EXPECT_CALL(t, setArray(FixedSizeArrayMatches(a, 3));

Related

How to initialize a template class with a non constant value

I have a template class that needs I need to set the size of using the size of a vector. what is the best way to achieve this? below is a simplified version, I will link to the full class if you need to see it.
template<int maxParams>
class ParameterChangeHandler
{
public:
inline ParameterChangeHandler()
{
//Do Stuff
};
//More Inline Methods that use maxparams and paramBitArray
protected:
unsigned char paramBitArray[(((maxParams)+((8) - 1)) & ~((8) - 1)) / 8]
};
int main()
{
std::vector<int> myVectorOfParameters = { 1,2,3,4,5 };
//This is OK
//ParameterChangeHandler<10> paramChangeHandler;
//This is what I want
ParameterChangeHandler<myVectorOfParameters.size()> paramChangeHandler
}
This is for an audio application that I am building using the Wwise SDK, Here is a link to the actual class that is giving me the issue
AkFXParameterChangeHandler
What you want isn't possible. Here's what you can do. Pass myVectorOfParameters.size() as an argument to the constructor and use std::vector/std::basic_string instead of unsigned char array so you don't need a constant expression for the size.
#include <vector>
#include <cstddef>
class ParameterChangeHandler
{
public:
ParameterChangeHandler(std::size_t const max_size)
: paramBitArray(max_size) // or reserve and push_back as needed
{
// Do Stuff
};
protected:
std::vector<unsigned char> paramBitArray;
};

C++ Pointer function to other class function

I need help with passing a function pointer on C++. I can't linkage one function for a class to other function. I will explain. Anyway I will put a code resume of my program, it is much larger than the code expose here but for more easier I put only the part I need to it works fine.
I have one class (MainSystem) and inside I have an object pointer to the other class (ComCamera). The last class is a SocketServer, and I want when the socket received any data, it sends to the linkage function to MainSystem.
ComCamera is a resource Shared with more class and I need to associate the functions ComCamera::vRecvData to a MainSystem::vRecvData or other function of other class for the call when receive data and send de data to the function class associate.
Can Anyone help to me?
EDDITED - SOLUTION BELOW
main.cpp
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <exception>
#include <unistd.h>
using std::string;
class ComCamera {
public:
std::function<void(int, std::string)> vRecvData;
void vLinkRecvFunction(std::function<void(int, std::string)> vCallBack) {
this->vRecvData = vCallBack;
}
void vCallFromCamera() {
this->vRecvData(4, "Example");
};
};
class MainSystem {
private:
ComCamera *xComCamera;
public:
MainSystem(ComCamera *xComCamera) {
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iChannelNumber, std::string sData) {vRecvData(iChannelNumber, sData); });
}
void vRecvData(int iNumber, string sData) {
std::cout << "RECV Data From Camera(" + std::to_string(iNumber) + "): " << sData << std::endl;
};
};
int main(void) {
ComCamera xComCamera;
MainSystem xMainSystem(&xComCamera);
xComCamera.vCallFromCamera();
return 0;
}
Output will be:
MainSystem RECV Data From Camera(4): Example
You can have ComCamera::vRecvData be of type std::function<void(int, std::string)> and then have ComCamera::vLinkRecvFunction() be like this:
void ComCamera::vLinkRecvFunction(std::function<void(int, std::string)> callBack)
{
this->vRecvData = callBack;
}
and have MainSystem constructor be like this:
MainSystem::MainSystem(ComCamera *xComCamera)
{
using namespace std::placeholders;
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iNumber, std::string sData){vRecvData(number, sData);});
}
Still though the original question has way too much code to go through friend.
Here what you want :
#include<iostream>
using std::cout;
class A; //forward declare A
class B{
public:
void (A::*ptr)(int x); //Only declare the pointer because A is not yet defined.
};
class A{
public:
void increase_by(int x){
a+=x;
} // this function will be pointed by B's ptr
int a = 0; // assume some data in a;
B b; // creating B inside of A;
void analyze(int y){
(*this.*(b.ptr))(y);
} // Some function that analyzes the data of A or B; Here this just increments A::a through B's ptr
};
int main(){
A a; // creates A
cout<<a.a<<"\n"; // shows initial value of a
a.b.ptr = &A::increase_by; // defines the ptr that lies inside of b which inturns lies inside a
a.analyze(3); // calls the initialize method
(a.*(a.b.ptr))(3); // directly calls b.ptr to change a.a
cout<<a.a; // shows the value after analyzing
return 0;
}
Output will be :
0
6
I still don't get why would you do something like this. But maybe this is what you wanted as per your comments.
To know more read this wonderful PDF.

Undefined Reference to 'vtable for class'

I am implementing a Visitor class in C++ that generates XML output for a parse tree.
When I compile with Clion on Windows the code compiles but when it runs after it outputs what is expected it crashes. The error code is this
Process finished with exit code -1073741819 (0xC0000005)
When I try to compile using gcc (without Clion) I get the error message
Undefined Reference to 'vtable for PrintXMLVisitor'.
My code is the following. I have distilled it down to the least amount the produces the error
ASTNode.h
#ifndef MINILANG_ASTNODE_H
#define MINILANG_ASTNODE_H
#include <memory>
class Visitor;
class ASTNode {
public:
virtual void accept(std::shared_ptr<Visitor> visitor) = 0;
};
#endif //MINILANG_ASTNODE_H
ASTTypeNode.h
#ifndef MINILANG_ASTTYPENODE_H
#define MINILANG_ASTTYPENODE_H
#include "ASTNode.h"
class ASTTypeNode: public ASTNode {
public:
enum Type {Real, Int, Bool, String};
ASTTypeNode(Type type);
Type getType() const;
void accept(std::shared_ptr<Visitor> visitor) override;
private:
Type type;
};
#endif //MINILANG_ASTTYPENODE_H
ASTTypeNode.cpp
#include "ASTTypeNode.h"
#include "Visitor.h"
ASTTypeNode::ASTTypeNode(ASTTypeNode::Type type)
: type(type)
{
}
ASTTypeNode::Type ASTTypeNode::getType() const {
return type;
}
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor) {
visitor->visit(std::shared_ptr<ASTTypeNode>(this));
}
Visitor.h
#ifndef MINILANG_VISITOR_H
#define MINILANG_VISITOR_H
#include <memory>
#include "ASTTypeNode.h"
class Visitor {
public:
virtual void visit(std::shared_ptr<ASTTypeNode> typeNode) = 0;
};
#endif //MINILANG_VISITOR_H
PrintXMLVisitor.h
#ifndef MINILANG_PRINTXMLVISITOR_H
#define MINILANG_PRINTXMLVISITOR_H
#include "Visitor.h"
class PrintXMLVisitor: public Visitor {
public:
void visit(std::shared_ptr<ASTTypeNode> typeNode) override;
};
#endif //MINILANG_PRINTXMLVISITOR_H
PrintXMLVisitor.cpp
#include "PrintXMLVisitor.h"
#include <iostream>
void PrintXMLVisitor::visit(std::shared_ptr<ASTTypeNode> typeNode) {
std::string typeName;
switch(typeNode->getType())
{
case ASTTypeNode::Type::Real:
typeName = "Real";
break;
case ASTTypeNode::Type::Int:
typeName = "Int";
break;
case ASTTypeNode::Type::Bool:
typeName = "Bool";
break;
case ASTTypeNode::Type::String:
typeName = "String";
break;
default:
typeName = "Error";
exit(22);
}
std::cout << "<TypeNode>" << typeName << "</TypeNode>" << std:: endl;
}
main.cpp
#include <iostream>
#include "Lexer.h"
#include "ASTTypeNode.h"
#include "PrintXMLVisitor.h"
int main() {
ASTTypeNode astTypeNode (ASTTypeNode::Type::Int);
astTypeNode.accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
Your crafting a shared pointer that isn't dynamic. Specifically,
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor) {
visitor->visit(std::shared_ptr<ASTTypeNode>(this)); // <=== HERE
}
The this in that statement refers to:
int main()
{
ASTTypeNode astTypeNode (ASTTypeNode::Type::Int); // <== this object
astTypeNode.accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
Changing toolchains isn't going to fix this problem you have options, the two most obvious being:
Stop using a std::shared_ptr for the visit parameter.
Manage all ASTNodeType instances a requiring being std::shared_ptr managed and share from this using the std:enable_shared_from_this capabilities of the standard library.
The former of these is obvious (or at least it is now), so I'll not discuss it further. The latter is not necessarily trivial, as it mandates any instances of your underlying class that utilize shared_from_this must be managed by std::shared_ptr wrappers. I.e., there are no concrete constructions like you're currently doing in main(). This could have significant impact on your overall code base, so choose this carefully.
An example of how the above would work in your case:
First, change the derivation chain of ASTNodeType to look like this:
class ASTTypeNode
: public ASTNode
, public std::enable_shared_from_this<ASTTypeNode> // ADDED
Next, utilize shared_from_this as follows:
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor)
{
visitor->visit(shared_from_this()); // HERE
}
And finally, honor the warrant you've made that ASTNodeType instances are shared-ptr managed by doing this:
int main()
{
std::shared_ptr<ASTTypeNode> astTypeNode = std::make_shared<ASTTypeNode>(ASTTypeNode::Type::Int);
astTypeNode->accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
That should work. Read more about the things used in the above code here:
std::enable_shared_from_this
std::enable_shared_from_this::shared_from_this
As I said, all of this is to facilitate using a std::shared_ptr from an object given only a this pointer. If you can remove that requirement in the first place, it may be an easier path to take, and I would consider that first.

operator == list of pointers googleTest c++

I'm trying to compare two lists of pointers via googletest, and everytime I do that my test stops running at that test block. it doesn't give me an error or something, just stops.
here is my code:
TEST_F(WorkerTest, checkCtor)
{
Worker oved(m_id,m_job,m);
EXPECT_EQ(oved.getId(),m_id);
EXPECT_TRUE(m_job == oved.getJob() );
EXPECT_TRUE(m == oved.getMoviesOfWorker()); //PROBLEMATIC LINE
}
here is my code for getMoviesOfWorker:
list<Movie*> Worker::getMoviesOfWorker(){
std::list<Movie*> m;
return m;
}
my constructor of Worker looks like this:
Worker(int m_id, std::string m_job, std::list<Movie*> moviesToWorker){};
and my WorkerTest class looks like this:
#include "gtest/gtest.h"
#include "Worker.h"
#include <list>
class WorkerTest : public ::testing::Test {
protected:
int sizeBefore;
std::list<Movie*> m;
std::string m_job;
int m_id;
virtual void SetUp(){};
virtual void TearDown(){};
public:
WorkerTest() : sizeBefore(), m(), m_id(), m_job(){}
};
I don't understand in general why would googleTest stop, and btw I don't have implementation for any of my functions (getId or getJob), and even when I do return some list in getMoviesOfWorker() it still crashes.. HELP?

Casting to undeclared type

The idea is identical to the generic version of GetComponent() in Unity. But I'm currently stumbling on the following template issue:
template<class T> std::shared_ptr<T> MyClass::GetMyComponent()
{
for (int i = 0; i < _baseTypeList.size(); i++)
{
auto base = _baseTypeList[i];
T* check = dynamic_cast<T*>(base.get());
if (check)
{
return std::static_pointer_cast<T>(base);
}
}
return std::shared_ptr<T>(nullptr);
}
where _baseTypeList is a std::vector<std::shared_pntr{MyBaseType}> types.
In this function, I am iterating over a list of components to find if there is one that matches the type I'm asking for. if there is one, return the component cast to that type. Otherwise return a nullptr.
However, when I call this function from outside code, I get the following error:
error C2680: 'MyType*' : invalid target type for dynamic_cast
where MyType is some class that derives from component.
When I put #include "MyType.h" in the header it compiles just fine but without it it gives this error and doesn't compile.
This means I cannot use it in other classes without modifying the header file this template class resides in, which will be a problem for me.
Is there a way I can achieve simular results without having to #include every single header of the type I pass in the template for?
[EDIT]
For clarity, consider a person using my library, he creates a type
"Foo : MyBaseType" where MyBaseType has a virtual method "Update" that is called every frame.
any instance of class MyBaseType (including Foo) is to be managed by this library, and have update called every frame.
This library thus has a large list of "MyBaseType" objects. But has no knowledge of the actual type they are, just that they derive from "MyBaseType", so it can call Update() on them.
If I need a specific type the library needs to be able to search for it in this list and return it.
I would like this "search" to happen in the library itself, so I do not have to expose the list, and write a new "search" method for every type that derives from "MyBaseType"
[FINAL]
It turned out I messed up the include order in my project.
a minimal example of what I was trying to do would be:
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <memory>
#include "vector"
class MyBaseClass
{
virtual void Update(){};
};
class MyLibrary
{
public:
template<class T> std::shared_ptr<T> GetComponent();
std::vector<std::shared_ptr<MyBaseClass>> list;
};
template<class T> std::shared_ptr<T> MyLibrary::GetComponent()
{
static_assert(std::is_base_of<MyBaseClass, T>::value, "T1 is no subclass of ModelComponent");
for (unsigned int i = 0; i < list.size(); i++)
{
auto comp = list[i];
T* check = dynamic_cast<T*>(comp.get());
if (check)
{
return std::static_pointer_cast<T>(comp);
}
}
return std::shared_ptr<T>(nullptr);
}
class MyClass : public MyBaseClass
{
void Update() override;
};
void MyClass::Update()
{
}
int _tmain(int argc, _TCHAR* argv[])
{
MyLibrary lib;
lib.list.push_back(std::make_shared<MyClass>());
auto var = lib.GetComponent<MyClass>();
std::cout << (var ? "var is object" : "var is not") << std::endl;
while (true)
{
}
return 0;
}
which works as expected.
The primary issue was that the compiler gave an error in the "GetMyComponent" function, so I found a usage of it that did everything as suggested.
But it turned out there was a second usage that did not have the definition of "MyClass" before calling it (but didn't give an error, as it was forward declared in its header file).
You don't need the definition of possible T types included into your header. You do need the relevant one defined in the translation unit in which the template is expanded:
// client.cpp
#include <myclass.h>
#include <foo.h> // defines class Foo
void f(MyClass *p)
{
auto c = p->GetMyComponent<Foo>();
c->foobar();
}