I'm a beginner at JUnit, I got a problem when I am learning it. I did a lot of searches, but still can't find the answer.
The version of JUnit Jupiter I'm using is 5.3.0-M1.
I'm doing tests on some sorting algorithms. I'd like to test if they are correct, and the performance on different arrays with different length. Here is my solution.
#BeforeAll
Generated a random unsorted array as source, and a target array which is a sorted.
#BeforeEach
Copy the unsorted source to a new array as inputs ready for the test.
Each #Test method sorts the inputs array and compares it with target, so I know if it is correct, and the IDE will tell me how much time it cost.
The problem is: I have to manually change the length every time, and test it again.
I wonder if there is a way to setup up the test, so it will run for each different length I set.
For example, pass an array like [16, 32, 64, ...] as different length I want to test with.
I know I can pass parameters to #Test method, but then I have to generate source and target multiple times in each #Test.
(Sorry for my bad English, I hope I have explained the problem clearly enough.)
Here is my test class looks like:
class SortingTest {
static int length = 512; // manually change every time.
// static int length = 1024;
// static int length = 2048;
// static int length = 4096;
static int[] source;
static int[] target;
static int[] inputs;
#BeforeAll
static void beforeAllSort() {
source = MintArray.generateIntArray(length);
target = new int[length];
inputs = new int[length];
System.arraycopy(source, 0, target, 0, source.length);
Arrays.sort(target);
System.out.println("[SORT] Array Length : [" + length + "]");
System.out.println("[SORT] Source Array : " + Arrays.toString(source));
System.out.println("[SORT] Target Array : " + Arrays.toString(target));
}
#BeforeEach
void beforeEachSort() {
System.arraycopy(source, 0, inputs, 0, source.length);
System.out.println();
}
#Test
#DisplayName("Bubble Sort")
void bubbleSort() {
System.out.println("[SORT] Bubble Sort");
inputs = new BubbleSort().bubbleSort(inputs);
assertArrayEquals(inputs, target);
}
#Test
#DisplayName("Insertion Sort")
void insertionSort() {
System.out.println("[SORT] Insertion Sort");
inputs = new InsertionSort().insertionSort(inputs);
assertArrayEquals(inputs, target);
}
#Test
.......more sort
}
Related
The official flutter tutorial on C/C++ interop through ffi only touches on calling a C++ function and getting a single return value.
Goal
What if I have a data buffer created on C/C++ side, but want to deliver to dart/flutter-side to show?
Problem
With #MilesBudnek 's tip, I'm testing Dart's FFI by trying to have safe memory deallocation from Dart to C/C++. The test reuses the official struct sample .
I could get the Array as a dart Pointer, but it's unclear to me how to iterate the array as a collection easily.
Code
I'm implementing a Dart-side C array binding like this:
In struct.h
struct Array
{
int* array;
int len;
};
and a pair of simple allocation/deallocation test functions:
struct Array* get_array();
int del_array(struct Array* arr);
Then on Dart side in structs.dart:
typedef get_array_func = Pointer<Array> Function();
typedef del_array_func = void Function(int arrAddress);
...
final getArrayPointer = dylib.lookup<NativeFunction<get_array_func>>('get_array');
final getArray = getArrayPointer.asFunction<get_array_func>();
final arrayPointer = getArray();
final array = arrayPointer.ref.array;
print('array.array: $array');
This gives me the print out
array.array: Pointer<Int32>: address=0x7fb0a5900000
Question
Can I convert the array pointer to a List easily? Something like:
final array = arrayPointer.ref.array.toList();
array.forEach(index, elem) => print("array[$idx]: $elem");
======
Old Question (you can skip this)
Problem
It's unclear to me how to retrieve this kind of vector data from C/C++ by dart/flutter.
Possible solutions
More importantly, how to push data from C++ side from various threads?
If there is no builtin support, off the top of my head I'd need to implement some communication schemes.
Option #1: Networking
I could do network through TCP sockets. But I'm reluctant to go there if there are easier solutions.
Option #2: file I/O
Write data to file with C/C++, and let dart/flutter poll on the file and stream data over. This is not realtime friendly.
So, are there better options?
Solved it.
According to this issue, the API asTypedList is the way to go.
Here is the code that works for me
final getArrayPointer = dylib.lookup<NativeFunction<get_array_func>>('get_array');
final getArray = getArrayPointer.asFunction<get_array_func>();
final arrayPointer = getArray();
final arr = arrayPointer.ref.arr;
print('array.array: $arr');
final arrReal = arr.asTypedList(10);
final arrType = arrReal.runtimeType;
print('arrReal: $arrReal, $arrType');
arrReal.forEach((elem) => print("array: $elem"));
This gives me:
array.array: Pointer<Int32>: address=0x7f9eebb02870
arrReal: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], Int32List
array: 0
array: 1
array: 2
array: 3
array: 4
array: 5
array: 6
array: 7
array: 8
array: 9
asTypedList will only work with pointers that relate to TypedData.
there are other cases where, for example, you want to convert an Pointer<UnsignedChar> to a Uint8List, in this case you can:
use an extension and then either cast the Pointer<UnsignedChar to a Pointer<Uint8> and then use asTypedList. In this case you have to make sure the pointer is not freed while the Uint8List is still referenced.
extension UnsignedCharPointerExtension on Pointer<UnsignedChar> {
Uint8List? toUint8List(int length) {
if (this == nullptr) {
return null;
}
return cast<Uint8>().asTypedList(length);
}
}
use an extension and don't cast the pointer but copy it manually. In this case you can free the pointer after you get the Uint8List
extension UnsignedCharPointerExtension on Pointer<UnsignedChar> {
Uint8List? toUint8List(int length) {
if (this == nullptr) {
return null;
}
final Uint8List list = Uint8List(length);
for (int i = 0; i < length; i++) {
list[i] = this[i];
}
return list;
}
}
I have an array of values e.g. 1, 4, 7, 2.
I also have another array of values and I want to add its values to this first array, but only when they all are different from all values that are already in this array. How can I check it? I've tried many types of loops, but I always ended with an iteration problem.
Could you please tell me how to solve this problem? I code in c++.
int array1[7] = {2,3,7,1,0};
int val1 = rand() % 10;
int val2 = rand() % 10;
int array2[2] = {val1, val2};
and I am trying to put every value from array2 into array1. I tried loop
for (int x:array2)
{
while((val1 && val2) == x)
{
val1 = rand() % 10;
val2 = rand() % 10;
}
}
and many more, but still cannot figure it out. I have this problem because I may have various number of elements for array2. So it makes this "&&" solution infinite.
It is just a sample to show it more clearly, my code has much more lines.
Okay, you have a few problems here. If I understand the problem, here's what you want:
A. You have array1 already populated with several values but with space at the end.
1. How do you identify the number of entries in the array already versus the extras?
B. You have a second array you made from two random values. No problem.
You want to append the values from B to A.
2. If initial length of A plus initial length of B is greater than total space allocated for A, you have a new problem.
Now, other people will tell you to use the standard template library, but if you're having problems at this level, you should know how to do this yourself without the extra help from a confusing library. So this is one solution.
class MyArray {
public:
int * data;
int count;
int allocated;
MyArray() : data(nullptr), count(0), allocated(0) {}
~MyArray() { if (data != nullptr) free(data); }
// Appends value to the list, making more space if necessary
void add(int value) {
if (count >= allocated) {
// Not enough space, so make some.
allocated += 10;
data = (data == nullptr) malloc(allocated * sizeof(int))
: realloc)data, allocated * sizeof(int));
}
data[count++] = value;
}
// Adds value only if not already present.
void addUnique(int value) {
if (indexOf(value) < 0) {
add(value);
}
}
// Returns the index of the value, if found, else -1
int indexOf(int value) {
for (int index = 0; index < count; ++index) {
if (data[index] == value) {
return index;
}
}
return -1;
}
}
This class provides you a dynamic array of integers. It's REALLY basic, but it teaches you the basics. It helps you understand about allocation / reallocating space using old-style C-style malloc/realloc/free. It's the sort of code I was writing back in the 80s.
Now, your main code:
MyArray array;
array.add(2);
array.add(3);
array.add(7);
// etc. Yes, you could write a better initializer, but this is easy to understand
MyArray newValues;
newValues.add(rand() % 10);
newValues.add(rand() % 10);
for (int index = 0; index < newValues.count; ++index) {
array.addUnique(newValues.data[index]);
}
Done.
The key part of this is the addUnique function, which simply checks first whether the value you're adding already is in the array. If not, it appends the value to the array and keeps track of the new count.
Ultimately, when using integer arrays like this instead of the fancier classes available in C++, you HAVE TO keep track of the size of the array yourself. There is no magic .length method on int[]. You can use some magic value that indicates the end of the list, if you want. Or you can do what I did and keep two values, one that holds the current length and one that holds the amount of space you've allocated.
With programming, there are always multiple ways to do this.
Now, this is a lot of code. Using standard libraries, you can reduce all of this to about 4 or 5 lines of code. But you're not ready for that, and you need to understand what's going on under the hood. Don't use the fancy libraries until you can do it manually. That's my belief.
I am trying to port a JS algorithm to C++, to see if I can improve the perfs, but I'm facing a huge performance bottleneck on populating v8 arrays.
Here is a snippet that reproduce just the array populating. I create an array of 800k items, each item being an array of 17 numbers. This algo takes 3secs to execute on my machine, which is quite huge.
Is there anyway to speed it up?
#include <node.h>
namespace demo {
using namespace v8; // just for lisibility of the example
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Array> array = Array::New(isolate, 800000);
for (int i = 0; i < 800000; ++i) {
Local<Array> line = Array::New(isolate, 17);
for (int j = 0; j < 17; ++j) {
line->Set(j, Number::New(isolate, i * 100 + j));
}
array->Set(i, line);
}
args.GetReturnValue().Set(array);
}
void Init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(parser, Init)
}
Creating JS objects (and interacting with them) from C++ is more expensive than doing it from JS. This can easily offset performance gains from the rest of the C++ code.
You can work around this by communicating via a Buffer (the serialization overhead will typically be lower than the above). More importantly, this will also let you do the work off the main v8 thread.
If you're only dealing with numbers, this should be relatively straightforward using Buffer.readIntLE (or similar methods). You could also encode the array's length into the first few bytes of the buffer. Here's what the JS side of things could look like:
var buf = new Buffer(/* Large enough to contain your serialized data. */);
// Function defined in your C++ addon.
addon.populate(buf, function (err) {
if (err) {
// Handle C++ error.
return;
}
// At this point, `buf` contains the serialized data. Deserialization
// will depend on the chosen serialization format but a reasonable
// option could be the following:
var arr = [];
var pos = 4;
var size = buf.readInt32LE(0);
while (size--) {
var subarr = new Array(17);
for (var i = 0; i < 17; i++) {
subarr[i] = buf.readInt32LE(pos);
pos += 4;
}
arr.push(subarr);
}
// `arr` now contains your decoded data.
});
The C++ part of the code would keep a reference to buf's data (a char *) and populate it inside a worker thread (see nan's AsyncWorker for a convenient helper).
As mtth said, working with JS arrays in C++ is expensive. Using a buffer would work, but you can also use TypedArrays. These are accessible from C++ as pointers to contiguous, aligned blocks of memory, which makes them easy to work with and fast to iterate over.
See https://stackoverflow.com/a/31712512/1218408 for some info on how to access their contents.
I am working on bridging between a C++ class and Swift. I know I can only interface with c and Objective C so I am writing a wrapping function in c.
I need to return some data that I have packaged in a structure and with the structure holding an array of unknown length. All this needs to be done with only c to interface with Swift.
My structure looks as follows:
struct Output {
double DataA;
long DataArrayLength;
double *DataArray;
};
I have written the following function in c to package the data:
struct Output* GetData( double InputA) {
struct Output output;
output.DataArrayLength = 100; // The length will only be known at run time and
// once I get into this function.
output.DataArray = new double[output.DataArrayLength];
///
Fill in the data array - some complicated calculations behind this.
output.DataArray[0] = 12345.0;
output.DataArray[99] = 98761.0;
///
return &output; // Getting warning Address of stack associated with local variable 'output' returned.
}
From Swift I can then call
var swoutput = GetData( 1.0)
var count = swoutput.memory.DataArrayLength
My questions are:
Is there a better way do do this? How?
How should I allocate, pass, return the Output struct? I realize the problem with the current method but not sure the best fix.
I still need to release the memory from DataArray. I think I need to do this from the Swift code. How do I do this?
You have to do:
Output* GetData( double InputA) {
Output* output = new Output;
output->DataArrayLength = 100; // The length will only be known at run time and
// once I get into this function.
output->DataArray = new double[output->DataArrayLength];
/// Fill in the data array - some complicated calculations behind this.
output->DataArray[0] = 12345.0;
output->DataArray[99] = 98761.0;
///
return output;
}
And don't forget:
void DeleteOutput(Output* output)
{
if (output == nullptr) {
return;
}
delete [] output->DataArray;
delete output;
}
Okay I basically want to get the ball rolling and write some CPPUnit tests but I have no idea how to go about it. Here I have some code that basically gets a pointer to the Menu Button for the associated button group and position arguments, how would I go about creating a test for this?
CMenuButton* CMenuContainer::GetButton(const enumButtonGroup argGroup, const int32_t argPosition)
{
CMenuButton* pButton = NULL;
if (argGroup < MAX_GROUP_BUTTONS)
{
pButton = m_ButtonGroupList[argGroup].GetButton(argPosition);
}
return pButton;
In reply to #Fabio Ceconello, would it be possible to set some tests for some code like this?
unsigned long CCRC32::Reflect(unsigned long ulReflect, const char cChar)
{
unsigned long ulValue = 0;
// Swap bit 0 for bit 7, bit 1 For bit 6, etc....
for(int iPos = 1; iPos < (cChar + 1); iPos++)
{
if(ulReflect & 1)
{
ulValue |= (1 << (cChar - iPos));
}
ulReflect >>= 1;
}
return ulValue;
}
CppUnit isn't well suited for creating automated tests for user interface. It's more for processing-only units. For instance, let's say you created a replacement for std::vector and want to make sure it behaves like the original one, you could write tests that add elements to both your and the standard implementation, then do some more handling (removing, changing elements, etc.) and after each step check if the two have a consistent result.
For UI I'm not aware of good open source/free tools, but one good commercial tool is TestComplete from Smart Bear, among others.
For the second example you gave, the first thing is to define a validity check for the Reflect() method. You can, for instance, calculate the result of some values by hand to check if the returned value for each of them is what was expected. Or you could use an inverse function that's known to be fully working.
Assuming the first option, you could write the test like this:
class CRC32Test : public CppUnit::TestCase
{
public:
CRC32Test( std::string name ) : CppUnit::TestCase( name ) {}
void runTest()
{
struct Sample {unsigned long ulReflect; char cChar; unsigned long result};
static Sample samples[] =
{
// Put here the pre-calculated values
};
int count = sizeof(samples) / sizeof(Sample);
for (int i = 0; i < count; ++i)
CPPUNIT_ASSERT(subject.Reflect(samples[i].ulReflect, samples[i].cChar) == samples[i].result);
}
private:
CRC32 subject;
};
int main(void)
{
CppUnit::TextUi::TestRunner runner;
runner.addTest(new CppUnit::TestCaller<CRC32Test>("test CRC32", &CRC32::runTest));
runner.run();
}