mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
Rewrite plot tests using C interface #703
The Plot unit tests were reaching directly into the objects, which meant the implementations couldn't include anything we didn't want public. This was annoying, so I've changed it. This required adding ncdplot_sample() and ncuplot_sample(), which we should have had anyway.
This commit is contained in:
parent
4d9171aee1
commit
70183ee283
2
NEWS.md
2
NEWS.md
@ -13,6 +13,8 @@ rearrangements of Notcurses.
|
||||
* `ncvisual_geom()`'s `ncblitter_e` argument has been replaced with a
|
||||
`const struct ncvisual_options*`, so that `NCVISUAL_OPTIONS_NODEGRADE`
|
||||
can be taken into account (the latter contains a `blitter_e` field).
|
||||
* Added `ncuplot_sample()` and `ncdplot_sample()`, allowing retrieval of
|
||||
sample data from `ncuplot`s and `ncdplot`s, respectively.
|
||||
|
||||
* 1.5.0 (2020-07-08)
|
||||
* The various `bool`s of `struct notcurses_options` have been folded into
|
||||
|
@ -46,6 +46,10 @@ typedef struct ncplot_options {
|
||||
|
||||
**int ncdplot_set_sample(struct ncdplot* n, uint64_t x, double y);**
|
||||
|
||||
**int ncuplot_sample(const struct ncuplot* n, uint64_t x, uint64_t* y);**
|
||||
|
||||
**int ncdplot_sample(const struct ncdplot* n, uint64_t x, double* y);**
|
||||
|
||||
**void ncuplot_destroy(struct ncuplot* n);**
|
||||
|
||||
**void ncdplot_destroy(struct ncdplot* n);**
|
||||
|
@ -2894,6 +2894,8 @@ API int ncuplot_add_sample(struct ncuplot* n, uint64_t x, uint64_t y);
|
||||
API int ncdplot_add_sample(struct ncdplot* n, uint64_t x, double y);
|
||||
API int ncuplot_set_sample(struct ncuplot* n, uint64_t x, uint64_t y);
|
||||
API int ncdplot_set_sample(struct ncdplot* n, uint64_t x, double y);
|
||||
API int ncuplot_sample(const struct ncuplot* n, uint64_t x, uint64_t* y);
|
||||
API int ncdplot_sample(const struct ncdplot* n, uint64_t x, double* y);
|
||||
|
||||
API void ncuplot_destroy(struct ncuplot* n);
|
||||
API void ncdplot_destroy(struct ncdplot* n);
|
||||
|
@ -460,6 +460,8 @@ int ncuplot_add_sample(struct ncuplot* n, uint64_t x, uint64_t y);
|
||||
int ncdplot_add_sample(struct ncdplot* n, uint64_t x, double y);
|
||||
int ncuplot_set_sample(struct ncuplot* n, uint64_t x, uint64_t y);
|
||||
int ncdplot_set_sample(struct ncdplot* n, uint64_t x, double y);
|
||||
int ncuplot_sample(const struct ncuplot* n, uint64_t x, uint64_t* y);
|
||||
int ncdplot_sample(const struct ncdplot* n, uint64_t x, double* y);
|
||||
void ncuplot_destroy(struct ncuplot* n);
|
||||
void ncdplot_destroy(struct ncdplot* n);
|
||||
bool ncplane_set_scrolling(struct ncplane* n, bool scrollp);
|
||||
|
@ -55,6 +55,14 @@ auto ncdplot_set_sample(ncdplot* n, uint64_t x, double y) -> int {
|
||||
return n->n.set_sample(x, y);
|
||||
}
|
||||
|
||||
auto ncuplot_sample(const ncuplot* n, uint64_t x, uint64_t* y) -> int {
|
||||
return n->n.sample(x, y);
|
||||
}
|
||||
|
||||
auto ncdplot_sample(const ncdplot* n, uint64_t x, double* y) -> int {
|
||||
return n->n.sample(x, y);
|
||||
}
|
||||
|
||||
void ncdplot_destroy(ncdplot* n) {
|
||||
if(n){
|
||||
n->n.destroy();
|
||||
|
@ -98,7 +98,7 @@ class ncppplot {
|
||||
free(slots);
|
||||
}
|
||||
|
||||
int redraw_plot() {
|
||||
auto redraw_plot() -> int {
|
||||
ncplane_erase(ncp);
|
||||
const int scale = bset->width;
|
||||
int dimy, dimx;
|
||||
@ -250,7 +250,7 @@ class ncppplot {
|
||||
// x window, the x window is advanced to include x, and values passing beyond
|
||||
// the window are lost. The first call will place the initial window. The plot
|
||||
// will be redrawn, but notcurses_render() is not called.
|
||||
int add_sample(uint64_t x, T y) {
|
||||
auto add_sample(uint64_t x, T y) -> int {
|
||||
if(window_slide(x)){
|
||||
return -1;
|
||||
}
|
||||
@ -261,7 +261,7 @@ class ncppplot {
|
||||
return redraw_plot();
|
||||
}
|
||||
|
||||
int set_sample(uint64_t x, T y) {
|
||||
auto set_sample(uint64_t x, T y) -> int {
|
||||
if(window_slide(x)){
|
||||
return -1;
|
||||
}
|
||||
@ -272,11 +272,21 @@ class ncppplot {
|
||||
return redraw_plot();
|
||||
}
|
||||
|
||||
auto sample(int64_t x, T* y) const -> int {
|
||||
if(x < slotx - (slotcount - 1)){ // x is behind window
|
||||
return -1;
|
||||
}else if(x > slotx){ // x is ahead of window
|
||||
return -1;
|
||||
}
|
||||
*y = slots[x % slotcount];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if we're doing domain detection, update the domain to reflect the value we
|
||||
// just set. if we're not, check the result against the known ranges, and
|
||||
// return -1 if the value is outside of that range.
|
||||
int update_domain(uint64_t x){
|
||||
const uint64_t val = slots[x % slotcount];
|
||||
auto update_domain(uint64_t x) -> int {
|
||||
const T val = slots[x % slotcount];
|
||||
if(detectdomain){
|
||||
if(val > maxy){
|
||||
maxy = val;
|
||||
@ -299,7 +309,7 @@ class ncppplot {
|
||||
// otherwise, the x is the newest sample. if it is obsoletes all existing slots,
|
||||
// reset them, and write the new sample anywhere. otherwise, write it to the
|
||||
// proper slot based on the current newest slot.
|
||||
int window_slide(int64_t x){
|
||||
auto window_slide(int64_t x) -> int {
|
||||
if(x < slotx - (slotcount - 1)){ // x is behind window, won't be counted
|
||||
return -1;
|
||||
}else if(x <= slotx){ // x is within window, do nothing
|
||||
|
136
tests/plot.cpp
136
tests/plot.cpp
@ -1,5 +1,4 @@
|
||||
#include "main.h"
|
||||
#include "plot.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
@ -47,84 +46,95 @@ TEST_CASE("Plot") {
|
||||
SUBCASE("AugmentSamples5"){
|
||||
ncplot_options popts{};
|
||||
popts.rangex = 5;
|
||||
ncppplot<uint64_t> p;
|
||||
ncppplot<uint64_t>::create(&p, n_, &popts, 0, 10);
|
||||
CHECK(0 == p.slots[0]);
|
||||
CHECK(0 == p.add_sample((uint64_t)0, (uint64_t)1));
|
||||
CHECK(1 == p.slots[0]);
|
||||
CHECK(0 == p.add_sample((uint64_t)0, (uint64_t)1));
|
||||
CHECK(2 == p.slots[0]);
|
||||
CHECK(0 == p.slots[1]);
|
||||
CHECK(0 == p.slots[2]);
|
||||
CHECK(0 == p.add_sample((uint64_t)2, (uint64_t)3));
|
||||
CHECK(3 == p.slots[2]);
|
||||
CHECK(0 == p.set_sample((uint64_t)2, (uint64_t)3));
|
||||
CHECK(3 == p.slots[2]);
|
||||
CHECK(0 == p.slots[3]);
|
||||
CHECK(0 == p.slots[4]);
|
||||
CHECK(0 == p.add_sample((uint64_t)4, (uint64_t)6));
|
||||
CHECK(6 == p.slots[4]);
|
||||
CHECK(2 == p.slots[0]);
|
||||
CHECK(4 == p.slotx);
|
||||
p.destroy();
|
||||
struct ncuplot* p = ncuplot_create(n_, &popts, 0, 10);
|
||||
uint64_t y;
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(0 == y);
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)0, (uint64_t)1));
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(1 == y);
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)0, (uint64_t)1));
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(2 == y);
|
||||
CHECK(-1 == ncuplot_sample(p, 1, &y));
|
||||
CHECK(-1 == ncuplot_sample(p, 2, &y));
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)2, (uint64_t)3));
|
||||
CHECK(0 == ncuplot_sample(p, 2, &y));
|
||||
CHECK(3 == y);
|
||||
CHECK(0 == ncuplot_set_sample(p, (uint64_t)2, (uint64_t)3));
|
||||
CHECK(0 == ncuplot_sample(p, 2, &y));
|
||||
CHECK(3 == y);
|
||||
CHECK(-1 == ncuplot_sample(p, 3, &y));
|
||||
CHECK(-1 == ncuplot_sample(p, 4, &y));
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)4, (uint64_t)6));
|
||||
CHECK(0 == ncuplot_sample(p, 4, &y));
|
||||
CHECK(6 == y);
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(2 == y);
|
||||
//CHECK(4 == p->slotx);
|
||||
ncuplot_destroy(p);
|
||||
}
|
||||
|
||||
// 2-ary slot space with window movement
|
||||
SUBCASE("AugmentCycle2"){
|
||||
ncplot_options popts{};
|
||||
popts.rangex = 2;
|
||||
ncppplot<uint64_t> p;
|
||||
ncppplot<uint64_t>::create(&p, n_, &popts, 0, 10);
|
||||
CHECK(0 == p.slots[0]);
|
||||
CHECK(0 == p.add_sample((uint64_t)0, (uint64_t)1));
|
||||
CHECK(1 == p.slots[0]);
|
||||
CHECK(0 == p.add_sample((uint64_t)0, (uint64_t)1));
|
||||
CHECK(2 == p.slots[0]);
|
||||
CHECK(0 == p.set_sample((uint64_t)1, (uint64_t)5));
|
||||
CHECK(5 == p.slots[1]);
|
||||
CHECK(0 == p.set_sample((uint64_t)2, (uint64_t)9));
|
||||
CHECK(5 == p.slots[1]);
|
||||
CHECK(9 == p.slots[0]);
|
||||
CHECK(0 == p.add_sample((uint64_t)3, (uint64_t)4));
|
||||
CHECK(9 == p.slots[0]);
|
||||
CHECK(4 == p.slots[1]);
|
||||
CHECK(3 == p.slotx);
|
||||
CHECK(0 == p.add_sample((uint64_t)5, (uint64_t)1));
|
||||
CHECK(1 == p.slots[0]);
|
||||
CHECK(0 == p.slots[1]);
|
||||
CHECK(5 == p.slotx);
|
||||
p.destroy();
|
||||
struct ncuplot* p = ncuplot_create(n_, &popts, 0, 10);
|
||||
uint64_t y;
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)0, (uint64_t)1));
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(1 == y);
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)0, (uint64_t)1));
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(2 == y);
|
||||
CHECK(0 == ncuplot_set_sample(p, (uint64_t)1, (uint64_t)5));
|
||||
CHECK(0 == ncuplot_sample(p, 1, &y));
|
||||
CHECK(5 == y);
|
||||
CHECK(0 == ncuplot_set_sample(p, (uint64_t)2, (uint64_t)9));
|
||||
CHECK(0 == ncuplot_sample(p, 1, &y));
|
||||
CHECK(5 == y);
|
||||
CHECK(-1 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)3, (uint64_t)4));
|
||||
CHECK(-1 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(-1 == ncuplot_sample(p, 1, &y));
|
||||
//CHECK(3 == p->slotx);
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)5, (uint64_t)1));
|
||||
CHECK(-1 == ncuplot_sample(p, 0, &y));
|
||||
CHECK(-1 == ncuplot_sample(p, 1, &y));
|
||||
//CHECK(5 == p.slotx);
|
||||
ncuplot_destroy(p);
|
||||
}
|
||||
|
||||
// augment past the window, ensuring everything gets zeroed
|
||||
SUBCASE("AugmentLong"){
|
||||
ncplot_options popts{};
|
||||
popts.rangex = 5;
|
||||
ncppplot<uint64_t> p;
|
||||
ncppplot<uint64_t>::create(&p, n_, &popts, 0, 10);
|
||||
for(int x = 0 ; x < 5 ; ++x){
|
||||
CHECK(0 == p.slots[x]);
|
||||
}
|
||||
CHECK(0 == p.add_sample((uint64_t)4, (uint64_t)4));
|
||||
for(int x = 0 ; x < 4 ; ++x){
|
||||
CHECK(0 == p.slots[x]);
|
||||
}
|
||||
CHECK(4 == p.slots[4]);
|
||||
CHECK(0 == p.add_sample((uint64_t)10, (uint64_t)5));
|
||||
CHECK(5 == p.slots[0]);
|
||||
for(int x = 1 ; x < 4 ; ++x){
|
||||
CHECK(0 == p.slots[x]);
|
||||
}
|
||||
CHECK(0 == p.add_sample((uint64_t)24, (uint64_t)7));
|
||||
CHECK(7 == p.slots[0]);
|
||||
struct ncuplot* p = ncuplot_create(n_, &popts, 0, 10);
|
||||
uint64_t y;
|
||||
CHECK(0 == ncuplot_sample(p, 0, &y));
|
||||
for(int x = 1 ; x < 5 ; ++x){
|
||||
CHECK(0 == p.slots[x]);
|
||||
CHECK(-1 == ncuplot_sample(p, x, &y));
|
||||
}
|
||||
CHECK(0 == p.add_sample((uint64_t)100, (uint64_t)0));
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)4, (uint64_t)4));
|
||||
for(int x = 1 ; x < 4 ; ++x){
|
||||
CHECK(0 == ncuplot_sample(p, x, &y));
|
||||
}
|
||||
CHECK(0 == ncuplot_sample(p, 4, &y));
|
||||
CHECK(4 == y);
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)10, (uint64_t)5));
|
||||
for(int x = 0 ; x < 4 ; ++x){
|
||||
CHECK(-1 == ncuplot_sample(p, x, &y));
|
||||
}
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)24, (uint64_t)7));
|
||||
for(int x = 0 ; x < 5 ; ++x){
|
||||
CHECK(0 == p.slots[x]);
|
||||
CHECK(-1 == ncuplot_sample(p, x, &y));
|
||||
}
|
||||
p.destroy();
|
||||
CHECK(0 == ncuplot_add_sample(p, (uint64_t)100, (uint64_t)0));
|
||||
for(int x = 0 ; x < 5 ; ++x){
|
||||
CHECK(-1 == ncuplot_sample(p, x, &y));
|
||||
}
|
||||
ncuplot_destroy(p);
|
||||
}
|
||||
|
||||
// FIXME need some high-level rendering tests, one for each geometry
|
||||
|
Loading…
x
Reference in New Issue
Block a user