diff options
author | Jade Lovelace <lix@jade.fyi> | 2024-03-09 23:59:50 -0800 |
---|---|---|
committer | Jade Lovelace <lix@jade.fyi> | 2024-03-15 12:31:16 -0700 |
commit | 18ed6c3bdf2c03c763c0d128083f507295bcf864 (patch) | |
tree | 7b3a03bad074f50ecdff4d331ca5ce18d463ec62 /tests/functional/repl_characterization/repl_characterization.cc | |
parent | 38571c50e6dc0ee910e9e7619e482fdbbfd644e1 (diff) |
Implement a repl characterization test system
This allows for automating using the repl without needing a PTY, with
very easy to write test files.
Change-Id: Ia8d7854edd91f93477638942cb6fc261354e6035
Diffstat (limited to 'tests/functional/repl_characterization/repl_characterization.cc')
-rw-r--r-- | tests/functional/repl_characterization/repl_characterization.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tests/functional/repl_characterization/repl_characterization.cc b/tests/functional/repl_characterization/repl_characterization.cc index 5b73e7a89..993c30232 100644 --- a/tests/functional/repl_characterization/repl_characterization.cc +++ b/tests/functional/repl_characterization/repl_characterization.cc @@ -5,8 +5,11 @@ #include <optional> #include <unistd.h> +#include "test-session.hh" +#include "util.hh" #include "tests/characterization.hh" #include "tests/cli-literate-parser.hh" +#include "tests/terminal-code-eater.hh" using namespace std::string_literals; @@ -14,6 +17,18 @@ namespace nix { static constexpr const char * REPL_PROMPT = "nix-repl> "; +// ASCII ENQ character +static constexpr const char * AUTOMATION_PROMPT = "\x05"; + +static std::string_view trimOutLog(std::string_view outLog) +{ + const std::string trailer = "\n"s + AUTOMATION_PROMPT; + if (outLog.ends_with(trailer)) { + outLog.remove_suffix(trailer.length()); + } + return outLog; +} + class ReplSessionTest : public CharacterizationTest { Path unitTestData = getUnitTestData(); @@ -23,6 +38,43 @@ public: { return unitTestData + "/" + testStem; } + + void runReplTest(std::string_view const & content, std::vector<std::string> extraArgs = {}) const + { + auto syntax = CLILiterateParser::parse(REPL_PROMPT, content); + + // FIXME: why does this need two --quiets + // show-trace is on by default due to test configuration, but is not a standard + Strings args{"--quiet", "repl", "--quiet", "--option", "show-trace", "false", "--offline", "--extra-experimental-features", "repl-automation"}; + args.insert(args.end(), extraArgs.begin(), extraArgs.end()); + + auto nixBin = canonPath(getEnvNonEmpty("NIX_BIN_DIR").value_or(NIX_BIN_DIR)); + + auto process = RunningProcess::start(nixBin + "/nix", args); + auto session = TestSession{AUTOMATION_PROMPT, std::move(process)}; + + for (auto & bit : syntax) { + if (bit.kind != CLILiterateParser::NodeKind::COMMAND) { + continue; + } + + if (!session.waitForPrompt()) { + ASSERT_TRUE(false); + } + session.runCommand(bit.text); + } + if (!session.waitForPrompt()) { + ASSERT_TRUE(false); + } + session.close(); + + auto parsedOutLog = CLILiterateParser::parse(AUTOMATION_PROMPT, trimOutLog(session.outLog), 0); + + parsedOutLog = CLILiterateParser::tidyOutputForComparison(std::move(parsedOutLog)); + syntax = CLILiterateParser::tidyOutputForComparison(std::move(syntax)); + + ASSERT_EQ(parsedOutLog, syntax); + } }; TEST_F(ReplSessionTest, parses) @@ -39,4 +91,10 @@ TEST_F(ReplSessionTest, parses) return out.str(); }); } + +TEST_F(ReplSessionTest, repl_basic) +{ + readTest("basic_repl.test", [this](std::string input) { runReplTest(input); }); +} + }; |