use super::*;
mod tests {
use super::*;
#[tokio::test]
async fn test_language_analyzer_basic() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supported_languages().len() >= 50);
}
#[tokio::test]
async fn test_analysis_support() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Complexity));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::Satd));
assert!(!analyzer.supports_analysis(Language::JSON, &AnalysisType::Complexity));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Documentation));
}
#[test]
fn test_comment_detection() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.is_comment_line("// This is a comment", Language::Rust));
assert!(analyzer.is_comment_line("# This is a comment", Language::Python));
assert!(analyzer.is_comment_line("/* Comment */", Language::Java));
assert!(!analyzer.is_comment_line("let x = 5;", Language::Rust));
}
}
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}
mod coverage_tests {
use super::*;
use std::io::Write;
use std::path::Path;
use tempfile::NamedTempFile;
fn create_temp_file(content: &str, extension: &str) -> NamedTempFile {
let mut file = tempfile::Builder::new()
.suffix(extension)
.tempfile()
.unwrap();
file.write_all(content.as_bytes()).unwrap();
file.flush().unwrap();
file
}
fn sample_rust_code() -> &'static str {
r#"// This is a Rust file
use std::io;
/// A simple function
fn main() {
// TODO: Add more features
if true {
println!("Hello");
} else {
println!("World");
}
for i in 0..10 {
match i {
0 => println!("zero"),
_ => println!("{}", i),
}
}
}
fn helper() {
while true {
break;
}
}
"#
}
fn sample_python_code() -> &'static str {
r#"# This is a Python file
import os
from typing import List
def main():
# FIXME: This needs work
if True:
print("Hello")
elif False:
print("World")
else:
print("!")
for i in range(10):
try:
print(i)
except Exception:
pass
def helper():
while True:
break
"#
}
fn sample_javascript_code() -> &'static str {
r#"// This is a JavaScript file
import { something } from 'module';
const axios = require('axios');
function main() {
// HACK: temporary fix
if (true) {
console.log("Hello");
} else {
console.log("World");
}
for (let i = 0; i < 10; i++) {
switch (i) {
case 0:
console.log("zero");
break;
default:
console.log(i);
}
}
try {
doSomething();
} catch (e) {
console.error(e);
}
}
const arrow = () => console.log("arrow");
"#
}
fn sample_typescript_code() -> &'static str {
r#"// TypeScript file
import { Component } from '@angular/core';
interface User {
name: string;
age: number;
}
function processUser(user: User): void {
// XXX: review this
if (user.age > 18) {
console.log("Adult");
} else {
console.log("Minor");
}
}
const arrowFn = (x: number): number => x * 2;
"#
}
fn sample_java_code() -> &'static str {
r#"// Java file
import java.util.List;
public class Main {
// BUG: Memory leak here
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("Has args");
} else {
System.out.println("No args");
}
for (int i = 0; i < 10; i++) {
switch (i) {
case 0:
System.out.println("zero");
break;
default:
System.out.println(i);
}
}
try {
doSomething();
} catch (Exception e) {
e.printStackTrace();
}
}
private void helper() {
while (true) {
break;
}
}
}
"#
}
fn sample_go_code() -> &'static str {
r#"// Go file
package main
import "fmt"
func main() {
// KLUDGE: hack for now
if true {
fmt.Println("Hello")
} else {
fmt.Println("World")
}
for i := 0; i < 10; i++ {
switch i {
case 0:
fmt.Println("zero")
default:
fmt.Println(i)
}
}
}
func helper() {
for {
break
}
}
"#
}
fn sample_kotlin_code() -> &'static str {
r#"// Kotlin file
import kotlin.collections.List
fun main() {
// TODO: refactor
if (true) {
println("Hello")
} else {
println("World")
}
for (i in 0..10) {
when (i) {
0 -> println("zero")
else -> println(i)
}
}
try {
doSomething()
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun helper() {
while (true) {
break
}
}
"#
}
fn sample_sql_code() -> &'static str {
r#"-- SQL file
-- This is a comment
SELECT * FROM users WHERE id = 1;
UPDATE users SET name = 'test' WHERE id = 1;
DELETE FROM users WHERE id = 1;
DROP TABLE IF EXISTS temp;
"#
}
fn sample_python_with_docs() -> &'static str {
r#"# Module docstring
# This module does things
def function_one():
# Comment line
# Another comment
pass
def function_two():
# Inline comment
x = 5 # trailing comment
return x
# More comments
# Even more comments
# And more
def function_three():
pass
"#
}
#[test]
fn test_language_analyzer_new() {
let analyzer = LanguageAnalyzer::new();
assert!(!analyzer.supported_languages().is_empty());
}
#[test]
fn test_language_analyzer_default() {
let analyzer = LanguageAnalyzer::default();
assert!(!analyzer.supported_languages().is_empty());
}
#[test]
fn test_supported_languages_count() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supported_languages().len() >= 50);
}
#[test]
fn test_supports_analysis_complexity() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Complexity));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::Complexity));
assert!(analyzer.supports_analysis(Language::Java, &AnalysisType::Complexity));
assert!(analyzer.supports_analysis(Language::TypeScript, &AnalysisType::Complexity));
assert!(!analyzer.supports_analysis(Language::JSON, &AnalysisType::Complexity));
assert!(!analyzer.supports_analysis(Language::YAML, &AnalysisType::Complexity));
}
#[test]
fn test_supports_analysis_satd() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Satd));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::Satd));
assert!(analyzer.supports_analysis(Language::JSON, &AnalysisType::Satd));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Satd));
}
#[test]
fn test_supports_analysis_dead_code() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::DeadCode));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::DeadCode));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::DeadCode));
}
#[test]
fn test_supports_analysis_security() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::JavaScript, &AnalysisType::Security));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::Security));
}
#[test]
fn test_supports_analysis_style() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Style));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Style));
}
#[test]
fn test_supports_analysis_documentation() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Documentation));
assert!(analyzer.supports_analysis(Language::LaTeX, &AnalysisType::Documentation));
assert!(analyzer.supports_analysis(Language::AsciiDoc, &AnalysisType::Documentation));
assert!(analyzer.supports_analysis(Language::Unknown, &AnalysisType::Documentation));
assert!(!analyzer.supports_analysis(Language::Rust, &AnalysisType::Documentation));
}
#[test]
fn test_supports_analysis_dependencies() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Dependencies));
assert!(analyzer.supports_analysis(Language::Python, &AnalysisType::Dependencies));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Dependencies));
}
#[test]
fn test_supports_analysis_metrics() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.supports_analysis(Language::Rust, &AnalysisType::Metrics));
assert!(analyzer.supports_analysis(Language::JSON, &AnalysisType::Metrics));
assert!(analyzer.supports_analysis(Language::Markdown, &AnalysisType::Metrics));
}
#[test]
fn test_is_comment_line_c_style() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.is_comment_line("// comment", Language::Rust));
assert!(analyzer.is_comment_line("// comment", Language::C));
assert!(analyzer.is_comment_line("// comment", Language::Cpp));
assert!(analyzer.is_comment_line("// comment", Language::Go));
assert!(analyzer.is_comment_line("// comment", Language::Java));
assert!(analyzer.is_comment_line("// comment", Language::JavaScript));
assert!(analyzer.is_comment_line("// comment", Language::TypeScript));
assert!(analyzer.is_comment_line("// comment", Language::CSharp));
assert!(analyzer.is_comment_line("// comment", Language::Swift));
assert!(analyzer.is_comment_line("// comment", Language::Kotlin));
assert!(analyzer.is_comment_line("// comment", Language::Scala));
assert!(analyzer.is_comment_line("/* comment */", Language::Java));
assert!(analyzer.is_comment_line("/* comment", Language::C));
assert!(analyzer.is_comment_line("* continuation", Language::Java));
}
#[test]
fn test_is_comment_line_hash() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.is_comment_line("# comment", Language::Python));
assert!(analyzer.is_comment_line("# comment", Language::Ruby));
assert!(analyzer.is_comment_line("# comment", Language::Bash));
assert!(analyzer.is_comment_line("# comment", Language::Zsh));
assert!(analyzer.is_comment_line("# comment", Language::Fish));
assert!(analyzer.is_comment_line("# comment", Language::Perl));
assert!(analyzer.is_comment_line("# comment", Language::R));
assert!(analyzer.is_comment_line("# comment", Language::YAML));
assert!(analyzer.is_comment_line("# comment", Language::TOML));
assert!(analyzer.is_comment_line("# comment", Language::Makefile));
}
#[test]
fn test_is_comment_line_semicolon() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.is_comment_line("; comment", Language::Clojure));
}
#[test]
fn test_is_comment_line_percent() {
let analyzer = LanguageAnalyzer::new();
assert!(analyzer.is_comment_line("% comment", Language::Erlang));
assert!(analyzer.is_comment_line("% comment", Language::Matlab));
}
#[test]
fn test_is_comment_line_double_dash() {
let analyzer = LanguageAnalyzer::new();