1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial |
3 | |
4 | use std::error::Error; |
5 | use std::{fs::File, io::Write, path::PathBuf}; |
6 | |
7 | #[track_caller ] |
8 | fn check_output(o: std::process::Output) { |
9 | if !o.status.success() { |
10 | eprintln!( |
11 | "STDERR: \n{}\nSTDOUT: \n{}" , |
12 | String::from_utf8_lossy(&o.stderr), |
13 | String::from_utf8_lossy(&o.stdout), |
14 | ); |
15 | //panic!("Build Failed {:?}", o.status); |
16 | } |
17 | } |
18 | |
19 | lazy_static::lazy_static! { |
20 | static ref NODE_API_JS_PATH: PathBuf = { |
21 | let node_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR" )).join("../../../api/node" ); |
22 | |
23 | // On Windows npm is 'npm.cmd', which Rust's process::Command doesn't look for as extension, because |
24 | // it tries to emulate CreateProcess. |
25 | let npm = which::which("npm" ).unwrap(); |
26 | |
27 | // installs the slint node package dependencies |
28 | let o = std::process::Command::new(npm.clone()) |
29 | .arg("install" ) |
30 | .arg("--no-audit" ) |
31 | .arg("--ignore-scripts" ) |
32 | .current_dir(node_dir.clone()) |
33 | .stdout(std::process::Stdio::piped()) |
34 | .stderr(std::process::Stdio::piped()) |
35 | .output() |
36 | .map_err(|err| format!("Could not launch npm install: {}" , err)).unwrap(); |
37 | |
38 | check_output(o); |
39 | |
40 | // builds the slint node package in debug |
41 | let o = std::process::Command::new(npm.clone()) |
42 | .arg("run" ) |
43 | .arg("build:debug" ) |
44 | .current_dir(node_dir.clone()) |
45 | .stdout(std::process::Stdio::piped()) |
46 | .stderr(std::process::Stdio::piped()) |
47 | .output() |
48 | .map_err(|err| format!("Could not launch npm install: {}" , err)).unwrap(); |
49 | |
50 | check_output(o); |
51 | |
52 | node_dir.join("index.js" ) |
53 | }; |
54 | } |
55 | |
56 | pub fn test(testcase: &test_driver_lib::TestCase) -> Result<(), Box<dyn Error>> { |
57 | let slintpath = NODE_API_JS_PATH.clone(); |
58 | |
59 | let dir = tempfile::tempdir()?; |
60 | |
61 | let mut main_js = File::create(dir.path().join("main.js" ))?; |
62 | write!( |
63 | main_js, |
64 | r#" |
65 | const assert = require('assert').strict; |
66 | let slintlib = require(String.raw` {slintpath}`); |
67 | let slint = slintlib.loadFile(String.raw` {path}`); |
68 | "# , |
69 | slintpath = slintpath.to_string_lossy(), |
70 | path = testcase.absolute_path.to_string_lossy() |
71 | )?; |
72 | let source = std::fs::read_to_string(&testcase.absolute_path)?; |
73 | let include_paths = test_driver_lib::extract_include_paths(&source); |
74 | let library_paths = test_driver_lib::extract_library_paths(&source) |
75 | .map(|(k, v)| { |
76 | let mut abs_path = testcase.absolute_path.clone(); |
77 | abs_path.pop(); |
78 | abs_path.push(v); |
79 | format!(" {}= {}" , k, abs_path.to_string_lossy()) |
80 | }) |
81 | .collect::<Vec<_>>(); |
82 | for x in test_driver_lib::extract_test_functions(&source).filter(|x| x.language_id == "js" ) { |
83 | write!(main_js, " {{\n {}\n}}\n" , x.source.replace(" \n" , " \n " ))?; |
84 | } |
85 | |
86 | let output = std::process::Command::new("node" ) |
87 | .arg(dir.path().join("main.js" )) |
88 | .current_dir(dir.path()) |
89 | .env("SLINT_INCLUDE_PATH" , std::env::join_paths(include_paths).unwrap()) |
90 | .env("SLINT_LIBRARY_PATH" , std::env::join_paths(library_paths).unwrap()) |
91 | .env("SLINT_SCALE_FACTOR" , "1" ) // We don't have a testing backend, but we can try to force a SF1 as the tests expect. |
92 | .env("SLINT_ENABLE_EXPERIMENTAL_FEATURES" , "1" ) |
93 | .stdout(std::process::Stdio::piped()) |
94 | .stderr(std::process::Stdio::piped()) |
95 | .output() |
96 | .map_err(|err| format!("Could not launch npm start: {}" , err))?; |
97 | |
98 | if !output.status.success() { |
99 | print!(" {}" , String::from_utf8_lossy(output.stdout.as_ref())); |
100 | print!(" {}" , String::from_utf8_lossy(output.stderr.as_ref())); |
101 | return Err(String::from_utf8_lossy(output.stderr.as_ref()).to_owned().into()); |
102 | } |
103 | |
104 | Ok(()) |
105 | } |
106 | |