mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 08:06:03 +02:00
History, more test coverage improvements, and refactorings. (#3217)
Improvements overall to Nu. Also among the changes here, we can also be more confident towards incorporating `3041`. End to end tests for checking envs properly exported to externals is not added here (since it's in the other PR) A few things added in this PR (probably forgetting some too) * no writes happen to history during test runs. * environment syncing end to end coverage added. * clean up / refactorings few areas. * testing API for finer control (can write tests passing more than one pipeline) * can pass environment variables in tests that nu will inherit when running. * No longer needed. * no longer under a module. No need to use super.
This commit is contained in:
committed by
GitHub
parent
b243b3ee1d
commit
8fc8fc89aa
@ -1,48 +1,66 @@
|
||||
use super::nu_process::*;
|
||||
use super::EnvironmentVariable;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Director {
|
||||
pub cwd: Option<OsString>,
|
||||
pub environment_vars: Vec<EnvironmentVariable>,
|
||||
pub config: Option<OsString>,
|
||||
pub pipeline: Option<String>,
|
||||
pub pipeline: Option<Vec<String>>,
|
||||
pub executable: Option<NuProcess>,
|
||||
}
|
||||
|
||||
impl Director {
|
||||
pub fn cococo(&self, arg: &str) -> Self {
|
||||
let mut process = NuProcess::default();
|
||||
let mut process = NuProcess {
|
||||
environment_vars: self.environment_vars.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
process.args(&["--testbin", "cococo", arg]);
|
||||
Director {
|
||||
config: self.config.clone(),
|
||||
executable: Some(process),
|
||||
environment_vars: self.environment_vars.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn and_then(&mut self, commands: &str) -> &mut Self {
|
||||
let commands = commands.to_string();
|
||||
|
||||
if let Some(ref mut pipeline) = self.pipeline {
|
||||
pipeline.push(commands);
|
||||
} else {
|
||||
self.pipeline = Some(vec![commands]);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn pipeline(&self, commands: &str) -> Self {
|
||||
let mut director = Director {
|
||||
pipeline: if commands.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(format!(
|
||||
"
|
||||
{}
|
||||
exit",
|
||||
commands
|
||||
))
|
||||
Some(vec![commands.to_string()])
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut process = NuProcess::default();
|
||||
let mut process = NuProcess {
|
||||
environment_vars: self.environment_vars.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(working_directory) = &self.cwd {
|
||||
process.cwd(working_directory);
|
||||
}
|
||||
|
||||
process.arg("--skip-plugins");
|
||||
process.arg("--no-history");
|
||||
if let Some(config_file) = self.config.as_ref() {
|
||||
process.args(&[
|
||||
"--config-file",
|
||||
@ -64,7 +82,7 @@ impl Director {
|
||||
}
|
||||
|
||||
impl Executable for Director {
|
||||
fn execute(&self) -> NuResult {
|
||||
fn execute(&mut self) -> NuResult {
|
||||
use std::io::Write;
|
||||
use std::process::Stdio;
|
||||
|
||||
@ -81,13 +99,16 @@ impl Executable for Director {
|
||||
Err(why) => panic!("Can't run test {}", why.to_string()),
|
||||
};
|
||||
|
||||
if let Some(pipeline) = &self.pipeline {
|
||||
process
|
||||
.stdin
|
||||
.as_mut()
|
||||
.expect("couldn't open stdin")
|
||||
.write_all(pipeline.as_bytes())
|
||||
.expect("couldn't write to stdin");
|
||||
if let Some(pipelines) = &self.pipeline {
|
||||
let child = process.stdin.as_mut().expect("Failed to open stdin");
|
||||
|
||||
for pipeline in pipelines.iter() {
|
||||
child
|
||||
.write_all(format!("{}\n", pipeline).as_bytes())
|
||||
.expect("Could not write to");
|
||||
}
|
||||
|
||||
child.write_all(b"exit\n").expect("Could not write to");
|
||||
}
|
||||
|
||||
process
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::fs::executable_path;
|
||||
use std::collections::HashMap;
|
||||
use super::EnvironmentVariable;
|
||||
use crate::fs::{binaries as test_bins_path, executable_path};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, ExitStatus};
|
||||
|
||||
pub trait Executable {
|
||||
fn execute(&self) -> NuResult;
|
||||
fn execute(&mut self) -> NuResult;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -36,7 +36,7 @@ pub struct NuError {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NuProcess {
|
||||
pub arguments: Vec<OsString>,
|
||||
pub environment_vars: HashMap<String, Option<OsString>>,
|
||||
pub environment_vars: Vec<EnvironmentVariable>,
|
||||
pub cwd: Option<OsString>,
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ impl Default for NuProcess {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
arguments: vec![],
|
||||
environment_vars: HashMap::default(),
|
||||
environment_vars: Vec::default(),
|
||||
cwd: None,
|
||||
}
|
||||
}
|
||||
@ -90,6 +90,21 @@ impl NuProcess {
|
||||
command.current_dir(cwd);
|
||||
}
|
||||
|
||||
command.env_clear();
|
||||
|
||||
let paths = vec![test_bins_path()];
|
||||
|
||||
let paths_joined = match std::env::join_paths(paths.iter()) {
|
||||
Ok(all) => all,
|
||||
Err(_) => panic!("Couldn't join paths for PATH var."),
|
||||
};
|
||||
|
||||
command.env("PATH", paths_joined);
|
||||
|
||||
for env_var in &self.environment_vars {
|
||||
command.env(&env_var.name, &env_var.value);
|
||||
}
|
||||
|
||||
for arg in &self.arguments {
|
||||
command.arg(arg);
|
||||
}
|
||||
|
@ -7,11 +7,27 @@ use std::path::{Path, PathBuf};
|
||||
use std::str;
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct EnvironmentVariable {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl EnvironmentVariable {
|
||||
fn new(name: &str, value: &str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
value: value.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Playground<'a> {
|
||||
root: TempDir,
|
||||
tests: String,
|
||||
cwd: PathBuf,
|
||||
config: PathBuf,
|
||||
environment_vars: Vec<EnvironmentVariable>,
|
||||
dirs: &'a Dirs,
|
||||
}
|
||||
|
||||
@ -71,6 +87,7 @@ impl<'a> Playground<'a> {
|
||||
tests: topic.to_string(),
|
||||
cwd: nuplay_dir,
|
||||
config: fixtures.join("playground/config/default.toml"),
|
||||
environment_vars: Vec::default(),
|
||||
dirs: &Dirs::default(),
|
||||
};
|
||||
|
||||
@ -108,6 +125,12 @@ impl<'a> Playground<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_env(&mut self, name: &str, value: &str) -> &mut Self {
|
||||
self.environment_vars
|
||||
.push(EnvironmentVariable::new(name, value));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_config(&self) -> &str {
|
||||
self.config.to_str().expect("could not convert path.")
|
||||
}
|
||||
@ -116,6 +139,7 @@ impl<'a> Playground<'a> {
|
||||
Director {
|
||||
cwd: Some(self.dirs.test().into()),
|
||||
config: Some(self.config.clone().into()),
|
||||
environment_vars: self.environment_vars.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user