/crates/nu-test-support/src/macros.rs

https://github.com/nushell/nushell · Rust · 170 lines · 138 code · 32 blank · 0 comment · 4 complexity · f86ce285d76c7bd538470d3935da6fa7 MD5 · raw file

  1. #[macro_export]
  2. macro_rules! nu {
  3. (cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
  4. use $crate::fs::DisplayPath;
  5. let path = format!($path, $(
  6. $part.display_path()
  7. ),*);
  8. nu!($cwd, &path)
  9. }};
  10. (cwd: $cwd:expr, $path:expr) => {{
  11. nu!($cwd, $path)
  12. }};
  13. ($cwd:expr, $path:expr) => {{
  14. pub use std::error::Error;
  15. pub use std::io::prelude::*;
  16. pub use std::process::{Command, Stdio};
  17. let commands = &*format!(
  18. "
  19. cd \"{}\"
  20. {}
  21. exit",
  22. $crate::fs::in_directory($cwd),
  23. $crate::fs::DisplayPath::display_path(&$path)
  24. );
  25. let test_bins = $crate::fs::binaries();
  26. let test_bins = dunce::canonicalize(&test_bins).unwrap_or_else(|e| {
  27. panic!(
  28. "Couldn't canonicalize dummy binaries path {}: {:?}",
  29. test_bins.display(),
  30. e
  31. )
  32. });
  33. let mut paths = $crate::shell_os_paths();
  34. paths.insert(0, test_bins);
  35. let paths_joined = match std::env::join_paths(paths.iter()) {
  36. Ok(all) => all,
  37. Err(_) => panic!("Couldn't join paths for PATH var."),
  38. };
  39. let mut process = match Command::new($crate::fs::executable_path())
  40. .env("PATH", paths_joined)
  41. .arg("--skip-plugins")
  42. .stdout(Stdio::piped())
  43. .stdin(Stdio::piped())
  44. .stderr(Stdio::piped())
  45. .spawn()
  46. {
  47. Ok(child) => child,
  48. Err(why) => panic!("Can't run test {}", why.to_string()),
  49. };
  50. let stdin = process.stdin.as_mut().expect("couldn't open stdin");
  51. stdin
  52. .write_all(commands.as_bytes())
  53. .expect("couldn't write to stdin");
  54. let output = process
  55. .wait_with_output()
  56. .expect("couldn't read from stdout/stderr");
  57. let out = $crate::macros::read_std(&output.stdout);
  58. let err = String::from_utf8_lossy(&output.stderr);
  59. println!("=== stderr\n{}", err);
  60. $crate::macros::Outcome::new(out,err.into_owned())
  61. }};
  62. }
  63. #[macro_export]
  64. macro_rules! nu_with_plugins {
  65. (cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
  66. use $crate::fs::DisplayPath;
  67. let path = format!($path, $(
  68. $part.display_path()
  69. ),*);
  70. nu_with_plugins!($cwd, &path)
  71. }};
  72. (cwd: $cwd:expr, $path:expr) => {{
  73. nu_with_plugins!($cwd, $path)
  74. }};
  75. ($cwd:expr, $path:expr) => {{
  76. pub use std::error::Error;
  77. pub use std::io::prelude::*;
  78. pub use std::process::{Command, Stdio};
  79. let commands = &*format!(
  80. "
  81. cd \"{}\"
  82. {}
  83. exit",
  84. $crate::fs::in_directory($cwd),
  85. $crate::fs::DisplayPath::display_path(&$path)
  86. );
  87. let test_bins = $crate::fs::binaries();
  88. let test_bins = dunce::canonicalize(&test_bins).unwrap_or_else(|e| {
  89. panic!(
  90. "Couldn't canonicalize dummy binaries path {}: {:?}",
  91. test_bins.display(),
  92. e
  93. )
  94. });
  95. let mut paths = $crate::shell_os_paths();
  96. paths.insert(0, test_bins);
  97. let paths_joined = match std::env::join_paths(paths.iter()) {
  98. Ok(all) => all,
  99. Err(_) => panic!("Couldn't join paths for PATH var."),
  100. };
  101. let mut process = match Command::new($crate::fs::executable_path())
  102. .env("PATH", paths_joined)
  103. .stdout(Stdio::piped())
  104. .stdin(Stdio::piped())
  105. .stderr(Stdio::piped())
  106. .spawn()
  107. {
  108. Ok(child) => child,
  109. Err(why) => panic!("Can't run test {}", why.to_string()),
  110. };
  111. let stdin = process.stdin.as_mut().expect("couldn't open stdin");
  112. stdin
  113. .write_all(commands.as_bytes())
  114. .expect("couldn't write to stdin");
  115. let output = process
  116. .wait_with_output()
  117. .expect("couldn't read from stdout/stderr");
  118. let out = $crate::macros::read_std(&output.stdout);
  119. let err = String::from_utf8_lossy(&output.stderr);
  120. println!("=== stderr\n{}", err);
  121. $crate::macros::Outcome::new(out,err.into_owned())
  122. }};
  123. }
  124. pub struct Outcome {
  125. pub out: String,
  126. pub err: String,
  127. }
  128. impl Outcome {
  129. pub fn new(out: String, err: String) -> Outcome {
  130. Outcome { out, err }
  131. }
  132. }
  133. pub fn read_std(std: &[u8]) -> String {
  134. let out = String::from_utf8_lossy(std);
  135. let out = out.lines().skip(1).collect::<Vec<_>>().join("\n");
  136. let out = out.replace("\r\n", "");
  137. out.replace("\n", "")
  138. }