use cure_engine::Config;
use cure_java_parser::parse;
use cure_java_print::print_unit;
use cure_java_simplify::simplify_unit;
fn process(src: &str) -> (String, usize) {
let mut out = parse(src);
let report = simplify_unit(&mut out.ast, &mut out.unit, &Config::default());
(print_unit(&out.ast, &out.unit), report.edits)
}
#[test]
fn doc_example_through_real_source() {
let src = r#"
class A {
int m() {
int a = foo();
int b = a;
return b;
}
}
"#;
let (printed, edits) = process(src);
assert!(edits > 0);
assert!(printed.contains("return foo();"), "{printed}");
assert!(!printed.contains("int b = a;"), "{printed}");
}
#[test]
fn broken_method_skipped_good_method_optimized() {
let src = r#"
class A {
void broken() {
int x = ;
foo(= dead);
}
int good() {
int a = foo();
int b = a;
return b;
}
}
"#;
let (printed, _edits) = process(src);
assert!(printed.contains("int x = ;"), "{printed}");
assert!(printed.contains("foo(= dead);"), "{printed}");
assert!(printed.contains("return foo();"), "{printed}");
assert!(!printed.contains("int b = a;"), "{printed}");
}
#[test]
fn broken_statement_skipped_rest_optimized() {
let src = r#"
class A {
int m(boolean flag) {
int a = 1;
bar(= broken);
if (flag) {
return true;
} else {
return false;
}
}
}
"#;
let (printed, _edits) = process(src);
assert!(printed.contains("bar(= broken);"), "{printed}");
assert!(printed.contains("return flag;"), "{printed}");
}
#[test]
fn decompiler_artifacts_cleaned() {
let src = r#"
class Order {
private static final int MAX = 100;
boolean check(int value) {
boolean b = value > 10;
if (b) {
return true;
} else {
return false;
}
}
String describe(int x) {
if (x == 0) {
return "zero";
}
int t = x * 1;
int u = t;
int self = 5;
self = self;
return "value=" + u;
}
}
"#;
let (printed, edits) = process(src);
assert!(edits >= 4, "expect multiple edits, got {edits}");
assert!(printed.contains("return value > 10;"), "{printed}");
assert!(
printed.contains("return \"value=\" + x;")
|| printed.contains(": \"value=\" + x;"),
"{printed}"
);
assert!(!printed.contains("self = self;"), "{printed}");
}
#[test]
fn idiomatic_code_left_alone() {
let src = r#"
class Ok {
int sum(int[] xs) {
int total = 0;
for (int x : xs) {
total += x;
}
return total;
}
}
"#;
let (printed, edits) = process(src);
assert_eq!(edits, 0, "should not touch idiomatic code: {printed}");
assert!(printed.contains("total += x;"), "{printed}");
}
#[test]
fn formatting_only_still_valid() {
let src = "class A{void m(int x){if(x>0){System.out.println(\"hi\");}}}";
let (printed, _) = process(src);
assert!(printed.contains("if (x > 0) {"), "{printed}");
assert!(printed.contains(" System.out.println(\"hi\");"), "{printed}");
}