xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
<root> / tests / misc / dir_stack.c (abc18e27d3a26c05133faba86b2532182429ea9c) (5,227B) (mode 100644) [raw]
#include <stic.h>

#include <stdlib.h> /* free() */
#include <string.h> /* strcmp() strcpy() */

#include <test-utils.h>

#include "../../src/compat/fs_limits.h"
#include "../../src/ui/ui.h"
#include "../../src/utils/fs.h"
#include "../../src/utils/path.h"
#include "../../src/utils/string_array.h"
#include "../../src/dir_stack.h"
#include "../../src/filelist.h"

static void load_view_pair(const char left_path[], const char right_path[]);

static char cwd[PATH_MAX + 1];

SETUP_ONCE()
{
	assert_non_null(get_cwd(cwd, sizeof(cwd)));
}

SETUP()
{
	dir_stack_clear();
	dir_stack_freeze();

	view_setup(&lwin);
	view_setup(&rwin);

	strcpy(lwin.curr_dir, "/left");
	strcpy(rwin.curr_dir, "/right");

	curr_view = &lwin;
	other_view = &rwin;

	opt_handlers_setup();
}

TEARDOWN()
{
	view_teardown(&lwin);
	view_teardown(&rwin);

	opt_handlers_teardown();
}

TEST(underflow_is_detected)
{
	assert_failure(dir_stack_pop());
}

TEST(pop_returns_views_to_previous_location)
{
	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");
	assert_success(dir_stack_push_current());

	strcpy(lwin.curr_dir, "/new-left");
	strcpy(rwin.curr_dir, "/new-right");

	assert_success(dir_stack_pop());

	assert_false(strcmp(lwin.curr_dir, "/new-left") == 0);
	assert_false(strcmp(rwin.curr_dir, "/new-right") == 0);
}

TEST(swap_swaps_current_locations_and_stack_top)
{
	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");
	assert_success(dir_stack_push_current());
	load_view_pair(TEST_DATA_PATH "/rename", TEST_DATA_PATH "/read");

	assert_success(dir_stack_swap());

	assert_string_ends_with("/read", lwin.curr_dir);
	assert_string_ends_with("/rename", rwin.curr_dir);

	assert_success(dir_stack_swap());

	assert_string_ends_with("/rename", lwin.curr_dir);
	assert_string_ends_with("/read", rwin.curr_dir);
}

TEST(empty_stack_is_described_via_current_directories)
{
	char **list = dir_stack_list();
	assert_string_equal("/left", list[0]);
	assert_string_equal("/right", list[1]);
	assert_string_equal(NULL, list[2]);
	free_string_array(list, 3);
}

TEST(non_empty_stack_is_described_correctly)
{
	char **list;

	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");
	assert_success(dir_stack_push_current());
	load_view_pair(TEST_DATA_PATH "/rename", TEST_DATA_PATH "/read");
	assert_success(dir_stack_push_current());

	strcpy(lwin.curr_dir, "/new-left");
	strcpy(rwin.curr_dir, "/new-right");

	list = dir_stack_list();
	assert_string_equal("/new-left", list[0]);
	assert_string_equal("/new-right", list[1]);
	assert_string_equal("-----", list[2]);
	assert_string_ends_with("/rename", list[3]);
	assert_string_ends_with("/read", list[4]);
	assert_string_equal("-----", list[5]);
	assert_string_ends_with("/read", list[6]);
	assert_string_ends_with("/rename", list[7]);
	assert_string_equal(NULL, list[8]);
	free_string_array(list, 9);
}

TEST(stack_is_changed_by_push_and_successful_pop)
{
	/* Push. */

	assert_false(dir_stack_changed());

	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");

	assert_success(dir_stack_push_current());
	assert_true(dir_stack_changed());

	/* Successful pop. */

	dir_stack_freeze();
	assert_false(dir_stack_changed());

	assert_success(dir_stack_pop());
	assert_true(dir_stack_changed());

	/* Failed pop. */

	dir_stack_freeze();
	assert_false(dir_stack_changed());

	assert_failure(dir_stack_pop());
	assert_false(dir_stack_changed());
}

TEST(rotate_does_nothing_for_zero_argument)
{
	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");
	assert_success(dir_stack_push_current());
	load_view_pair(TEST_DATA_PATH "/rename", TEST_DATA_PATH "/read");

	assert_success(dir_stack_rotate(0));

	assert_string_ends_with("/rename", lwin.curr_dir);
	assert_string_ends_with("/read", rwin.curr_dir);
}

TEST(rotate_rotates_the_stack)
{
	load_view_pair(TEST_DATA_PATH "/read", TEST_DATA_PATH "/rename");
	assert_success(dir_stack_push_current());
	load_view_pair(TEST_DATA_PATH "/tree", TEST_DATA_PATH "/various-sizes");
	assert_success(dir_stack_push_current());
	load_view_pair(TEST_DATA_PATH "/rename", TEST_DATA_PATH "/read");

	assert_success(dir_stack_rotate(2));
	assert_string_ends_with("/read", lwin.curr_dir);
	assert_string_ends_with("/rename", rwin.curr_dir);

	assert_success(dir_stack_rotate(2));
	assert_string_ends_with("/tree", lwin.curr_dir);
	assert_string_ends_with("/various-sizes", rwin.curr_dir);

	assert_success(dir_stack_rotate(2));
	assert_string_ends_with("/rename", lwin.curr_dir);
	assert_string_ends_with("/read", rwin.curr_dir);

	assert_success(dir_stack_rotate(1));
	assert_string_ends_with("/tree", lwin.curr_dir);
	assert_string_ends_with("/various-sizes", rwin.curr_dir);
}

static void
load_view_pair(const char left_path[], const char right_path[])
{
	char path[PATH_MAX + 1];

	make_abs_path(path, sizeof(path), left_path, "", cwd);
	to_canonic_path(path, "", lwin.curr_dir, sizeof(lwin.curr_dir));
	populate_dir_list(&lwin, 0);

	make_abs_path(path, sizeof(path), right_path, "", cwd);
	to_canonic_path(path, "", rwin.curr_dir, sizeof(rwin.curr_dir));
	populate_dir_list(&rwin, 0);
}

/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
/* vim: set cinoptions+=t0 filetype=c : */
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master