extern crate rustfmt_nightly;
extern crate difference;
extern crate regex;
use difference::Changeset;
use rustfmt_nightly as rustfmt;
use std::fs;
use std::io::Read;
#[test]
fn check_expansions() {
let test_data = fs::read_dir( "tests/data" ).unwrap();
let source_paths = test_data
.into_iter()
.map( |e| e.expect("Failed to read entry").path() )
.map( |p| p.to_str().unwrap().to_owned() )
.filter( |p| p.ends_with( ".source.rs" ) )
.collect::<Vec<_>>();
let mut failed = 0;
for source_path in source_paths {
let mut target_file = fs::File::open( source_path.replace(
".source.rs",
".target.rs" ) ).unwrap();
let mut source_code = build( &source_path );
let mut target_code = String::new();
target_file.read_to_string( &mut target_code )
.expect( "Failed to read target" );
target_code = target_code.replace( "\r", "" );
source_code = source_code.replace( "\r", "" );
let changeset = Changeset::new(
&format( source_code.trim() ),
&format( target_code.trim() ),
"\n" );
if changeset.diffs.len() > 1 {
println!( "{}", changeset );
failed += 1;
}
}
assert_eq!( failed, 0, "{} tests failed", failed );
}
fn build( path : &str ) -> String {
let output = std::process::Command::new( "rustc" )
.args( &[
"--crate-name", "source",
"--crate-type", "lib",
path,
"--out-dir", "tests/out",
"-L", "dependency=../target/debug/deps",
"--extern", "intercom=../target/debug/libintercom.rlib",
"--pretty=expanded",
"-Z", "unstable-options",
] )
.output()
.expect( "Failed to execute" );
if ! output.status.success() {
println!( "FAILED TO COMPILE SOURCE {}", path );
panic!( format!(
"{}\n\n{}",
String::from_utf8( output.stdout ).unwrap(),
String::from_utf8( output.stderr ).unwrap()
) );
}
String::from_utf8( output.stdout ).expect( "Bad output" )
}
fn strip_comments( code : &str ) -> String {
let re = regex::Regex::new( r"//.*" ).expect( "Bad regex" );
re.replace_all( code, "" ).into_owned()
}
fn strip_empty_lines( code : &str ) -> String {
let re = regex::Regex::new( r"^\s+$" ).expect( "Bad regex" );
re.replace_all( code, "" ).into_owned().replace( "\n\n", "" )
}
fn format( code : &str ) -> String {
let code = strip_comments( code );
let code = strip_empty_lines( &code );
let mut config = rustfmt::config::Config::default();
config.override_value( "write_mode", "Display" );
let mut out : Vec<u8> = vec![];
rustfmt::format_input(
rustfmt::Input::Text( code ),
&config,
Some( &mut out ) ).expect( "Failed to format" );
String::from_utf8( out ).expect( "Bad output" )
}