aboutsummaryrefslogtreecommitdiff
path: root/tests/functional/repl_characterization/repl_characterization.cc
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-03-09 23:59:50 -0800
committerJade Lovelace <lix@jade.fyi>2024-03-15 12:31:16 -0700
commit18ed6c3bdf2c03c763c0d128083f507295bcf864 (patch)
tree7b3a03bad074f50ecdff4d331ca5ce18d463ec62 /tests/functional/repl_characterization/repl_characterization.cc
parent38571c50e6dc0ee910e9e7619e482fdbbfd644e1 (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.cc58
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); });
+}
+
};