mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-23 11:57:58 +02:00
add dataspan
This commit is contained in:
116
core/test/CircularFifo.test.cpp
Normal file
116
core/test/CircularFifo.test.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "aare/CircularFifo.hpp"
|
||||
|
||||
using aare::CircularFifo;
|
||||
|
||||
// Only for testing. To make sure we can avoid copy constructor
|
||||
// and copy assignment
|
||||
|
||||
struct MoveOnlyInt {
|
||||
int value{};
|
||||
|
||||
MoveOnlyInt() = default;
|
||||
MoveOnlyInt(int i) : value(i){};
|
||||
MoveOnlyInt(const MoveOnlyInt &) = delete;
|
||||
MoveOnlyInt &operator=(const MoveOnlyInt &) = delete;
|
||||
MoveOnlyInt(MoveOnlyInt &&other) { std::swap(value, other.value); }
|
||||
MoveOnlyInt &operator=(MoveOnlyInt &&other) {
|
||||
std::swap(value, other.value);
|
||||
return *this;
|
||||
}
|
||||
bool operator==(int other) const { return value == other; }
|
||||
};
|
||||
|
||||
TEST_CASE("CircularFifo can be default constructed") { CircularFifo<MoveOnlyInt> f; }
|
||||
|
||||
TEST_CASE("Newly constructed fifo has the right size") {
|
||||
size_t size = 17;
|
||||
CircularFifo<MoveOnlyInt> f(size);
|
||||
CHECK(f.numFreeSlots() == size);
|
||||
CHECK(f.numFilledSlots() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Can fit size number of objects") {
|
||||
size_t size = 8;
|
||||
size_t numPushedItems = 0;
|
||||
CircularFifo<MoveOnlyInt> f(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
MoveOnlyInt a;
|
||||
bool popped = f.try_pop_free(a);
|
||||
CHECK(popped);
|
||||
if (popped) {
|
||||
a.value = i;
|
||||
bool pushed = f.try_push_value(std::move(a));
|
||||
CHECK(pushed);
|
||||
if (pushed)
|
||||
numPushedItems++;
|
||||
}
|
||||
}
|
||||
CHECK(f.numFreeSlots() == 0);
|
||||
CHECK(f.numFilledSlots() == size);
|
||||
CHECK(numPushedItems == size);
|
||||
}
|
||||
|
||||
TEST_CASE("Push move only type") {
|
||||
CircularFifo<MoveOnlyInt> f;
|
||||
f.push_value(5);
|
||||
}
|
||||
|
||||
TEST_CASE("Push pop") {
|
||||
CircularFifo<MoveOnlyInt> f;
|
||||
f.push_value(MoveOnlyInt(1));
|
||||
|
||||
auto a = f.pop_value();
|
||||
CHECK(a == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Pop free and then push") {
|
||||
CircularFifo<MoveOnlyInt> f;
|
||||
|
||||
auto a = f.pop_free();
|
||||
a.value = 5;
|
||||
f.push_value(std::move(a)); // Explicit move since we can't copy
|
||||
auto b = f.pop_value();
|
||||
|
||||
CHECK(a == 0); // Moved from value
|
||||
CHECK(b == 5); // Original value
|
||||
}
|
||||
|
||||
TEST_CASE("Skip the first value") {
|
||||
CircularFifo<MoveOnlyInt> f;
|
||||
|
||||
for (int i = 0; i != 10; ++i) {
|
||||
auto a = f.pop_free();
|
||||
a.value = i + 1;
|
||||
f.push_value(std::move(a)); // Explicit move since we can't copy
|
||||
}
|
||||
|
||||
auto b = f.pop_value();
|
||||
CHECK(b == 1);
|
||||
f.next();
|
||||
auto c = f.pop_value();
|
||||
CHECK(c == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("Use in place and move to free") {
|
||||
size_t size = 18;
|
||||
CircularFifo<MoveOnlyInt> f(size);
|
||||
|
||||
//Push 10 values to the fifo
|
||||
for (int i = 0; i != 10; ++i) {
|
||||
auto a = f.pop_free();
|
||||
a.value = i + 1;
|
||||
f.push_value(std::move(a)); // Explicit move since we can't copy
|
||||
}
|
||||
|
||||
auto b = f.frontPtr();
|
||||
CHECK(*b == 1);
|
||||
CHECK(f.numFilledSlots() == 10);
|
||||
CHECK(f.numFreeSlots() == size-10);
|
||||
f.next();
|
||||
auto c = f.frontPtr();
|
||||
CHECK(*c == 2);
|
||||
CHECK(f.numFilledSlots() == 9);
|
||||
CHECK(f.numFreeSlots() == size-9);
|
||||
}
|
45
core/test/ProducerConsumerQueue.test.cpp
Normal file
45
core/test/ProducerConsumerQueue.test.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
#include "aare/ProducerConsumerQueue.hpp"
|
||||
|
||||
// using arve::SimpleQueue;
|
||||
TEST_CASE("push pop"){
|
||||
|
||||
folly::ProducerConsumerQueue<int> q(5);
|
||||
int a = 3;
|
||||
int b = 8;
|
||||
CHECK(q.sizeGuess() == 0);
|
||||
CHECK(q.write(a));
|
||||
CHECK(q.sizeGuess() == 1);
|
||||
CHECK(q.write(b));
|
||||
CHECK(q.sizeGuess() == 2);
|
||||
int c = 0;
|
||||
|
||||
CHECK(q.read(c));
|
||||
CHECK(c == 3);
|
||||
CHECK(q.sizeGuess() == 1);
|
||||
CHECK(q.read(c));
|
||||
CHECK(c == 8);
|
||||
CHECK(q.sizeGuess() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Cannot push to a full queue"){
|
||||
folly::ProducerConsumerQueue<int> q(3);
|
||||
int a = 3;
|
||||
int b = 4;
|
||||
int c = 0;
|
||||
CHECK(q.write(a));
|
||||
CHECK(q.write(b));
|
||||
CHECK_FALSE(q.write(a));
|
||||
|
||||
//values are still ok
|
||||
CHECK(q.read(c));
|
||||
CHECK(c == 3);
|
||||
CHECK(q.read(c));
|
||||
CHECK(c == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Cannot pop from an empty queue"){
|
||||
folly::ProducerConsumerQueue<int> q(2);
|
||||
int a=0;
|
||||
CHECK_FALSE(q.read(a));
|
||||
}
|
8
core/test/defs.test.cpp
Normal file
8
core/test/defs.test.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
#include "aare/defs.hpp"
|
||||
TEST_CASE("Enum to string conversion"){
|
||||
//By the way I don't think the enum string conversions should be in the defs.hpp file
|
||||
//but let's use this to show a test
|
||||
REQUIRE(toString(DetectorType::Jungfrau) == "Jungfrau");
|
||||
}
|
49
core/test/wrappers.test.cpp
Normal file
49
core/test/wrappers.test.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <aare/DataSpan.hpp>
|
||||
#include <aare/Frame.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
TEST_CASE("Frame") {
|
||||
auto data = new uint16_t[100];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
Frame f(reinterpret_cast<std::byte *>(data), 10, 10, 16);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
REQUIRE((uint16_t)*f.get(i / 10, i % 10) == data[i]);
|
||||
}
|
||||
REQUIRE(f.rows() == 10);
|
||||
REQUIRE(f.cols() == 10);
|
||||
REQUIRE(f.bitdepth() == 16);
|
||||
|
||||
uint16_t i = 44;
|
||||
f.set(0, 0, i);
|
||||
REQUIRE((uint16_t)*f.get(0, 0) == i);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
TEST_CASE("DataSpan") {
|
||||
auto data = new uint16_t[100];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
SECTION("constructors") {
|
||||
DataSpan<uint16_t, 2> ds(data, std::vector<ssize_t>({10, 10}));
|
||||
for (int i = 0; i < 100; i++) {
|
||||
REQUIRE(ds(i / 10, i % 10) == data[i]);
|
||||
}
|
||||
}
|
||||
SECTION("from Frame") {
|
||||
Frame f(reinterpret_cast<std::byte *>(data), 10, 10, 16);
|
||||
DataSpan<uint16_t, 2> ds(f);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
REQUIRE(ds(i / 10, i % 10) == data[i]);
|
||||
}
|
||||
|
||||
f.set(0, 0, (uint16_t)44);
|
||||
REQUIRE((uint16_t)*f.get(0, 0) == 44); // check that set worked
|
||||
REQUIRE(ds(0, 0) == 44);// check that ds is updated
|
||||
REQUIRE(data[0] == 0); // check that data is not updated
|
||||
}
|
||||
delete[] data;
|
||||
}
|
Reference in New Issue
Block a user