'(maybe you meant to use ‘->’ ?)' in gmock test - c++

I have a unit test using gtest and gmock.
These are provided, and in my turn I should make them pass.
I have a RentalAdministration Object, which takes (in some methods) a Car object pointer. One of the functions looks like this:
bool RentalAdministration::Add(Car *car){
if(!car){
throw invalid_argument("Car parameter can't be null!");
}
if(FindCar(car->GetLicencePlate()) != NULL){
return false;
}
cars.push_back(car);
return true;
}
One of such tests looks like his:
TEST(RentalAdministrationAdd, test_add_car_to_empty_administration)
{
RentalAdministration admin;
Car *car;
EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
EXPECT_TRUE(admin.Add(&car));
}
When I try to make these tests, I get loads of errors, all of which are alike:
g++ -Wall -Werror -pedantic -ggdb -O0 -std=c++98 -Iproduct -Itest test/RentalAdministrationTest.cpp product/RentalAdministration.cpp -lgtest -lgmock -lgmock_main -lpthread -o RentalAdministrationTest
In file included from /usr/include/gmock/gmock-generated-function-mockers.h:43:0,
                 from /usr/include/gmock/gmock.h:61,
                 from test/RentalAdministrationTest.cpp:2:
test/RentalAdministrationTest.cpp: In member function ‘virtual void RentalAdministrationAdd_test_add_car_to_empty_administration_Test::TestBody()’:
test/RentalAdministrationTest.cpp:13:5: error: request for member ‘gmock_GetLicencePlate’ in ‘car’, which is of pointer type ‘Car*’ (maybe you meant to use ‘->’ ?)
     EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
     ^
In file included from /usr/include/gtest/gtest.h:58:0,
                 from /usr/include/gmock/internal/gmock-internal-utils.h:47,
                 from /usr/include/gmock/gmock-actions.h:46,
                 from /usr/include/gmock/gmock.h:58,
                 from test/RentalAdministrationTest.cpp:2:
test/RentalAdministrationTest.cpp:14:31: error: no matching function for call to ‘RentalAdministration::Add(Car**)’
     EXPECT_TRUE(admin.Add(&car));
                               ^
I wonder what I am doing wrong here. I'm just starting off with C++.
btw: I am compiling in g++ and have version 98.
Thanks.
Edit: excuse me for not posting this, but I have a mock file for Car.h which is in the same folder as the test itself.
#ifndef __CAR_H
#define __CAR_H
#include "gmock/gmock.h"
#include <string>
using namespace std;
class Car
{
public:
MOCK_CONST_METHOD0(GetLicencePlate, string());
MOCK_METHOD0(Rent, bool());
MOCK_METHOD1(Return, double(int kilometers));
MOCK_METHOD0(Clean, void());
};
#endif
Edit1: As suggested I have tried to use the reference (&) of Car*.
This kills the error I've stated above, but leaves me with some other errors:
error: cannot declare field ‘AdminTest::car’ to be of abstract type ‘Car’
Car car;
error: ‘class Car’ has no member named ‘gmock_GetLicencePlate’

car is a pointer to Car. Its type is: Car*. In order to call Car members from a Car*, you must dereference the pointer. This is automatically done when using the car->x syntax, which is equivalent to (*car).x.
I assume that EXPECT_CALL requires a non-pointer argument. Therefore, you can get a reference to car and pass it to the macro:
Car& car_ref = *car;
EXPECT_CALL(car_ref, GetLicencePlate()).WillOnce(Return("fh-01-ict"));

First is the pointer issue, that Vittorio already said but, also, you need to mock Car object to use EXCEPT_CALL:
class MockCar : public Car{
// Here I assume that original method is const
MOCK_CONST_METHOD0(GetLicencePlate);
}
TEST(RentalAdministrationAdd, test_add_car_to_empty_administration)
{
RentalAdministration admin;
MockCar car;
EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
EXPECT_TRUE(admin.Add(&car));
}
You can see in my examle that you are not using real car object but a Mock one where you can control access and force return values

