use super::common::{PackageError, run_install_loop};
use super::config::GemConfig;
pub struct GemHandler {
config: GemConfig,
}
impl GemHandler {
pub fn new(config: GemConfig) -> Self {
Self { config }
}
pub fn install(&self) -> Result<(), PackageError> {
run_install_loop(
"gem",
"gem",
"[gem]",
"No gem packages configured",
&self.config.packages,
|name, spec| Ok(build_install_args(name, spec.version())),
)
}
}
pub(crate) fn build_install_args(name: &str, version: &str) -> Vec<String> {
let mut args: Vec<String> = Vec::with_capacity(5);
args.push("install".into());
args.push("--no-document".into());
args.push(name.into());
if version != "latest" {
args.push("-v".into());
args.push(version.into());
}
args
}
#[cfg(test)]
mod tests {
use super::super::config::PackageSpec;
use super::*;
use std::collections::HashMap;
#[test]
fn gem_handler_empty() {
let config = GemConfig::default();
let handler = GemHandler::new(config);
assert!(handler.config.packages.is_empty());
}
#[test]
fn gem_handler_holds_packages() {
let mut packages = HashMap::new();
packages.insert(
"rubocop".to_string(),
PackageSpec::Version("latest".to_string()),
);
packages.insert(
"bundler".to_string(),
PackageSpec::Version("2.5.0".to_string()),
);
let config = GemConfig { packages };
let handler = GemHandler::new(config);
assert_eq!(handler.config.packages.len(), 2);
}
#[test]
fn build_install_args_table() {
let cases = [
(
"rubocop",
"latest",
vec!["install", "--no-document", "rubocop"],
),
(
"bundler",
"2.5.0",
vec!["install", "--no-document", "bundler", "-v", "2.5.0"],
),
];
for (name, version, expected) in cases {
let actual = build_install_args(name, version);
let actual_refs: Vec<&str> = actual.iter().map(String::as_str).collect();
assert_eq!(
actual_refs, expected,
"argv mismatch for {} = {}",
name, version
);
assert_eq!(actual[0], "install");
assert_eq!(actual[1], "--no-document");
}
}
#[test]
fn gem_rejects_flag_like_names() {
use super::super::common::validate_package_name;
let err =
validate_package_name("--source", "[gem]").expect_err("flag-like name must be refused");
assert!(matches!(err, PackageError::RefusedUnsafeSpec(_, _)));
}
}