mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-24 15:02:37 +08:00
Add a test for autoload_t
This commit is contained in:
parent
4ff50eba41
commit
51c62d6cc6
|
@ -144,6 +144,11 @@ autoload_t::autoload_t(wcstring env_var_name)
|
|||
autoload_t::autoload_t(autoload_t &&) = default;
|
||||
autoload_t::~autoload_t() = default;
|
||||
|
||||
void autoload_t::invalidate_cache() {
|
||||
auto cache = make_unique<autoload_file_cache_t>(cache_->dirs());
|
||||
cache_ = std::move(cache);
|
||||
}
|
||||
|
||||
bool autoload_t::can_autoload(const wcstring &cmd) {
|
||||
return cache_->check(cmd, true /* allow stale */).has_value();
|
||||
}
|
||||
|
@ -160,15 +165,17 @@ wcstring_list_t autoload_t::get_autoloaded_commands() const {
|
|||
}
|
||||
|
||||
maybe_t<wcstring> autoload_t::resolve_command(const wcstring &cmd, const environment_t &env) {
|
||||
maybe_t<env_var_t> mvar = env.get(env_var_name_);
|
||||
return resolve_command(cmd, mvar ? mvar->as_list() : wcstring_list_t{});
|
||||
}
|
||||
|
||||
maybe_t<wcstring> autoload_t::resolve_command(const wcstring &cmd, const wcstring_list_t &paths) {
|
||||
// Are we currently in the process of autoloading this?
|
||||
if (current_autoloading_.count(cmd) > 0) return none();
|
||||
|
||||
// Check to see if our paths have changed. If so, replace our cache.
|
||||
// Note we don't have to modify autoloadable_files_. We'll naturally detect if those have
|
||||
// changed when we query the cache.
|
||||
maybe_t<env_var_t> mvar = env.get(env_var_name_);
|
||||
const wcstring_list_t empty;
|
||||
const wcstring_list_t &paths = mvar ? mvar->as_list() : empty;
|
||||
if (paths != cache_->dirs()) {
|
||||
cache_ = make_unique<autoload_file_cache_t>(paths);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class autoload_file_cache_t;
|
||||
class environment_t;
|
||||
struct autoload_tester_t;
|
||||
|
||||
/// autoload_t is a class that knows how to autoload .fish files from a list of directories. This
|
||||
/// is used by autoloading functions and completions. It maintains a file cache, which is
|
||||
|
@ -38,6 +39,16 @@ class autoload_t {
|
|||
/// changes. This is never null (but it may be a cache with no paths).
|
||||
std::unique_ptr<autoload_file_cache_t> cache_;
|
||||
|
||||
/// Invalidate any underlying cache.
|
||||
/// This is exposed for testing.
|
||||
void invalidate_cache();
|
||||
|
||||
/// Like resolve_autoload(), but accepts the paths directly.
|
||||
/// This is exposed for testing.
|
||||
maybe_t<wcstring> resolve_command(const wcstring &cmd, const wcstring_list_t &paths);
|
||||
|
||||
friend autoload_tester_t;
|
||||
|
||||
public:
|
||||
/// Construct an autoloader that loads from the paths given by \p env_var_name.
|
||||
explicit autoload_t(wcstring env_var_name);
|
||||
|
@ -76,7 +87,8 @@ class autoload_t {
|
|||
/// This does not actually mark the command as being autoloaded.
|
||||
bool can_autoload(const wcstring &cmd);
|
||||
|
||||
/// \return the names of all commands that have been autoloaded.
|
||||
/// \return the names of all commands that have been autoloaded. Note this includes "in-flight"
|
||||
/// commands.
|
||||
wcstring_list_t get_autoloaded_commands() const;
|
||||
|
||||
/// Mark that all autoloaded files have been forgotten.
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "autoload.h"
|
||||
#include "builtin.h"
|
||||
#include "color.h"
|
||||
#include "common.h"
|
||||
|
@ -2472,6 +2473,74 @@ static void test_colors() {
|
|||
do_test(rgb_color_t(L"mooganta").is_none());
|
||||
}
|
||||
|
||||
// This class allows accessing private bits of autoload_t.
|
||||
struct autoload_tester_t {
|
||||
static void run(const wchar_t *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
wcstring cmd = vformat_string(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
int status = system(wcs2string(cmd).c_str());
|
||||
do_test(status == 0);
|
||||
}
|
||||
|
||||
static void run_test() {
|
||||
char t1[] = "/tmp/fish_test_autoload.XXXXXX";
|
||||
wcstring p1 = str2wcstring(mkdtemp(t1));
|
||||
char t2[] = "/tmp/fish_test_autoload.XXXXXX";
|
||||
wcstring p2 = str2wcstring(mkdtemp(t2));
|
||||
|
||||
const wcstring_list_t paths = {p1, p2};
|
||||
|
||||
autoload_t autoload(L"test_var");
|
||||
do_test(!autoload.resolve_command(L"file1", paths));
|
||||
do_test(!autoload.resolve_command(L"nothing", paths));
|
||||
do_test(autoload.get_autoloaded_commands().empty());
|
||||
|
||||
run(L"touch %ls/file1.fish", p1.c_str());
|
||||
run(L"touch %ls/file2.fish", p2.c_str());
|
||||
autoload.invalidate_cache();
|
||||
|
||||
do_test(!autoload.autoload_in_progress(L"file1"));
|
||||
do_test(autoload.resolve_command(L"file1", paths));
|
||||
do_test(!autoload.resolve_command(L"file1", paths));
|
||||
do_test(autoload.autoload_in_progress(L"file1"));
|
||||
do_test(autoload.get_autoloaded_commands() == wcstring_list_t{L"file1"});
|
||||
autoload.mark_autoload_finished(L"file1");
|
||||
do_test(!autoload.autoload_in_progress(L"file1"));
|
||||
do_test(autoload.get_autoloaded_commands() == wcstring_list_t{L"file1"});
|
||||
|
||||
do_test(!autoload.resolve_command(L"file1", paths));
|
||||
do_test(!autoload.resolve_command(L"nothing", paths));
|
||||
do_test(autoload.resolve_command(L"file2", paths));
|
||||
do_test(!autoload.resolve_command(L"file2", paths));
|
||||
autoload.mark_autoload_finished(L"file2");
|
||||
do_test(!autoload.resolve_command(L"file2", paths));
|
||||
do_test((autoload.get_autoloaded_commands() == wcstring_list_t{L"file1", L"file2"}));
|
||||
|
||||
autoload.clear();
|
||||
do_test(autoload.resolve_command(L"file1", paths));
|
||||
autoload.mark_autoload_finished(L"file1");
|
||||
do_test(!autoload.resolve_command(L"file1", paths));
|
||||
do_test(!autoload.resolve_command(L"nothing", paths));
|
||||
do_test(autoload.resolve_command(L"file2", paths));
|
||||
do_test(!autoload.resolve_command(L"file2", paths));
|
||||
autoload.mark_autoload_finished(L"file2");
|
||||
|
||||
do_test(!autoload.resolve_command(L"file1", paths));
|
||||
run(L"touch %ls/file1.fish", p1.c_str());
|
||||
autoload.invalidate_cache();
|
||||
do_test(autoload.resolve_command(L"file1", paths));
|
||||
autoload.mark_autoload_finished(L"file1");
|
||||
}
|
||||
};
|
||||
|
||||
static void test_autoload() {
|
||||
say(L"Testing autoload");
|
||||
autoload_tester_t::run_test();
|
||||
}
|
||||
|
||||
static void test_complete() {
|
||||
say(L"Testing complete");
|
||||
|
||||
|
@ -5289,6 +5358,7 @@ int main(int argc, char **argv) {
|
|||
if (should_test_function("is_potential_path")) test_is_potential_path();
|
||||
if (should_test_function("colors")) test_colors();
|
||||
if (should_test_function("complete")) test_complete();
|
||||
if (should_test_function("autoload")) test_autoload();
|
||||
if (should_test_function("input")) test_input();
|
||||
if (should_test_function("line_iterator")) test_line_iterator();
|
||||
if (should_test_function("universal")) test_universal();
|
||||
|
|
Loading…
Reference in New Issue
Block a user