Add a test for history path detection

This will support history path detection improvements in a future
commit.
This commit is contained in:
ridiculousfish 2020-12-30 00:40:56 -08:00
parent 686d64cf05
commit f03ff8cd00

View File

@ -1884,26 +1884,47 @@ static void test_lru() {
do_test(cache.evicted.size() == size_t(total_nodes)); do_test(cache.evicted.size() == size_t(total_nodes));
} }
/// A crappy environment_t that only knows about PWD. /// An environment built around an std::map.
struct pwd_environment_t : public environment_t { struct test_environment_t : public environment_t {
std::map<wcstring, wcstring> extras; std::map<wcstring, wcstring> vars;
virtual maybe_t<env_var_t> get(const wcstring &key, virtual maybe_t<env_var_t> get(const wcstring &key,
env_mode_flags_t mode = ENV_DEFAULT) const override { env_mode_flags_t mode = ENV_DEFAULT) const override {
UNUSED(mode); UNUSED(mode);
if (key == L"PWD") { auto iter = vars.find(key);
return env_var_t{wgetcwd(), 0}; if (iter != vars.end()) {
return env_var_t(iter->second, ENV_DEFAULT);
} }
auto extra = extras.find(key); return none();
if (extra != extras.end()) {
return env_var_t(extra->second, ENV_DEFAULT);
}
return {};
} }
wcstring_list_t get_names(int flags) const override { wcstring_list_t get_names(int flags) const override {
UNUSED(flags); UNUSED(flags);
return {L"PWD"}; wcstring_list_t result;
for (const auto &kv : vars) {
result.push_back(kv.first);
}
return result;
}
};
/// A test environment that knows about PWD.
struct pwd_environment_t : public test_environment_t {
virtual maybe_t<env_var_t> get(const wcstring &key,
env_mode_flags_t mode = ENV_DEFAULT) const override {
if (key == L"PWD") {
return env_var_t{wgetcwd(), 0};
}
return test_environment_t::get(key, mode);
}
wcstring_list_t get_names(int flags) const override {
auto res = test_environment_t::get_names(flags);
res.clear();
if (std::count(res.begin(), res.end(), L"PWD") == 0) {
res.push_back(L"PWD");
}
return res;
} }
}; };
@ -3323,7 +3344,7 @@ static void test_autosuggest_suggest_special() {
const wcstring wd = L"test/autosuggest_test"; const wcstring wd = L"test/autosuggest_test";
pwd_environment_t vars{}; pwd_environment_t vars{};
vars.extras[L"HOME"] = parser_t::principal_parser().vars().get(L"HOME")->as_string(); vars.vars[L"HOME"] = parser_t::principal_parser().vars().get(L"HOME")->as_string();
perform_one_autosuggestion_cd_test(L"cd test/autosuggest_test/0", L"foobar/", vars, __LINE__); perform_one_autosuggestion_cd_test(L"cd test/autosuggest_test/0", L"foobar/", vars, __LINE__);
perform_one_autosuggestion_cd_test(L"cd \"test/autosuggest_test/0", L"foobar/", vars, __LINE__); perform_one_autosuggestion_cd_test(L"cd \"test/autosuggest_test/0", L"foobar/", vars, __LINE__);
@ -3352,7 +3373,7 @@ static void test_autosuggest_suggest_special() {
perform_one_autosuggestion_cd_test(L"cd 'test/autosuggest_test/5", L"foo\"bar/", vars, perform_one_autosuggestion_cd_test(L"cd 'test/autosuggest_test/5", L"foo\"bar/", vars,
__LINE__); __LINE__);
vars.extras[L"AUTOSUGGEST_TEST_LOC"] = wd; vars.vars[L"AUTOSUGGEST_TEST_LOC"] = wd;
perform_one_autosuggestion_cd_test(L"cd $AUTOSUGGEST_TEST_LOC/0", L"foobar/", vars, __LINE__); perform_one_autosuggestion_cd_test(L"cd $AUTOSUGGEST_TEST_LOC/0", L"foobar/", vars, __LINE__);
perform_one_autosuggestion_cd_test(L"cd ~/test_autosuggest_suggest_specia", L"l/", vars, perform_one_autosuggestion_cd_test(L"cd ~/test_autosuggest_suggest_specia", L"l/", vars,
__LINE__); __LINE__);
@ -3934,6 +3955,7 @@ class history_tests_t {
public: public:
static void test_history(); static void test_history();
static void test_history_merge(); static void test_history_merge();
static void test_history_path_detection();
static void test_history_formats(); static void test_history_formats();
// static void test_history_speed(void); // static void test_history_speed(void);
static void test_history_races(); static void test_history_races();
@ -4286,6 +4308,73 @@ void history_tests_t::test_history_merge() {
everything->clear(); everything->clear();
} }
void history_tests_t::test_history_path_detection() {
// Regression test for #7582.
say(L"Testing history path detection");
char tmpdirbuff[] = "/tmp/fish_test_history.XXXXXX";
wcstring tmpdir = str2wcstring(mkdtemp(tmpdirbuff));
if (! string_suffixes_string(L"/", tmpdir)) {
tmpdir.push_back(L'/');
}
// Place one valid file in the directory.
wcstring filename = L"testfile";
std::string path = wcs2string(tmpdir + filename);
FILE *f = fopen(path.c_str(), "w");
if (!f) {
err(L"Failed to open test file from history path detection");
return;
}
fclose(f);
test_environment_t vars;
vars.vars[L"PWD"] = tmpdir;
vars.vars[L"HOME"] = tmpdir;
history_t &history = history_t::history_with_name(L"path_detection");
history.add_pending_with_file_detection(L"cmd0 not/a/valid/path", tmpdir);
history.add_pending_with_file_detection(L"cmd1 " + filename, tmpdir);
history.add_pending_with_file_detection(L"cmd2 " + tmpdir + L"/" + filename, tmpdir);
history.resolve_pending();
constexpr size_t hist_size = 3;
if (history.size() != hist_size) {
err(L"history has wrong size: %lu but expected %lu", (unsigned long)history.size(), (unsigned long)hist_size);
history.clear();
return;
}
// Expected sets of paths.
wcstring_list_t expected[hist_size] = {
{},
{filename},
{tmpdir + L"/" + filename},
};
size_t lap;
const size_t maxlap = 128;
for (lap = 0; lap < maxlap; lap++) {
int failures = 0;
bool last = (lap + 1 == maxlap);
for (size_t i = 1; i <= hist_size; i++) {
if (history.item_at_index(i).required_paths != expected[hist_size - i]) {
failures += 1;
if (last) {
err(L"Wrong detected paths for item %lu", (unsigned long)i);
}
}
}
if (failures == 0) {
break;
}
// The file detection takes a little time since it occurs in the background.
// Loop until the test passes.
usleep(1E6 / 500); // 1 msec
}
//fprintf(stderr, "History saving took %lu laps\n", (unsigned long)lap);
history.clear();
}
static bool install_sample_history(const wchar_t *name) { static bool install_sample_history(const wchar_t *name) {
wcstring path; wcstring path;
if (!path_get_data(path)) { if (!path_get_data(path)) {
@ -6198,6 +6287,7 @@ int main(int argc, char **argv) {
if (should_test_function("autosuggest_suggest_special")) test_autosuggest_suggest_special(); if (should_test_function("autosuggest_suggest_special")) test_autosuggest_suggest_special();
if (should_test_function("history")) history_tests_t::test_history(); if (should_test_function("history")) history_tests_t::test_history();
if (should_test_function("history_merge")) history_tests_t::test_history_merge(); if (should_test_function("history_merge")) history_tests_t::test_history_merge();
if (should_test_function("history_paths")) history_tests_t::test_history_path_detection();
if (!is_windows_subsystem_for_linux()) { if (!is_windows_subsystem_for_linux()) {
// this test always fails under WSL // this test always fails under WSL
if (should_test_function("history_races")) history_tests_t::test_history_races(); if (should_test_function("history_races")) history_tests_t::test_history_races();