Comparison of Arrays in Google Test

Comparison of arrays in google test?

I would really suggest looking at Google C++ Mocking Framework. Even if you don't want to mock anything, it allows you to write rather complicated assertions with ease.

For example

//checks that vector v is {5, 10, 15}
ASSERT_THAT(v, ElementsAre(5, 10, 15));

//checks that map m only have elements 1 => 10, 2 => 20
ASSERT_THAT(m, ElementsAre(Pair(1, 10), Pair(2, 20)));

//checks that in vector v all the elements are greater than 10 and less than 20
ASSERT_THAT(v, Each(AllOf(Gt(10), Lt(20))));

//checks that vector v consist of
// 5, number greater than 10, anything.
ASSERT_THAT(v, ElementsAre(5, Gt(10), _));

There's plenty of matchers for every possible situations, and you can combine them to achieve almost anything.

Did I tell you that ElementsAre needs only iterators and size() method on a class to work? So it not only works with any container from STL but with custom containers also.

Google Mock claims to be almost as portable as Google Test and frankly I don't see why you wouldn't use it. It is just purely awesome.

How does gtest compare the values in two arrays?

You don't need to add a dependency on googlemock if you don't want, you could write your own simple function that returns a testing::AssertionResult, e.g.

    template<typename T, size_t size>
::testing::AssertionResult ArraysMatch(const T (&expected)[size],
const T (&actual)[size]){
for (size_t i(0); i < size; ++i){
if (expected[i] != actual[i]){
return ::testing::AssertionFailure() << "array[" << i
<< "] (" << actual[i] << ") != expected[" << i
<< "] (" << expected[i] << ")";
}
}

return ::testing::AssertionSuccess();
}

Then in your test, call:

    EXPECT_TRUE(ArraysMatch(two_sorted, two));

Google test compare pointer-arrays' content

The gtest matchers that you are attempting to use, testing::UnorderedElementsAreArray
and testing::ContainerEq, are applicable only to objects that are STL-style containers.
See the documentation.

Your foo is a C-style array of int. Your
expected_result and result are pointers to int. None of these is an STL-style container,
and the pointers are not containers in any sense.

The question you want to test is whether the N integers beginning at expected_result
are any permutation of the N integers beginning at result, where N is the number
of elements in the array foo.

The only way to test that question with a single EXPECT... call
is to expect a true result when you call some function that determines exactly that
question with arguments result and expected_result and returns a boolean verdict (or something convertible to a boolean verdict).

The C++ Standard library (C++11 or later) provides a generic function for just such a purpose: std::is_permutation,
which you would apply as illustrated:

#include <gtest/gtest.h>
#include <algorithm>

int * reverse(int in[], std::size_t len)
{
int * permute = new int[len];
std::reverse_copy(in,in + len,permute);
return permute;
}

