mod common;
use common::sqry_bin;
use assert_cmd::Command;
use predicates::prelude::*;
use tempfile::TempDir;
#[test]
fn cli_scala_exports_classes_and_objects() {
let project = TempDir::new().unwrap();
let scala_code = r"
package com.example
class User(val name: String, val age: Int) {
def getName: String = name
}
object UserService {
def createUser(name: String): User = new User(name, 0)
}
trait Repository {
def save(item: String): Unit
}
";
std::fs::write(project.path().join("User.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("exports:User")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("User.scala"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:UserService")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("User.scala"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:Repository")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("User.scala"));
}
#[test]
fn cli_scala_exports_hide_private_members() {
let project = TempDir::new().unwrap();
let scala_code = r"
package com.example
class PublicClass {
def publicMethod(): Unit = {}
private def privateMethod(): Unit = {}
}
private class PrivateClass {
def someMethod(): Unit = {}
}
object PublicObject {
def publicFunction(): Unit = {}
}
private object PrivateObject {
def hiddenFunction(): Unit = {}
}
";
std::fs::write(project.path().join("Visibility.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("exports:PublicClass")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("PublicClass"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:PublicObject")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("PublicObject"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:PrivateClass")
.arg(project.path())
.assert()
.success()
.stderr(predicate::str::contains("No matches found"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:PrivateObject")
.arg(project.path())
.assert()
.success()
.stderr(predicate::str::contains("No matches found"));
}
#[test]
fn cli_scala_imports() {
let project = TempDir::new().unwrap();
let scala_code = r"
import scala.collection.mutable
import scala.collection.mutable.{Buffer, ListBuffer}
import java.util.{List => JavaList}
object DataProcessor {
def process(data: List[String]): Unit = {
println(data)
}
}
";
std::fs::write(project.path().join("Processor.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("imports:mutable")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("Processor.scala"));
Command::new(sqry_bin())
.arg("query")
.arg("imports:Buffer")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("Processor.scala"));
}
#[test]
fn cli_scala_callers_function_calls() {
let project = TempDir::new().unwrap();
let scala_code = r#"
object Calculator {
def validate(x: Int): Boolean = x > 0
def process(value: Int): Int = {
if (validate(value)) {
value * 2
} else {
0
}
}
def analyze(num: Int): String = {
if (validate(num)) {
"valid"
} else {
"invalid"
}
}
}
"#;
std::fs::write(project.path().join("Calculator.scala"), scala_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_scala_callers_method_calls() {
let project = TempDir::new().unwrap();
let scala_code = r"
class DataService {
private def fetchData(): List[Int] = List(1, 2, 3)
private def transformData(data: List[Int]): List[Int] = {
data.map(_ * 2)
}
def process(): List[Int] = {
val data = fetchData()
transformData(data)
}
}
";
std::fs::write(project.path().join("Service.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:fetchData")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("process"));
Command::new(sqry_bin())
.arg("query")
.arg("callers:transformData")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("process"));
}
#[test]
fn cli_scala_callees_function() {
let project = TempDir::new().unwrap();
let scala_code = r#"
object Logger {
def log(message: String): Unit = println(s"LOG: $message")
def warn(message: String): Unit = println(s"WARN: $message")
def handleError(error: String): Unit = {
log("Error occurred")
warn(error)
}
}
"#;
std::fs::write(project.path().join("Logger.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callees:handleError")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("log"))
.stdout(predicate::str::contains("warn"));
}
#[test]
fn cli_scala_case_classes() {
let project = TempDir::new().unwrap();
let scala_code = r#"
sealed trait Result
case class Success(value: String) extends Result
case class Failure(error: String) extends Result
object ResultHandler {
def process(result: Result): String = result match {
case Success(v) => s"Got: $v"
case Failure(e) => s"Error: $e"
}
}
"#;
std::fs::write(project.path().join("Result.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("exports:Success")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("Result.scala"));
Command::new(sqry_bin())
.arg("query")
.arg("exports:Failure")
.arg(project.path())
.assert()
.success()
.stdout(predicate::str::contains("Result.scala"));
}
#[test]
fn cli_scala_callers_no_results() {
let project = TempDir::new().unwrap();
let scala_code = r"
object Unused {
def unusedFunction(): Int = 42
}
";
std::fs::write(project.path().join("Unused.scala"), scala_code).unwrap();
Command::new(sqry_bin())
.arg("index")
.arg(project.path())
.assert()
.success();
Command::new(sqry_bin())
.arg("query")
.arg("callers:unusedFunction")
.arg(project.path())
.assert()
.success();
}