use std::collections::HashMap;
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use react_auditor::scanner::Scanner;
fn generate_source(stmt_count: usize) -> String {
let mut source = String::from("import React from 'react';\n\n");
source.push_str("const App: React.FC = () => {\n");
source.push_str(" const [count, setCount] = React.useState(0);\n");
source.push_str(" const [items, setItems] = React.useState<string[]>([]);\n\n");
for i in 0..stmt_count {
source.push_str(&format!(
" const item_{i} = {{ id: {i}, name: 'test_{i}', value: {i} * 2 }};\n"
));
}
source.push_str("\n return (\n <div>\n");
source.push_str(" <h1>Hello</h1>\n");
source.push_str(" <ul>\n");
for i in 0..(stmt_count / 10).max(1) {
source.push_str(&format!(" <li key={i}>{{item_{i}.name}}</li>\n"));
}
source.push_str(" </ul>\n");
source.push_str(" </div>\n");
source.push_str(" );\n};\n\nexport default App;\n");
source
}
fn bench_scan_1k_loc(c: &mut Criterion) {
let source = generate_source(200); let dir = std::env::temp_dir().join("_bench_scan");
let _ = std::fs::create_dir_all(&dir);
let path = dir.join("bench_1k.tsx");
std::fs::write(&path, &source).unwrap();
c.bench_function("scan_1k_loc", |b| {
b.iter(|| {
let scanner = Scanner::new(
black_box(vec![path.to_string_lossy().to_string()]),
black_box(HashMap::new()),
black_box(None),
black_box(Vec::new()),
);
let _ = scanner.scan();
})
});
let _ = std::fs::remove_file(&path);
}
fn bench_scan_10k_loc(c: &mut Criterion) {
let source = generate_source(2000); let dir = std::env::temp_dir().join("_bench_scan");
let _ = std::fs::create_dir_all(&dir);
let path = dir.join("bench_10k.tsx");
std::fs::write(&path, &source).unwrap();
c.bench_function("scan_10k_loc", |b| {
b.iter(|| {
let scanner = Scanner::new(
black_box(vec![path.to_string_lossy().to_string()]),
black_box(HashMap::new()),
black_box(None),
black_box(Vec::new()),
);
let _ = scanner.scan();
})
});
let _ = std::fs::remove_file(&path);
}
fn bench_scan_clean_file(c: &mut Criterion) {
let source = r#"
import React from 'react';
interface Props {
name: string;
}
const Greeting: React.FC<Props> = ({ name }) => {
return <div>Hello, {name}!</div>;
};
export default Greeting;
"#;
let dir = std::env::temp_dir().join("_bench_scan");
let _ = std::fs::create_dir_all(&dir);
let path = dir.join("bench_clean.tsx");
std::fs::write(&path, source).unwrap();
c.bench_function("scan_clean_file", |b| {
b.iter(|| {
let scanner = Scanner::new(
black_box(vec![path.to_string_lossy().to_string()]),
black_box(HashMap::new()),
black_box(None),
black_box(Vec::new()),
);
let _ = scanner.scan();
})
});
let _ = std::fs::remove_file(&path);
}
criterion_group!(
benches,
bench_scan_1k_loc,
bench_scan_10k_loc,
bench_scan_clean_file
);
criterion_main!(benches);