TEST(reverse,is_correct)
{
int foo[] {1,2,3};
int* expected_result = foo;
std::size_t len = sizeof(foo)/sizeof(foo[0]);
int* result = reverse(foo,len);
EXPECT_TRUE(std::is_permutation(result,result + len,expected_result));
delete [] result;
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Output:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from reverse
[ RUN ] reverse.is_correct
[ OK ] reverse.is_correct (0 sec)
[----------] 1 test from reverse (0 sec total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.

Note that the use of C-style arrays obliges you manage heap memory by
hand:

    int * permute = new int[len];
...
...
delete [] result

which in C++ is a gratuitous invitation to heap-leak or heap-corruption
bugs. For fixed size arrays, use std::array.
For dynamically sized arrays, use std::vector.
This is better:

#include <gtest/gtest.h>
#include <algorithm>
#include <array>

template<std::size_t N>
std::array<int,N> reverse(std::array<int,N> const & in)
{
std::array<int,N> permute;
std::reverse_copy(in.begin(),in.end(),permute.begin());
return permute;
}

TEST(reverse,is_correct)
{
std::array<int,3> foo {1,2,3};
auto result = reverse(foo);
EXPECT_TRUE(std::is_permutation(result.begin(),result.end(),foo.begin()));
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

And, since std::array and std::vector are STL-style containers, your
orginal attempt would have worked had you used either one:

#include <gmock/gmock.h>
#include <algorithm>
#include <array>

template<std::size_t N>
std::array<int,N> reverse(std::array<int,N> const & in)
{
std::array<int,N> permute;
std::reverse_copy(in.begin(),in.end(),permute.begin());
return permute;
}

TEST(reverse,is_correct)
{
std::array<int,3> foo {1,2,3};
auto result = reverse(foo);
EXPECT_THAT(foo,testing::UnorderedElementsAreArray(result));
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Compare containers with GoogleTest

You're just missing gtest's testing namespace qualifier:

EXPECT_THAT(test1, ::testing::ContainerEq(test2));

Google Mock matching an array

First of all, I did not reproduce your problem. The following example compiles and the test passes:

class ServerFake {
public:
MOCK_METHOD2(sendInternal, void(uint8_t data[], uint8_t size));
};

// If only possible, I recommend you to use std::vector instead of raw array
class ServerFake2 {
public:
MOCK_METHOD1(sendInternal, void(std::vector<uint8_t> data));
};

MATCHER_P2(HasBytes, bytes, size, "") {
// unnecessary assignment, I think ...
uint8_t * dataToCheck = arg;
bool isMatch = (memcmp(dataToCheck, bytes, size) == 0);
return isMatch;
}

using ::testing::ElementsAre;

TEST(xxx, yyy) {

ServerFake* serverFake = new ServerFake;
ServerFake2* serverFake2 = new ServerFake2;

uint8_t expectedMessageData[3] = { 0x08, 0xda, 0xff };
std::vector<uint8_t> expectedMessageData2({ 0x08, 0xda, 0xff });

EXPECT_CALL(*serverFake, sendInternal(HasBytes(expectedMessageData, 3), 3)).Times(1);
// the code below compiles and passes as well! However, I didn't check why;
// EXPECT_CALL(*serverFake, sendInternal(testing::_,3))
// .With(testing::Args<0, 1>(ElementsAre(0x08, 0xda, 0xff)))
// .Times(1);
serverFake->sendInternal(expectedMessageData, 3);

// much better, do like this!
EXPECT_CALL(*serverFake2, sendInternal(ElementsAre(0x08, 0xda, 0xff))).Times(1);
serverFake2->sendInternal(expectedMessageData2);

delete serverFake;
delete serverFake2;
}

Second, ElementsAre officially does not support C-style arrays, according to this topic. If you really cannot change your method signature, and you really wish to use ElementsAre on your raw array, you can use the hack proposed in that topic. Cheers.

Comparing two 2D arrays with different length for matches

I would suggest the following changes:

(1) As you are using data from single columns, you don't need the variables y and j.

sheetdata[x][0] will be the value of the string in the xth row of the array.

And sheet1data[i][0] will be the value of the string in the ith row of the array.

(2) Arrays are zero-based, i.e. the first "row" in the array is 0. Where as the first row on the sheet is 1.

So when writing to the sheet for the xth row in the array, you need to write to the x+1 th row on the sheet.

Here is what the for loops will look like with these changes:

  for (var x = 0; x < sheetdata.length; x++) {
for(var i = 0; i < sheet1data.length; i++){
if (sheetdata[x][0] == sheet1data[i][0]){
sheet1.getRange(x + 1, 2).setValue("Already in other Spreadsheet");
match.push(sheetdata[x][0]);
};
};
};

And as Tanaike-san said, lastRow1 should be used in calculating range1 and not lastRow:

  var range1 = sheet1.getRange(1, 2, lastrow1, 1);

Fastest method to compare two arrays for find equal value on Google app script

Thank you @sandy-good !,
If it is an 1D array we can use indexOf() method.

for(var line in firstArray) 
{
var isMatched = secondArray.indexOf(firstArray[line]);
if (isMatched !== -1)
{
var matchedValFromArray2 = secondArray[isMatched]
};
}

If you want to compare 2D array (or two rows of a spreadsheet), you can use .join() method.

for(var i in firstArray)
{
var duplicate = false;
for(var j in secondArray)
{
if(firstArray[i].join() == secondArray[j].join())
{
var matchedValFromArray2 = firstArray[i];
break;
}
}
}

Compare Eigen matrices in Google Test or Google Mock

Why not use the isApprox or isMuchSmallerThan member functions of Eigen Matrix types?

The documentation of these above functions are available here

So for most cases ASSERT_TRUE(C_actual.isApprox(C_expect)); is what you need. You can also provide a precision parameter as the second arguement to isApprox.



Related Topics



Leave a reply



Submit