-
Notifications
You must be signed in to change notification settings - Fork 80
/
cmd_test.rs
150 lines (121 loc) · 4.27 KB
/
cmd_test.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
use std::process::{Command, exit};
use std::iter;
use std::env;
use std::fs;
use std::ffi::OsStr;
use clap;
use cargo_shim::{
Profile,
CargoResult,
TargetKind
};
use build::{BuildArgs, Backend};
use error::Error;
use utils::{
CommandExt,
find_cmd,
read,
write
};
use test_chromium::test_in_chromium;
use project_dirs::PROJECT_DIRS;
pub const TEST_RUNNER: &'static str = include_str!( "test_runner.js" );
fn test_in_nodejs(
backend: Backend,
build: CargoResult,
arg_passthrough: &Vec< &OsStr >,
any_failure: &mut bool
) -> Result< (), Error > {
let possible_commands =
if cfg!( windows ) {
&[ "node.exe" ][..]
} else {
&[ "nodejs", "node" ][..]
};
let nodejs_name = find_cmd( possible_commands ).ok_or_else( || {
Error::EnvironmentError( "node.js not found; please install it!".into() )
})?;
let cache_path = PROJECT_DIRS.cache_dir().join( "bin" );
fs::create_dir_all( &cache_path ).unwrap();
let runner_path = cache_path.join( "test_runner.js" );
if !runner_path.exists() || read( &runner_path ).expect( "cannot read test runner" ) != TEST_RUNNER {
write( &runner_path, &TEST_RUNNER ).expect( "cannot write test runner" );
}
let js_files: Vec< _ > =
build.artifacts()
.iter()
.filter( |artifact| artifact.extension().map( |ext| ext == "js" ).unwrap_or( false ) )
.collect();
if js_files.is_empty() {
panic!( "internal error: no .js file found" );
}
let artifact = if let Some( artifact ) = js_files.iter().find( |artifact| !artifact.iter().any( |chunk| chunk == "deps" ) ) {
artifact
} else {
js_files[ 0 ]
};
let test_args = iter::once( runner_path.as_os_str() )
.chain( iter::once( OsStr::new( backend.triplet() ) ) )
.chain( iter::once( artifact.as_os_str() ) )
.chain( arg_passthrough.iter().cloned() );
let previous_cwd = env::current_dir().unwrap();
if backend.is_emscripten_wasm() {
// On the Emscripten target the `.wasm` file is in a different directory.
let wasm_artifact = build.artifacts().iter()
.find( |artifact| artifact.extension().map( |ext| ext == "wasm" ).unwrap_or( false ) )
.expect( "internal error: no .wasm file found" );
env::set_current_dir( wasm_artifact.parent().unwrap() ).unwrap();
} else {
env::set_current_dir( artifact.parent().unwrap() ).unwrap();
}
let mut command = Command::new( nodejs_name );
command.args( test_args );
debug!( "Launching: {:?}", command );
let status = command.run();
*any_failure = *any_failure || !status.is_ok();
debug!( "Status: {:?}", status );
env::set_current_dir( previous_cwd ).unwrap();
Ok(())
}
pub fn command_test< 'a >( matches: &clap::ArgMatches< 'a > ) -> Result< (), Error > {
let build_args = BuildArgs::new( matches )?;
let project = build_args.load_project()?;
let use_nodejs = matches.is_present( "nodejs" );
let no_run = matches.is_present( "no-run" );
let arg_passthrough = matches.values_of_os( "passthrough" )
.map_or( vec![], |args| args.collect() );
let targets = project.target_or_select( |target| {
target.kind == TargetKind::Lib ||
target.kind == TargetKind::CDyLib ||
target.kind == TargetKind::Bin ||
target.kind == TargetKind::Test
})?;
let config = project.aggregate_configuration( Profile::Test )?;
let mut builds = Vec::new();
for target in targets {
builds.push( project.build( &config, target )? );
}
if no_run {
exit( 0 );
}
let mut any_failure = false;
if use_nodejs {
for build in builds {
test_in_nodejs( project.backend(), build, &arg_passthrough, &mut any_failure )?;
}
} else {
for build in builds {
test_in_chromium( project.backend(), build, &arg_passthrough, &mut any_failure )?;
}
}
if any_failure {
exit( 101 );
} else {
if project.backend().is_native_wasm() {
eprintln!( "All tests passed!" );
// At least **I hope** that's the case; there are no prints
// when running those tests, so who knows what happens. *shrug*
}
}
Ok(())
}