Overview
This library contains functions to test the other tatami libraries. To include this in a project, just add the following chunk to the test-specific CMakeLists.txt
:
include(FetchContent)
FetchContent_Declare(
tatami_test
GIT_REPOSITORY https://github.com/tatami-inc/tatami_test
GIT_TAG master # or any version of interest
)
FetchContent_MakeAvailable(tatami_test)
target_link_libraries(mylib INTERFACE tatami_test)
This will automatically pull in GoogleTest via FetchContent
so downstream projects don't have to do it themselves. Then, to use the library, we just have to add the header:
#include "tatami_tests/tatami_tests.hpp"
Check out the reference documentation for the available functionality.
Simulating data
We can simulate random data easily:
std::vector< Type_ > simulate_vector(size_t length, const SimulateVectorOptions &options)
Definition simulate_vector.hpp:50
Options for simulate_vector().
Definition simulate_vector.hpp:18
double upper
Definition simulate_vector.hpp:27
double density
Definition simulate_vector.hpp:32
double lower
Definition simulate_vector.hpp:22
We can also simulate compressed sparse data to quickly create the corresponding sparse matrices:
100,
500,
0.1,
);
SimulateCompressedSparseResult< Value_, Index_ > simulate_compressed_sparse(size_t primary, size_t secondary, const SimulateCompressedSparseOptions &options)
Definition simulate_compressed_sparse.hpp:82
Options for simulate_compressed_sparse().
Definition simulate_compressed_sparse.hpp:18
Testing data access
The workhorses of this library are the various test_*_access()
functions. These test the extraction behavior of a tatami::Matrix
subclass by comparing it to a reference representation.
auto dense = std::shared_ptr<tatami::Matrix<double, int> >(
);
void test_full_access(const tatami::Matrix< Value_, Index_ > &matrix, const tatami::Matrix< Value_, Index_ > &reference, const TestAccessOptions &options)
Definition test_access.hpp:396
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_compressed_sparse(const Matrix< InputValue_, InputIndex_ > *matrix, bool row, bool two_pass=false, int threads=1)
Options for test_full_access() and friends.
Definition test_access.hpp:39
bool use_row
Definition test_access.hpp:49
We can also test access of a contiguous block, defined as a proportion of the extent non-target dimension. In the chunk below, the columns are the target dimension to be extracted, so the block starts at 10% of the number of rows and has length equal to 50% of the number of rows.
*sparse,
*dense,
0.1,
0.5,
options
);
void test_block_access(const tatami::Matrix< Value_, Index_ > &matrix, const tatami::Matrix< Value_, Index_ > &reference, double relative_start, double relative_length, const TestAccessOptions &options)
Definition test_access.hpp:427
A similar approach is used to test access for an indexed subset. We randomly sample elements in the non-target dimension for inclusion into the subset with the specified probability
.
*sparse,
*dense,
0.1,
0.5,
options
);
void test_indexed_access(const tatami::Matrix< Value_, Index_ > &matrix, const tatami::Matrix< Value_, Index_ > &reference, double relative_start, double probability, const TestAccessOptions &options)
Definition test_access.hpp:460
Seed wrappers for delayed operations
For tatami::Matrix
subclasses implementing delayed operations, we can test whether the operation correctly handles edge cases of seed behavior. For example, if the delayed operation needs to manipulate the indices during sparse extraction, can it handle seeds that might return unordered indices? We can test this via by wrapping the seed in a ReversedIndicesWrapper
before applying the delayed operation, and then using test_unsorted_*_access()
functions:
auto wrapped = std::make_shared<tatami_test::ReversedIndicesWrapper<double, int> >(sparse);
std::vector<int> odds { 1, 3, 5, 7, 9 };
auto submat = tatami::make_DelayedSubset<double, int>(wrapped, odds, true);
void test_unsorted_full_access(const tatami::Matrix< Value_, Index_ > &matrix, const TestAccessOptions &options)
Definition test_unsorted_access.hpp:185
void test_unsorted_block_access(const tatami::Matrix< Value_, Index_ > &matrix, double relative_start, double relative_length, const TestAccessOptions &options)
Definition test_unsorted_access.hpp:212
void test_unsorted_indexed_access(const tatami::Matrix< Value_, Index_ > &matrix, double relative_start, double probability, const TestAccessOptions &options)
Definition test_unsorted_access.hpp:239
Another edge case is when a delayed operation's oracular extraction uses different code paths based on whether the seeds benefit from an oracle. We can test this behavior by forcing one or more seeds to declare that, yes, they do benefit from an oracle:
auto wrapped2 = std::make_shared<tatami_test::ForcedOracleWrapper<double, int> >(dense);
auto bound = tatami::make_DelayedBind<double, int>({ wrapped2, sparse }, true);
auto ref = tatami::make_DelayedBind<double, int>({ dense, sparse }, true);
Other useful things
We can check that errors are thrown with the expected message:
throw std::runtime_error("foobar");
}, "foobar");
void throws_error(Function_ fun, const std::string &msg)
Definition throws_error.hpp:23
We also provide a wrapper around the fetch
+ copy_n
combination, which directly returns a vector of the desired row/column contents.
auto ext = dense->dense_column();
auto column = fetch(*ext, 10, dense->nrow());