2019-12-01 03:53:24 +00:00
|
|
|
|
#include <cstdlib>
|
2019-11-21 11:55:05 +00:00
|
|
|
|
#include <notcurses.h>
|
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
|
|
class NcplaneTest : public :: testing::Test {
|
|
|
|
|
protected:
|
|
|
|
|
void SetUp() override {
|
2019-11-25 18:36:16 +00:00
|
|
|
|
setlocale(LC_ALL, nullptr);
|
2019-11-21 11:55:05 +00:00
|
|
|
|
if(getenv("TERM") == nullptr){
|
|
|
|
|
GTEST_SKIP();
|
|
|
|
|
}
|
|
|
|
|
notcurses_options nopts{};
|
2019-11-29 08:25:55 +00:00
|
|
|
|
nopts.inhibit_alternate_screen = true;
|
|
|
|
|
nopts.retain_cursor = true;
|
|
|
|
|
nopts.pass_through_esc = true;
|
2019-11-27 15:43:03 +00:00
|
|
|
|
nopts.outfp = stdin;
|
2019-11-21 11:55:05 +00:00
|
|
|
|
nc_ = notcurses_init(&nopts);
|
|
|
|
|
ASSERT_NE(nullptr, nc_);
|
2019-11-21 12:46:19 +00:00
|
|
|
|
n_ = notcurses_stdplane(nc_);
|
|
|
|
|
ASSERT_NE(nullptr, n_);
|
2019-11-25 18:36:16 +00:00
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
2019-11-21 11:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TearDown() override {
|
2019-11-21 13:24:09 +00:00
|
|
|
|
if(nc_){
|
|
|
|
|
EXPECT_EQ(0, notcurses_stop(nc_));
|
|
|
|
|
}
|
2019-11-21 11:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-21 13:24:09 +00:00
|
|
|
|
struct notcurses* nc_{};
|
|
|
|
|
struct ncplane* n_{};
|
2019-11-21 11:55:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
2019-11-21 13:19:14 +00:00
|
|
|
|
// Starting position ought be 0, 0 (the origin)
|
|
|
|
|
TEST_F(NcplaneTest, StdPlanePosition) {
|
|
|
|
|
int x, y;
|
2019-11-23 03:47:12 +00:00
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-21 13:19:14 +00:00
|
|
|
|
EXPECT_EQ(0, x);
|
|
|
|
|
EXPECT_EQ(0, y);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-21 12:46:19 +00:00
|
|
|
|
// Dimensions of the standard plane ought be the same as those of the context
|
|
|
|
|
TEST_F(NcplaneTest, StdPlaneDimensions) {
|
|
|
|
|
int cols, rows;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
notcurses_term_dim_yx(nc_, &rows, &cols);
|
2019-11-21 12:46:19 +00:00
|
|
|
|
int ncols, nrows;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &nrows, &ncols);
|
2019-11-21 12:46:19 +00:00
|
|
|
|
EXPECT_EQ(rows, nrows);
|
|
|
|
|
EXPECT_EQ(cols, ncols);
|
2019-11-21 11:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify that we can move to all four coordinates of the standard plane
|
|
|
|
|
TEST_F(NcplaneTest, MoveStdPlaneDimensions) {
|
|
|
|
|
int cols, rows;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
notcurses_term_dim_yx(nc_, &rows, &cols);
|
2019-11-23 03:47:12 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
2019-11-21 13:19:14 +00:00
|
|
|
|
int x, y;
|
2019-11-23 03:47:12 +00:00
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-21 13:19:14 +00:00
|
|
|
|
EXPECT_EQ(y, 0);
|
|
|
|
|
EXPECT_EQ(x, 0);
|
2019-11-23 03:47:12 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, rows - 1, 0));
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-21 13:19:14 +00:00
|
|
|
|
EXPECT_EQ(y, rows - 1);
|
|
|
|
|
EXPECT_EQ(x, 0);
|
2019-11-23 03:47:12 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, rows - 1, cols - 1));
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-21 13:19:14 +00:00
|
|
|
|
EXPECT_EQ(y, rows - 1);
|
|
|
|
|
EXPECT_EQ(x, cols - 1);
|
2019-11-23 03:47:12 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 0, cols - 1));
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-21 13:19:14 +00:00
|
|
|
|
EXPECT_EQ(y, 0);
|
|
|
|
|
EXPECT_EQ(x, cols - 1);
|
2019-11-21 11:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify that we can move to all four coordinates of the standard plane
|
|
|
|
|
TEST_F(NcplaneTest, MoveBeyondPlaneFails) {
|
|
|
|
|
int cols, rows;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
notcurses_term_dim_yx(nc_, &rows, &cols);
|
2019-11-23 03:47:12 +00:00
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, -1, 0));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, -1, -1));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, 0, -1));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, rows - 1, -1));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, rows, 0));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, rows + 1, 0));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, rows, cols));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, -1, cols - 1));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, 0, cols));
|
|
|
|
|
EXPECT_NE(0, ncplane_cursor_move_yx(n_, 0, cols + 1));
|
2019-11-21 12:46:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, SetPlaneRGB) {
|
|
|
|
|
EXPECT_EQ(0, ncplane_fg_rgb8(n_, 0, 0, 0));
|
|
|
|
|
EXPECT_EQ(0, ncplane_fg_rgb8(n_, 255, 255, 255));
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-21 12:46:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, RejectBadRGB) {
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, -1, 0, 0));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 0, -1, 0));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 0, 0, -1));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, -1, -1, -1));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 256, 255, 255));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 255, 256, 255));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 255, 255, 256));
|
|
|
|
|
EXPECT_NE(0, ncplane_fg_rgb8(n_, 256, 256, 256));
|
2019-11-21 11:55:05 +00:00
|
|
|
|
}
|
2019-11-21 13:19:14 +00:00
|
|
|
|
|
|
|
|
|
// Verify we can emit a wide character, and it advances the cursor
|
|
|
|
|
TEST_F(NcplaneTest, EmitWchar) {
|
2019-11-23 23:34:06 +00:00
|
|
|
|
const char cchar[] = "✔";
|
2019-11-24 20:32:38 +00:00
|
|
|
|
cell c{};
|
2019-11-25 18:36:16 +00:00
|
|
|
|
EXPECT_EQ(strlen(cchar), cell_load(n_, &c, cchar));
|
2019-11-24 20:32:38 +00:00
|
|
|
|
EXPECT_EQ(strlen(cchar), ncplane_putc(n_, &c));
|
2019-11-21 13:19:14 +00:00
|
|
|
|
int x, y;
|
2019-11-23 03:47:12 +00:00
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-24 00:24:29 +00:00
|
|
|
|
EXPECT_EQ(0, y);
|
|
|
|
|
EXPECT_EQ(1, x);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-21 13:19:14 +00:00
|
|
|
|
}
|
2019-11-23 17:52:09 +00:00
|
|
|
|
|
|
|
|
|
// Verify we can emit a wide string, and it advances the cursor
|
2019-11-23 23:34:06 +00:00
|
|
|
|
TEST_F(NcplaneTest, EmitStr) {
|
|
|
|
|
const char s[] = "Σιβυλλα τι θελεις; respondebat illa: αποθανειν θελω.";
|
2019-11-24 00:24:29 +00:00
|
|
|
|
int wrote = ncplane_putstr(n_, s);
|
|
|
|
|
EXPECT_EQ(strlen(s), wrote);
|
2019-11-23 17:52:09 +00:00
|
|
|
|
int x, y;
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
2019-11-24 00:24:29 +00:00
|
|
|
|
EXPECT_EQ(0, y);
|
|
|
|
|
EXPECT_NE(1, x); // FIXME tighten in on this
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-23 17:52:09 +00:00
|
|
|
|
}
|
2019-11-24 21:41:43 +00:00
|
|
|
|
|
2019-11-24 21:46:58 +00:00
|
|
|
|
TEST_F(NcplaneTest, HorizontalLines) {
|
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &y, &x);
|
2019-11-24 21:46:58 +00:00
|
|
|
|
ASSERT_LT(0, y);
|
|
|
|
|
ASSERT_LT(0, x);
|
|
|
|
|
cell c{};
|
|
|
|
|
cell_load(n_, &c, "-");
|
|
|
|
|
for(int yidx = 0 ; yidx < y ; ++yidx){
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, yidx, 1));
|
|
|
|
|
EXPECT_EQ(x - 2, ncplane_hline(n_, &c, x - 2));
|
2019-11-24 21:57:53 +00:00
|
|
|
|
int posx, posy;
|
|
|
|
|
ncplane_cursor_yx(n_, &posy, &posx);
|
|
|
|
|
EXPECT_EQ(yidx, posy);
|
|
|
|
|
EXPECT_EQ(x - 1, posx);
|
|
|
|
|
}
|
2019-11-24 22:06:57 +00:00
|
|
|
|
cell_release(n_, &c);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-24 21:57:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, VerticalLines) {
|
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &y, &x);
|
2019-11-24 21:57:53 +00:00
|
|
|
|
ASSERT_LT(0, y);
|
|
|
|
|
ASSERT_LT(0, x);
|
|
|
|
|
cell c{};
|
2019-11-25 04:56:14 +00:00
|
|
|
|
cell_load(n_, &c, "|");
|
2019-11-29 08:25:55 +00:00
|
|
|
|
for(int xidx = 1 ; xidx < x - 1 ; ++xidx){
|
2019-11-24 21:57:53 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 1, xidx));
|
|
|
|
|
EXPECT_EQ(y - 2, ncplane_vline(n_, &c, y - 2));
|
|
|
|
|
int posx, posy;
|
|
|
|
|
ncplane_cursor_yx(n_, &posy, &posx);
|
|
|
|
|
EXPECT_EQ(y - 2, posy);
|
|
|
|
|
EXPECT_EQ(xidx, posx - 1);
|
2019-11-24 21:46:58 +00:00
|
|
|
|
}
|
2019-11-24 22:06:57 +00:00
|
|
|
|
cell_release(n_, &c);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-24 22:06:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-26 00:51:11 +00:00
|
|
|
|
// reject attempts to draw boxes beyond the boundaries of the ncplane
|
|
|
|
|
TEST_F(NcplaneTest, BadlyPlacedBoxen) {
|
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &y, &x);
|
2019-11-27 02:30:08 +00:00
|
|
|
|
ASSERT_LT(2, y);
|
|
|
|
|
ASSERT_LT(2, x);
|
2019-11-26 00:51:11 +00:00
|
|
|
|
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
|
2019-11-27 02:30:08 +00:00
|
|
|
|
ASSERT_EQ(0, ncplane_rounded_box_cells(n_, &ul, &ur, &ll, &lr, &hl, &vl));
|
2019-11-26 00:51:11 +00:00
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, y + 1, x + 1));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 1, 0));
|
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, y, x));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 0, 1));
|
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, y, x));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y - 1, x - 1));
|
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, 2, 2));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y - 2, x - 1));
|
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, 2, 2));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y - 1, x - 2));
|
|
|
|
|
EXPECT_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, 2, 2));
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-26 00:51:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, PerimeterBox) {
|
2019-11-24 22:06:57 +00:00
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &y, &x);
|
2019-11-27 02:30:08 +00:00
|
|
|
|
ASSERT_LT(2, y);
|
|
|
|
|
ASSERT_LT(2, x);
|
2019-11-24 22:06:57 +00:00
|
|
|
|
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
|
2019-11-27 02:30:08 +00:00
|
|
|
|
ASSERT_EQ(0, ncplane_rounded_box_cells(n_, &ul, &ur, &ll, &lr, &hl, &vl));
|
|
|
|
|
EXPECT_EQ(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, y - 1, x - 1));
|
2019-11-24 22:06:57 +00:00
|
|
|
|
cell_release(n_, &vl);
|
|
|
|
|
cell_release(n_, &hl);
|
|
|
|
|
cell_release(n_, &ul);
|
|
|
|
|
cell_release(n_, &ll);
|
|
|
|
|
cell_release(n_, &ur);
|
|
|
|
|
cell_release(n_, &lr);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-24 21:46:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-27 02:30:08 +00:00
|
|
|
|
TEST_F(NcplaneTest, PerimeterBoxSized) {
|
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &y, &x);
|
2019-11-27 02:30:08 +00:00
|
|
|
|
ASSERT_LT(2, y);
|
|
|
|
|
ASSERT_LT(2, x);
|
|
|
|
|
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
|
|
|
|
|
ASSERT_EQ(0, ncplane_rounded_box_cells(n_, &ul, &ur, &ll, &lr, &hl, &vl));
|
|
|
|
|
EXPECT_EQ(0, ncplane_box_sized(n_, &ul, &ur, &ll, &lr, &hl, &vl, y, x));
|
|
|
|
|
cell_release(n_, &vl);
|
|
|
|
|
cell_release(n_, &hl);
|
|
|
|
|
cell_release(n_, &ul);
|
|
|
|
|
cell_release(n_, &ll);
|
|
|
|
|
cell_release(n_, &ur);
|
|
|
|
|
cell_release(n_, &lr);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-27 02:30:08 +00:00
|
|
|
|
}
|
2019-11-27 15:43:03 +00:00
|
|
|
|
|
2019-11-24 21:41:43 +00:00
|
|
|
|
TEST_F(NcplaneTest, EraseScreen) {
|
|
|
|
|
ncplane_erase(n_);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
2019-11-24 21:41:43 +00:00
|
|
|
|
}
|
2019-11-26 02:11:27 +00:00
|
|
|
|
|
|
|
|
|
// we're gonna run both a composed latin a with grave, and then a latin a with
|
|
|
|
|
// a combining nonspacing grave
|
|
|
|
|
TEST_F(NcplaneTest, CellLoadCombining) {
|
|
|
|
|
const char* w1 = "à"; // U+00E0, U+0000 (c3 a0)
|
|
|
|
|
const char* w2 = "à"; // U+0061, U+0300, U+0000 (61 cc 80)
|
|
|
|
|
const char* w3 = "a"; // U+0061, U+0000 (61)
|
|
|
|
|
cell cell1 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell2 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell3 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
auto u1 = cell_load(n_, &cell1, w1);
|
|
|
|
|
auto u2 = cell_load(n_, &cell2, w2);
|
|
|
|
|
auto u3 = cell_load(n_, &cell3, w3);
|
|
|
|
|
ASSERT_EQ(2, u1);
|
|
|
|
|
ASSERT_EQ(3, u2);
|
|
|
|
|
ASSERT_EQ(1, u3);
|
|
|
|
|
cell_release(n_, &cell1);
|
|
|
|
|
cell_release(n_, &cell2);
|
|
|
|
|
cell_release(n_, &cell3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, CellDuplicateCombining) {
|
|
|
|
|
const char* w1 = "à"; // U+00E0, U+0000 (c3 a0)
|
|
|
|
|
const char* w2 = "à"; // U+0061, U+0300, U+0000 (61 cc 80)
|
|
|
|
|
const char* w3 = "a"; // U+0061, U+0000 (61)
|
|
|
|
|
cell cell1 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell2 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell3 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
auto u1 = cell_load(n_, &cell1, w1);
|
|
|
|
|
auto u2 = cell_load(n_, &cell2, w2);
|
|
|
|
|
auto u3 = cell_load(n_, &cell3, w3);
|
|
|
|
|
ASSERT_EQ(2, u1);
|
|
|
|
|
ASSERT_EQ(3, u2);
|
|
|
|
|
ASSERT_EQ(1, u3);
|
|
|
|
|
cell cell4 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell5 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell cell6 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
EXPECT_EQ(2, cell_duplicate(n_, &cell4, &cell1));
|
|
|
|
|
EXPECT_EQ(3, cell_duplicate(n_, &cell5, &cell2));
|
|
|
|
|
EXPECT_EQ(1, cell_duplicate(n_, &cell6, &cell3));
|
|
|
|
|
cell_release(n_, &cell1);
|
|
|
|
|
cell_release(n_, &cell2);
|
|
|
|
|
cell_release(n_, &cell3);
|
|
|
|
|
cell_release(n_, &cell4);
|
|
|
|
|
cell_release(n_, &cell5);
|
|
|
|
|
cell_release(n_, &cell6);
|
|
|
|
|
}
|
2019-11-26 12:14:38 +00:00
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, CellMultiColumn) {
|
|
|
|
|
const char* w1 = "👨";
|
|
|
|
|
const char* w2 = "N";
|
|
|
|
|
cell c1 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
cell c2 = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
auto u1 = cell_load(n_, &c1, w1);
|
|
|
|
|
auto u2 = cell_load(n_, &c2, w2);
|
|
|
|
|
ASSERT_EQ(strlen(w1), u1);
|
|
|
|
|
ASSERT_EQ(strlen(w2), u2);
|
2019-11-27 15:43:03 +00:00
|
|
|
|
EXPECT_TRUE(cell_double_wide_p(&c1));
|
|
|
|
|
EXPECT_FALSE(cell_double_wide_p(&c2));
|
2019-11-26 12:14:38 +00:00
|
|
|
|
cell_release(n_, &c1);
|
|
|
|
|
cell_release(n_, &c2);
|
|
|
|
|
}
|
2019-11-28 15:05:44 +00:00
|
|
|
|
|
|
|
|
|
// verifies that the initial userptr is what we provided, that it is a nullptr
|
|
|
|
|
// for the standard plane, and that we can change it.
|
|
|
|
|
TEST_F(NcplaneTest, UserPtr) {
|
|
|
|
|
EXPECT_EQ(nullptr, ncplane_userptr(n_));
|
|
|
|
|
int x, y;
|
|
|
|
|
void* sentinel = &x;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
notcurses_term_dim_yx(nc_, &y, &x);
|
2019-11-28 15:05:44 +00:00
|
|
|
|
struct ncplane* ncp = notcurses_newplane(nc_, y, x, 0, 0, sentinel);
|
|
|
|
|
ASSERT_NE(ncp, nullptr);
|
|
|
|
|
EXPECT_EQ(&x, ncplane_userptr(ncp));
|
|
|
|
|
EXPECT_EQ(sentinel, ncplane_set_userptr(ncp, nullptr));
|
|
|
|
|
EXPECT_EQ(nullptr, ncplane_userptr(ncp));
|
|
|
|
|
sentinel = &y;
|
|
|
|
|
EXPECT_EQ(nullptr, ncplane_set_userptr(ncp, sentinel));
|
|
|
|
|
EXPECT_EQ(&y, ncplane_userptr(ncp));
|
2019-11-29 03:08:26 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_destroy(ncp));
|
2019-11-28 15:05:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create a new plane, the same size as the terminal, and verify that it
|
|
|
|
|
// occupies the same dimensions as the standard plane.
|
|
|
|
|
TEST_F(NcplaneTest, NewPlaneSameSize) {
|
|
|
|
|
int x, y;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
notcurses_term_dim_yx(nc_, &y, &x);
|
2019-11-28 15:05:44 +00:00
|
|
|
|
struct ncplane* ncp = notcurses_newplane(nc_, y, x, 0, 0, nullptr);
|
|
|
|
|
ASSERT_NE(nullptr, ncp);
|
|
|
|
|
int px, py;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(ncp, &py, &px);
|
2019-11-28 15:05:44 +00:00
|
|
|
|
EXPECT_EQ(y, py);
|
|
|
|
|
EXPECT_EQ(x, px);
|
|
|
|
|
int sx, sy;
|
2019-11-29 03:08:26 +00:00
|
|
|
|
ncplane_dim_yx(n_, &sy, &sx);
|
2019-11-28 15:05:44 +00:00
|
|
|
|
EXPECT_EQ(sy, py);
|
|
|
|
|
EXPECT_EQ(sx, px);
|
2019-11-29 03:08:26 +00:00
|
|
|
|
EXPECT_EQ(0, ncplane_destroy(ncp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, ShrinkPlane) {
|
|
|
|
|
int maxx, maxy;
|
|
|
|
|
int x = 0, y = 0;
|
|
|
|
|
notcurses_term_dim_yx(nc_, &maxy, &maxx);
|
|
|
|
|
struct ncplane* newp = notcurses_newplane(nc_, maxy, maxx, y, x, nullptr);
|
|
|
|
|
ASSERT_NE(nullptr, newp);
|
|
|
|
|
while(y > 4 && x > 4){
|
|
|
|
|
maxx -= 2;
|
|
|
|
|
maxy -= 2;
|
|
|
|
|
++x;
|
|
|
|
|
++y;
|
|
|
|
|
ASSERT_EQ(0, ncplane_resize(newp, 1, 1, maxy, maxx, 1, 1, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
while(y > 4){
|
|
|
|
|
maxy -= 2;
|
|
|
|
|
++y;
|
|
|
|
|
ASSERT_EQ(0, ncplane_resize(newp, 1, 0, maxy, maxx, 1, 0, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
while(x > 4){
|
|
|
|
|
maxx -= 2;
|
|
|
|
|
++x;
|
|
|
|
|
ASSERT_EQ(0, ncplane_resize(newp, 0, 1, maxy, maxx, 0, 1, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
ASSERT_EQ(0, ncplane_resize(newp, 0, 0, 0, 0, 0, 0, 2, 2));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
ASSERT_EQ(0, ncplane_destroy(newp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NcplaneTest, GrowPlane) {
|
|
|
|
|
int maxx = 2, maxy = 2;
|
|
|
|
|
int x = 0, y = 0;
|
|
|
|
|
int dimy, dimx;
|
|
|
|
|
notcurses_term_dim_yx(nc_, &dimy, &dimx);
|
|
|
|
|
x = dimx / 2 - 1;
|
|
|
|
|
y = dimy / 2 - 1;
|
|
|
|
|
struct ncplane* newp = notcurses_newplane(nc_, maxy, maxx, y, x, nullptr);
|
|
|
|
|
ASSERT_NE(nullptr, newp);
|
|
|
|
|
while(dimx - maxx > 4 && dimy - maxy > 4){
|
|
|
|
|
maxx += 2;
|
|
|
|
|
maxy += 2;
|
|
|
|
|
--x;
|
|
|
|
|
--y;
|
|
|
|
|
// ASSERT_EQ(0, ncplane_resize(newp, 1, 1, maxy, maxx, 1, 1, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
while(y < dimy){
|
|
|
|
|
++maxy;
|
|
|
|
|
if(y){
|
|
|
|
|
++y;
|
|
|
|
|
}
|
|
|
|
|
// ASSERT_EQ(0, ncplane_resize(newp, 1, 0, maxy, maxx, 1, 0, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
while(x < dimx){
|
|
|
|
|
++maxx;
|
|
|
|
|
if(x){
|
|
|
|
|
++x;
|
|
|
|
|
}
|
|
|
|
|
// ASSERT_EQ(0, ncplane_resize(newp, 0, 1, maxy, maxx, 0, 1, maxy, maxx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
}
|
|
|
|
|
ASSERT_EQ(0, ncplane_resize(newp, 0, 0, 0, 0, 0, 0, dimy, dimx));
|
|
|
|
|
// FIXME check dims, pos
|
|
|
|
|
ASSERT_EQ(0, ncplane_destroy(newp));
|
2019-11-28 15:05:44 +00:00
|
|
|
|
}
|
2019-12-01 03:53:24 +00:00
|
|
|
|
|
|
|
|
|
// we ought be able to see what we're about to render, or have just rendered, or
|
|
|
|
|
// in any case whatever's in the virtual framebuffer for a plane
|
|
|
|
|
TEST_F(NcplaneTest, PlaneAtCursorSimples){
|
|
|
|
|
const char STR1[] = "Jackdaws love my big sphinx of quartz";
|
|
|
|
|
const char STR2[] = "Cwm fjord bank glyphs vext quiz";
|
|
|
|
|
const char STR3[] = "Pack my box with five dozen liquor jugs";
|
|
|
|
|
ncplane_styles_set(n_, 0);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR1));
|
|
|
|
|
int dimy, dimx;
|
|
|
|
|
ncplane_dim_yx(n_, &dimy, &dimx);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 1, dimx - strlen(STR2)));
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR2));
|
|
|
|
|
int y, x;
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
|
|
|
|
ASSERT_EQ(2, y);
|
|
|
|
|
ASSERT_EQ(0, x);
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR3));
|
|
|
|
|
cell testcell = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
ASSERT_EQ(0, ncplane_at_cursor(n_, &testcell)); // want nothing at the cursor
|
|
|
|
|
EXPECT_EQ(0, testcell.gcluster);
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
|
|
|
|
ASSERT_LT(0, ncplane_at_cursor(n_, &testcell)); // want first char of STR1
|
|
|
|
|
EXPECT_EQ(STR1[0], testcell.gcluster);
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 1, dimx - 1));
|
|
|
|
|
ASSERT_LT(0, ncplane_at_cursor(n_, &testcell)); // want last char of STR2
|
|
|
|
|
EXPECT_EQ(STR2[strlen(STR2) - 1], testcell.gcluster);
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
// FIXME maybe check all cells?
|
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ensure we read back what's expected for latinesque complex characters
|
|
|
|
|
TEST_F(NcplaneTest, PlaneAtCursorComplex){
|
|
|
|
|
const char STR1[] = "Σιβυλλα τι θελεις; respondebat illa:";
|
|
|
|
|
const char STR2[] = "αποθανειν θελω";
|
|
|
|
|
const char STR3[] = "Война и мир"; // just thrown in to complicate things
|
|
|
|
|
ncplane_styles_set(n_, 0);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR1));
|
|
|
|
|
int dimy, dimx;
|
|
|
|
|
ncplane_dim_yx(n_, &dimy, &dimx);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 1, dimx - mbstowcs(NULL, STR2, 0)));
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR2));
|
|
|
|
|
int y, x;
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
|
|
|
|
ASSERT_EQ(2, y);
|
|
|
|
|
ASSERT_EQ(0, x);
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR3));
|
|
|
|
|
cell testcell = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
ncplane_at_cursor(n_, &testcell); // should be nothing at the cursor
|
|
|
|
|
EXPECT_EQ(0, testcell.gcluster);
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 0, 0));
|
|
|
|
|
ASSERT_LT(0, ncplane_at_cursor(n_, &testcell)); // want first char of STR1
|
|
|
|
|
EXPECT_STREQ("Σ", cell_extended_gcluster(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
ASSERT_EQ(0, ncplane_cursor_move_yx(n_, 1, dimx - mbstowcs(NULL, STR2, 0)));
|
|
|
|
|
ASSERT_LT(0, ncplane_at_cursor(n_, &testcell)); // want first char of STR2
|
|
|
|
|
EXPECT_STREQ("α", cell_extended_gcluster(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
// FIXME maybe check all cells?
|
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// half-width, double-width, huge-yet-narrow, all that crap
|
|
|
|
|
TEST_F(NcplaneTest, PlaneAtCursorInsane){
|
|
|
|
|
const char EGC0[] = "\uffe0"; // fullwidth cent sign ¢
|
|
|
|
|
const char EGC1[] = "\u00c5"; // neutral A with ring above Å
|
|
|
|
|
const char EGC2[] = "\u20a9"; // half-width won ₩
|
|
|
|
|
const char EGC3[] = "\u212b"; // ambiguous angstrom Å
|
|
|
|
|
const char EGC4[] = "\ufdfd"; // neutral yet huge bismillah ﷽
|
|
|
|
|
std::array<cell, 5> tcells;
|
|
|
|
|
for(auto i = 0u ; i < tcells.size() ; ++i){
|
|
|
|
|
cell_init(&tcells[i]);
|
|
|
|
|
}
|
|
|
|
|
ASSERT_LT(1, cell_load(n_, &tcells[0], EGC0));
|
|
|
|
|
ASSERT_LT(1, cell_load(n_, &tcells[1], EGC1));
|
|
|
|
|
ASSERT_LT(1, cell_load(n_, &tcells[2], EGC2));
|
|
|
|
|
ASSERT_LT(1, cell_load(n_, &tcells[3], EGC3));
|
|
|
|
|
ASSERT_LT(1, cell_load(n_, &tcells[4], EGC4));
|
|
|
|
|
for(auto i = 0u ; i < tcells.size() ; ++i){
|
|
|
|
|
ASSERT_LT(1, ncplane_putc(n_, &tcells[i]));
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
|
|
|
|
int x = 0;
|
|
|
|
|
for(auto i = 0u ; i < tcells.size() ; ++i){
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, 0, x));
|
|
|
|
|
cell testcell = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
ASSERT_LT(0, ncplane_at_cursor(n_, &testcell));
|
|
|
|
|
EXPECT_STREQ(cell_extended_gcluster(n_, &tcells[i]),
|
|
|
|
|
cell_extended_gcluster(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(0, testcell.attrword);
|
|
|
|
|
wchar_t w;
|
|
|
|
|
ASSERT_LT(0, mbtowc(&w, cell_extended_gcluster(n_, &tcells[i]), MB_CUR_MAX));
|
|
|
|
|
if(wcwidth(w) == 2){
|
|
|
|
|
EXPECT_EQ(CELL_WIDEASIAN_MASK, testcell.channels);
|
|
|
|
|
++x;
|
|
|
|
|
}else{
|
|
|
|
|
EXPECT_EQ(0, testcell.channels);
|
|
|
|
|
}
|
|
|
|
|
++x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// test that we read back correct attrs/colors despite changing defaults
|
|
|
|
|
TEST_F(NcplaneTest, PlaneAtCursorAttrs){
|
|
|
|
|
const char STR1[] = "this has been a world destroyer production";
|
|
|
|
|
const char STR2[] = "not to mention dank";
|
|
|
|
|
const char STR3[] = "da chronic lives";
|
|
|
|
|
ncplane_styles_set(n_, CELL_STYLE_BOLD);
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR1));
|
|
|
|
|
int y, x;
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &x);
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y + 1, x - strlen(STR2)));
|
|
|
|
|
ncplane_styles_on(n_, CELL_STYLE_ITALIC);
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR2));
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y + 2, x - strlen(STR3)));
|
|
|
|
|
ncplane_styles_off(n_, CELL_STYLE_BOLD);
|
|
|
|
|
ASSERT_LT(0, ncplane_putstr(n_, STR3));
|
|
|
|
|
ncplane_styles_off(n_, CELL_STYLE_ITALIC);
|
|
|
|
|
EXPECT_EQ(0, notcurses_render(nc_));
|
|
|
|
|
int newx;
|
|
|
|
|
ncplane_cursor_yx(n_, &y, &newx);
|
|
|
|
|
EXPECT_EQ(newx, x);
|
|
|
|
|
cell testcell = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y - 2, x - 1));
|
|
|
|
|
ASSERT_EQ(1, ncplane_at_cursor(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(testcell.gcluster, STR1[strlen(STR1) - 1]);
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y - 1, x - 1));
|
|
|
|
|
ASSERT_EQ(1, ncplane_at_cursor(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(testcell.gcluster, STR2[strlen(STR2) - 1]);
|
|
|
|
|
EXPECT_EQ(0, ncplane_cursor_move_yx(n_, y, x - 1));
|
|
|
|
|
ASSERT_EQ(1, ncplane_at_cursor(n_, &testcell));
|
|
|
|
|
EXPECT_EQ(testcell.gcluster, STR3[strlen(STR3) - 1]);
|
|
|
|
|
}
|