mod common;
use common::sqry_bin;
use assert_cmd::Command;
use predicates::prelude::*;
use tempfile::TempDir;
#[test]
fn cli_r_imports() {
let project = TempDir::new().unwrap();
let r_code = r"
library(dplyr)
library(ggplot2)
require(tidyr)
process_data <- function(df) {
df %>%
filter(value > 0) %>%
select(id, value)
}
";
std::fs::write(project.path().join("analysis.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("imports:dplyr")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("analysis.R"));
Command::new(sqry_bin())
.arg("query")
.arg("imports:tidyr")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("analysis.R"));
}
#[test]
fn cli_r_callers_function_calls() {
let project = TempDir::new().unwrap();
let r_code = r"
validate <- function(x) {
!is.null(x) && length(x) > 0
}
process <- function(data) {
if (validate(data)) {
return(mean(data))
}
return(NULL)
}
analyze <- function(values) {
if (validate(values)) {
return(sum(values))
}
return(0)
}
";
std::fs::write(project.path().join("functions.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:validate")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("process"))
.stdout(predicate::str::contains("analyze"));
}
#[test]
fn cli_r_callers_with_namespace() {
let project = TempDir::new().unwrap();
let r_code = r"
calculate <- function(x) {
dplyr::mutate(x, new_col = value * 2)
}
transform <- function(df) {
dplyr::filter(df, value > 0)
}
";
std::fs::write(project.path().join("transform.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:mutate")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("calculate"));
Command::new(sqry_bin())
.arg("query")
.arg("callers:filter")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("transform"));
}
#[test]
fn cli_r_callees_function() {
let project = TempDir::new().unwrap();
let r_code = r#"
log_message <- function(msg) {
print(paste("LOG:", msg))
}
warn_message <- function(msg) {
warning(paste("WARN:", msg))
}
handle_error <- function(error) {
log_message("Error occurred")
warn_message(error$message)
}
"#;
std::fs::write(project.path().join("logger.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callees:handle_error")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("log_message"))
.stdout(predicate::str::contains("warn_message"));
}
#[test]
fn cli_r_method_calls() {
let project = TempDir::new().unwrap();
let r_code = r#"
User <- R6::R6Class("User",
public = list(
name = NULL,
get_name = function() {
self$name
},
validate = function() {
!is.null(self$name)
}
)
)
process_user <- function(user) {
if (user$validate()) {
return(user$get_name())
}
return(NULL)
}
"#;
std::fs::write(project.path().join("user.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:validate")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("process_user"));
Command::new(sqry_bin())
.arg("query")
.arg("callers:get_name")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("process_user"));
}
#[test]
fn cli_r_callers_no_results() {
let project = TempDir::new().unwrap();
let r_code = r#"
unused_function <- function() {
return(42)
}
print("Hello")
"#;
std::fs::write(project.path().join("unused.R"), r_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:unused_function")
.arg(project.path())
.assert()
.success();
}