I have found the solution.
For anyone wondering: Inside one class (RentalAdministration) I had included the Car.h file from the cars folder. (like #include "cars/Car.h")
However, for the test a different Car.h should be used. Therefore, changing to #include "Car.h" made it work.

Related

Returning an Array of Structs Solidity

I want to return an array of structs because i want to output all my data.
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
contract MyContract
{
mapping(uint256 => People) dataList;
uint256[] countArr;
struct People{
string name;
uint256 favNum;
}
In this function, i set the data of my struct object and then include it in my mapping.
function setPerson(string memory _name,uint256 _id, uint256 _favNum) public {
dataList[_id]= People(_name,_favNum);
countArr.push(_id);
}
This function here gets me the data of my specified struct object.
function getPerson(uint _id) public view returns(string memory,uint256){
return (dataList[_id].name, dataList[_id].favNum);
}
Now here is the function i think that is causing me trouble because in this function i want to return not the data of a single People object but all of my data and whenever i run this function on my REMIX IDE console it shows me the error: call to MyContract.getAllData errored: VM error: revert. revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
function getAllData()public view returns(People[] memory){
uint256 count = countArr.length;
uint256 i = 0;
People[] memory outputL= new People[](count);
while(count >= 0){
(string memory nam,uint256 num) = getPerson(count-1);
People memory temp = People(nam,num);
outputL[i]=temp;
count--;
i++;
}
return outputL;
}
}
Can anyone help and explain what is wrong and how can i get it running?
This version of the getAllData function works as you expect:
function getAllData() public view returns (People[] memory) {
uint256 count = countArr.length;
People[] memory outputL = new People[](count);
while(count > 0) {
count--;
(string memory nam, uint256 num) = getPerson(countArr[count]);
People memory temp = People(nam, num);
outputL[count] = temp;
}
return outputL;
}
Feel free to ask if you have any questions about the changes.

How to resolve warning "ignoring return value of function declared with 'warn_unused_result' attribute"

I'm writing test automation in QT. I'am using QTest::qWaitFor to wait until the event loop switches to another tab in UI.
QTest::qWaitFor([tabs, &currentIdx]() {
    currentIdx = tabs->currentIndex();
    return currentIdx == 1;
}, 5000);
Each time I'am using such construction following warning appears:
ignoring return value of function declared with 'warn_unused_result' attribute
I spent hours dealing with it but no result. I think the problem is the way functions consume returned values from lambda expressions. Is there any workaround?
Issue is not with lambda, but your usage:
You should use/check return value of qWaitFor (to know if timeout happens):
if (QTest::qWaitFor([tabs, &currentIdx]() {
currentIdx = tabs->currentIndex();
return currentIdx == 1;
}, 5000)) {
// OK.
// ...
} else {
// timeout.
// ...
}

Inheritance Linking throws 'undefined reference to...' C++

I've writing a "big" Indexs project in C++, that is difficult for me meanwhile...
While i was trying to create an inheritance between 2 clases:
ZonalPermutant wich inherit from Permutant
i got the following error:
error:
g++ -Wall -std=c++0x lib/PermZone.o lib/VectorSpace.o lib/Vector.o lib/PermZoneMain.o lib/Permutant.o lib/ZonalPermutant.o -o permZone
lib/Permutant.o: In function `Permutant::Permutant()':
Permutant.cpp:(.text+0x20): undefined reference to `vtable for Permutant'
lib/Permutant.o: In function `Permutant::Permutant(long)':
Permutant.cpp:(.text+0x8e): undefined reference to `vtable for Permutant'
lib/Permutant.o: In function `Permutant::Permutant(PList<long>*, long)':
Permutant.cpp:(.text+0x10c): undefined reference to `vtable for Permutant'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant()':
ZonalPermutant.cpp:(.text+0x41): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant(long)':
ZonalPermutant.cpp:(.text+0xa4): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant(PList<long>*, PList<long>*, long)':
ZonalPermutant.cpp:(.text+0x13e): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::~ZonalPermutant()':
ZonalPermutant.cpp:(.text._ZN14ZonalPermutantD2Ev[_ZN14ZonalPermutantD5Ev]+0x2f): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o:(.rodata._ZTI14ZonalPermutant[_ZTI14ZonalPermutant]+0x10): undefined reference to `typeinfo for Permutant'
collect2: error: ld returned 1 exit status
Makefile:17: recipe for target 'permZone' failed
make: *** [permZone] Error 1
I know it is probably that the linking in my makefile could be wrong written. So i will show you my makefile:
makefile:
CC = g++
STD = -std=c++0x
DIR = -I .
CFLAGS = -Wall -c $(STD)
LFLAGS = -Wall $(STD)
BRUTEFORCE_LIB = lib/VectorSpace.o lib/Vector.o lib/BruteForce.o lib/BruteForceMain.o
PIVOT_LIB = lib/VectorSpace.o lib/Vector.o lib/Pivot.o lib/PivotMain.o
PERM_LIB = lib/Permutants.o lib/VectorSpace.o lib/Vector.o lib/PermMain.o lib/Permutant.o
BASICS_LIB = lib/MajorOrderHeap.o lib/MinorOrderHeap.o lib/PList.o lib/OList.o lib/PList.o lib/HeapElement.o lib/Random.o lib/Tokenizer.o lib/Matrix.o
PERMZONE_LIB = lib/PermZone.o lib/VectorSpace.o lib/Vector.o lib/PermZoneMain.o lib/Permutant.o lib/ZonalPermutant.o
default: permZone
#EXE's
#PermZone
permZone: $(PERMZONE_LIB)
$(CC) $(LFLAGS) $(PERMZONE_LIB) -o permZone
lib/PermZoneMain.o: src/PermZoneMain.cpp src/Index.h src/Space.h
$(CC) src/PermZoneMain.cpp $(CFLAGS) -o lib/PermZoneMain.o
lib/PermZone.o: src/Indexes/PermZone/PermZone.h src/Indexes/PermZone/PermZone.cpp $(BASICS_LIB)
$(CC) src/Indexes/PermZone/PermZone.cpp $(CFLAGS) -o lib/PermZone.o
lib/ZonalPermutant.o: src/Indexes/PermZone/ZonalPermutant.cpp src/Indexes/PermZone/ZonalPermutant.h lib/Permutant.o
$(CC) src/Indexes/PermZone/ZonalPermutant.cpp $(CFLAGS) -o lib/ZonalPermutant.o
lib/Permutant.o: src/Element.h src/Indexes/Permutants/Permutant.h src/Indexes/Permutants/Permutant.cpp $(BASICS_LIB)
$(CC) src/Indexes/Permutants/Permutant.cpp $(CFLAGS) -o lib/Permutant.o
and now the h and cpp files (i know its a lot of text):
Permutant.h:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "../../Element.h"
#include "../../Basics/PList.h"
#ifndef PERMUTANT_H
#define PERMUTANT_H
class Permutant : public Element
{
protected:
PList<long> permutation;//stores only ID's
public:
bool isInverted;
Permutant();
~Permutant();
Permutant(long id);
Permutant(PList<long>* permutation,long id);
void setPermutation(PList<long>* permutation);
PList<long> getPermutation();
void invertPermutation();
long distance(Permutant* other);
string toString();
static long spearmanFootRule(Permutant &p1, Permutant &p2);
};
#endif // PERMUTANT_H
Permutant.cpp:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "Permutant.h"
//I dont like this trick.. but i have to use it for future distance calculations
typedef long (*P_distance)(Permutant&,Permutant&);//i hope it doesn't cause problems with inheritance :D
P_distance p_distance;
Permutant::Permutant()
{
isInverted = false;
p_distance = &spearmanFootRule;
}
Permutant::Permutant(long id)
{
this->id = id;
isInverted = false;
p_distance = &spearmanFootRule;
}
Permutant::Permutant(PList<long>* permutation,long id)
{
this->id = id;
isInverted = false;
this->permutation = *permutation;
p_distance = &spearmanFootRule;
}
void Permutant::setPermutation(PList<long>* permutation)
{
this->permutation = *permutation;
}
PList<long> Permutant::getPermutation()
{
return this->permutation;
}
void Permutant::invertPermutation()
{
PList<long> *inverted_permutation = new PList<long>(permutation.size());
inverted_permutation->toArray();
for (long i = 0; i < permutation.size(); ++i)
{
(*inverted_permutation)[permutation[i]] = i;
}
this->setPermutation(inverted_permutation);
this->isInverted = !isInverted;
}
long Permutant::distance(Permutant* other)
{
return p_distance(*this, *other);
}
string Permutant::toString()
{
ostringstream oss;
oss << ((isInverted)?"i":"")<< " " << permutation.toString();
return oss.str();
}
long Permutant::spearmanFootRule(Permutant &p1, Permutant &p2)
{
long dist = 0;
if(p1.isInverted == p2.isInverted)
{
p1.invertPermutation();
}
for (int i = 0; i < p2.getPermutation().size(); ++i)
{
dist+= abs(p1.getPermutation().get(p2.getPermutation().get(i)) - i);
}
return dist;
}
ZonalPermutant:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "../Permutants/Permutant.h"
#ifndef ZONAL_PERMUTANT_H
#define ZONAL_PERMUTANT_H
class ZonalPermutant :public Permutant
{
private:
PList<long> zones;
public:
ZonalPermutant();
~ZonalPermutant(){};
ZonalPermutant(long id);
ZonalPermutant(PList<long>* permutation, PList<long>* zones, long id);
void setZones(PList<long>* zones);
PList<long> getZones();
long distance(Permutant* other);
string toString();
};
#endif // ZONAL_PERMUTANT_H
ZonalPermutant.cpp:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "ZonalPermutant.h"
ZonalPermutant::ZonalPermutant() : Permutant()
{}
ZonalPermutant::ZonalPermutant(long id) : Permutant(id)
{}
ZonalPermutant::ZonalPermutant(PList<long>* permutation, PList<long>* zones, long id) : Permutant(permutation,id)
{
this->zones = *zones;
}
void ZonalPermutant::setZones(PList<long>* zones)
{
this->zones = *zones;
}
PList<long> ZonalPermutant::getZones()
{
return this->zones;
}
long ZonalPermutant::distance(Permutant* other)
{
return 0;
}
string ZonalPermutant::toString()
{
return ":D";
}
Every of the other classes used in my code are good implemented and they dont create any problem at the moment of compiling and linking others Indexes...
If there is any problem in my code or way to programm, i would like that you say that to me :).
Thanks you for the help.
Try declaring your destructors virtual (usually no harm done if not necessary), and/or add their implementations to .cpp files. In my experience
Undefined reference to `vtable for Permutant'
hints to this direction.

Delphi and C/C++ DLL Struct vs.Record

I previously asked a question about a delphi and a C/C++ DLL.
I have now another question about a record / struct.
The DLL should be able to dynamically CHANGE the VALUE of the pointer vars from the MainAPP.
My delphi MAINAPP has the following record:
type MyRec = record
MyInteger : Pointer;
MyWideString : pwidechar;
MyString : pchar;
MyBool : Pointer
end;
type
TMyFunc = function ( p : pointer ): pointer; stdcall;
procedure test;
var
MyFunction : TMyFunc;
TheRecord : MyRec;
AnInteger : Integer;
AWideString : WideString;
AString : String;
ABool : Bool;
begin
AnInteger := 1234;
AWideString := 'hello';
AString := 'hello2';
ABool := TRUE;
TheRecord.MyInteger := #AnInteger;
TheRecord.MyWideString := pwidechar(AWideString);
TheRecord.AString := pchar(AString);
TheRecord.ABool := #ABool;
[...]
#MyFunction := GetProcAddress...
[...]
MyFunction (#TheRecord); // now the DLL should be able to change the values dynamically.
MessageBoxW (0, pwidechar(AWideString), '', 0); // Show the results how the DLL changed the String to...
end;
C/C++ Code (just example)
typedef struct _TestStruct{
void *TheInteger; // Pointer to Integer
wchar_t *TheWideString; // Pointer to WideString
char *TheAnsiString; // Pointer to AnsiString
bool *TheBool // Pointer to Bool
}TestStruct;
__declspec(dllexport) PVOID __stdcall MyExportedFunc (TestStruct *PTestStruct)
{
MessageBoxW(0 ,PTestStruct->TheWideString, L"Debug" , 0); // We read the value.
PTestStruct->TheWideString = L"Let me change the value here.";
return 0;
}
For some reasons it crashes etc.
What do I do wrong?
Thanks for help.
This probably isn't the cause of the crash at the point where the C++ code assigns to the TheWideString pointer, but I do see a problem of expectations...
I notice that you're putting the address of the string data that the Delphi AWideString variable points to into the MyWideString field of the record. You pass the record to the C++ function, which assigns a new pointer value to the TheWideString/MyWideString field of the record. When execution returns to the Delphi code, you output the contents of the AWideString variable.
Your comments indicate that you expect the contents of the AWideString variable to be changed by the C++ function, but that's not what will happen.
The C++ function changes the field in the structure. It does nothing to the memory location that the field previously pointed to. The data that AWideString points to will not be affected by the C++ function.
If the C++ code copied data into the address contained in the field, then it would overwrite the string data that AWideString points to. Since AWideString is a Delphi managed string, and the C++ function would be copying more data to that string memory area than the original string had allocated space for, copying data in the C++ function would write past the end of the Delphi allocated string buffer and probably corrupt the Delphi heap. A crash may occur some time later. So it's a good that you're only assigning the pointer to the field, not copying the data! ;>
To see what the C++ function changed, your Delphi code should output the contents of the MyWideString field of the record after the call to the C++ function.
You are mismanaging the string fields. PWideChar and PChar are not the same thing as "pointer to WideString" and "pointer to AnsiString". Delphi has PWideString (WideString*) and PAnsiString (AnsiString*) types for that purpose instead. You should also use Delphi's PInteger (int*) and PBoolean (bool*) types instead of Pointer (void*). Delphi and C++ are both type-safe languages. Stay away from untyped pointers when possible, your code will be better for it.
type
PMyRec = ^MyRec;
MyRec = record
 MyInteger    : PInteger;
 MyWideString : PWideString;
 MyAnsiString : PAnsiString;
  MyBool       : PBoolean;
end;
 TMyFunc = function ( p  : PMyRec ): Integer; stdcall;
procedure test;
var
 MyFunction  : TMyFunc;
 TheRecord   : MyRec;
 AnInteger   : Integer;
 AWideString : WideString;
 AAnsiString : AnsiString;
 ABool       : Bool;
begin
 AnInteger                := 1234;
 AWideString              := 'hello';
 AAnsiString              := 'hello2';
 ABool                    := TRUE;
 TheRecord.MyInteger      := #AnInteger;
TheRecord.MyWideString   := #AWideString;
 TheRecord.MyAnsiString   := #AAnsiString;
 TheRecord.MyBool         := #ABool;
 [...]
 #MyFunction := GetProcAddress...
 [...]
 MyFunction  (#TheRecord);
 MessageBoxW (0, PWideChar(AWideString), '', 0);
end;
.
typedef struct _MyRec
{
int    *MyInteger;    // Pointer to Integer
WideString *MyWideString; // Pointer to WideString
AnsiString *MyAnsiString; // Pointer to AnsiString  
bool     *MyBool;       // Pointer to Bool
} MyRec, *PMyRec;
__declspec(dllexport) int __stdcall MyExportedFunc (PMyRec PRec)
{
MessageBoxW(NULL, PRec->MyWideString->c_bstr(), L"Debug" , 0);
    *(PRec->MyWideString) = L"Let me change the value here.";
return 0;
}
With that said, it can be very dangerous to manipulate AnsiString (and UnicodeString) values across a DLL boundary like this, especially if the EXE and DLL are written in different versions of Delphi/C++Builder due to RTL differences, memory manager differences, payload layout differences, etc. WideString is OK to pass around, though, because it's memory and layout are controlled by the OS, not the RTL.
Synchronize fields order in the structures. You can break memory heap using wrong pointers. Also, check alignment both in Delphi and C++.

ccGridSize in cocos2d

While using ccWave, one of the parameters was grid and it showed that the value should be of type ccGridSize.
I would like to know what a ccGridSize is..
What value should be given for a ccGridSize variable?
The code for ccWaves is as follows...
[CCWaves actionWithWaves:<(int)> amplitude:<(float)>
horizontal:<(BOOL)> vertical:<(BOOL)>
grid:<(ccGridSize)> duration:<(ccTime)>];
What value can be given in the place of the parameter grid???
Cocos2d defines ccGridSize as:
typedef struct _ccGridSize
{
NSInteger x;
NSInteger y;
} ccGridSize;
And provides an inline factory function:
static inline ccGridSize ccg(const NSInteger x, const NSInteger y);
So you can write your call as:
... grid:ccg(gridSizeX, gridSizeY)
Where gridSizeX and gridSizeY define a number of grid columns and rows for your effect.
From cctypes.h:
typedef struct _ccGridSize
{
       NSInteger   x;
        NSInteger   y;
} ccGridSize;
So it's just a couple of ints to state how big every step is of the grid that you are going to animate.