on master help sign in
Add integration tests for 'more' and 'most' used as pagers
commitc9efdd68edd6fede17ff21cac1d8ce0f826194f2 authorMartin Nordholts <enselic@gmail.com> dateMon 4 Jan 2021, 10:23 (6 years ago) parentbfa5342
3 files changed+127−18
tests/integration_tests.rs+123−18 tests/mocked-pagers/more+2 tests/mocked-pagers/most+2
tests/integration_tests.rs+123−18
@@ -1,6 +1,7 @@
11use assert_cmd::Command;
22use predicates::{prelude::predicate, str::PredicateStrExt};
3−use std::path::Path;
3+use std::env;
4+use std::path::{Path, PathBuf};
45use std::str::from_utf8;
56
67const EXAMPLES_DIR: &str = "tests/examples";
@@ -23,6 +24,61 @@ fn bat() -> Command {
2324 cmd
2425}
2526
27+/// For some tests we want mocked versions of some pagers
28+/// This fn returns the absolute path to the directory with these mocked pagers
29+fn get_mocked_pagers_dir() -> PathBuf {
30+ let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("Missing CARGO_MANIFEST_DIR");
31+ Path::new(&cargo_manifest_dir)
32+ .join("tests")
33+ .join("mocked-pagers")
34+}
35+
36+/// Prepends a directory to the PATH environment variable
37+/// Returns the original value for later restoration
38+fn prepend_dir_to_path_env_var(dir: PathBuf) -> String {
39+ // Get current PATH
40+ let original_path = env::var("PATH").expect("No PATH?!");
41+
42+ // Add the new dir first
43+ let mut split_paths = env::split_paths(&original_path).collect::<Vec<_>>();
44+ split_paths.insert(0, dir);
45+
46+ // Set PATH with the new dir
47+ let new_path = env::join_paths(split_paths).expect("Failed to join paths");
48+ env::set_var("PATH", new_path);
49+
50+ // Return the original value for later restoration of it
51+ original_path
52+}
53+
54+/// Helper to restore the value of PATH
55+fn restore_path(original_path: String) {
56+ env::set_var("PATH", original_path);
57+}
58+
59+/// Allows test to run that require our mocked versions of 'more' and 'most'
60+/// in PATH. Temporarily changes PATH while the test code runs, and then restore it
61+/// to avoid pollution of global state
62+fn with_mocked_versions_of_more_and_most_in_path(actual_test: fn()) {
63+ let original_path = prepend_dir_to_path_env_var(get_mocked_pagers_dir());
64+
65+ // Make sure our own variants of 'more' and 'most' is used
66+ Command::new("more")
67+ .assert()
68+ .success()
69+ .stdout("I am more\n");
70+ Command::new("most")
71+ .assert()
72+ .success()
73+ .stdout("I am most\n");
74+
75+ // Now run the actual test
76+ actual_test();
77+
78+ // Make sure to restore PATH since it is global state
79+ restore_path(original_path);
80+}
81+
2682#[test]
2783fn basic() {
2884 bat()
@@ -415,28 +471,77 @@ fn pager_value_bat() {
415471 .failure();
416472}
417473
474+/// We shall use less instead of most if PAGER is used since PAGER
475+/// is a generic env var
418476#[test]
419−fn pager_most() {
420− bat()
421− .env("PAGER", "most")
422− .arg("--paging=always")
423− .arg("test.txt")
424− .assert()
425− .success()
426− .stdout(predicate::eq("hello world\n").normalize());
427− // TODO: How to ensure less is used?
477+fn pager_most_from_pager_env_var() {
478+ with_mocked_versions_of_more_and_most_in_path(|| {
479+ // If the output is not "I am most\n" then we know 'most' is not used
480+ bat()
481+ .env("PAGER", "most")
482+ .arg("--paging=always")
483+ .arg("test.txt")
484+ .assert()
485+ .success()
486+ .stdout(predicate::eq("hello world\n").normalize());
487+ });
488+}
489+
490+/// If the bat-specific BAT_PAGER is used, obey the wish of the user
491+/// and allow 'most'
492+#[test]
493+fn pager_most_from_bat_pager_env_var() {
494+ with_mocked_versions_of_more_and_most_in_path(|| {
495+ bat()
496+ .env("BAT_PAGER", "most")
497+ .arg("--paging=always")
498+ .arg("test.txt")
499+ .assert()
500+ .success()
501+ .stdout(predicate::eq("I am most\n").normalize());
502+ });
428503}
429504
505+/// Same reasoning with --pager as with BAT_PAGER
506+#[test]
507+fn pager_most_from_pager_arg() {
508+ with_mocked_versions_of_more_and_most_in_path(|| {
509+ bat()
510+ .arg("--paging=always")
511+ .arg("--pager=most")
512+ .arg("test.txt")
513+ .assert()
514+ .success()
515+ .stdout(predicate::eq("I am most\n").normalize());
516+ });
517+}
518+
519+/// Make sure the logic for 'most' applies even if an argument is passed
430520#[test]
431521fn pager_most_with_arg() {
432− bat()
433− .env("PAGER", "most -w")
434− .arg("--paging=always")
435− .arg("test.txt")
436− .assert()
437− .success()
438− .stdout(predicate::eq("hello world\n").normalize());
439− // TODO: How to ensure less is used?
522+ with_mocked_versions_of_more_and_most_in_path(|| {
523+ bat()
524+ .env("PAGER", "most -w")
525+ .arg("--paging=always")
526+ .arg("test.txt")
527+ .assert()
528+ .success()
529+ .stdout(predicate::eq("hello world\n").normalize());
530+ });
531+}
532+
533+/// Sanity check that 'more' is treated like 'most'
534+#[test]
535+fn pager_more() {
536+ with_mocked_versions_of_more_and_most_in_path(|| {
537+ bat()
538+ .env("PAGER", "more")
539+ .arg("--paging=always")
540+ .arg("test.txt")
541+ .assert()
542+ .success()
543+ .stdout(predicate::eq("hello world\n").normalize());
544+ });
440545}
441546
442547#[test]
tests/mocked-pagers/morenew file+2
@@ -0,0 +1,2 @@
1+#!/usr/bin/env bash
2+echo "I am more"
tests/mocked-pagers/mostnew file+2
@@ -0,0 +1,2 @@
1+#!/usr/bin/env bash
2+echo "I am most"