Skip to content

Commit 94c1f3a

Browse files
committed
Use examples to hack for integration tests.
1 parent a4f622a commit 94c1f3a

File tree

16 files changed

+121
-20
lines changed

16 files changed

+121
-20
lines changed

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ members = [
1414
"examples/logging",
1515
"tests/integration",
1616
]
17+
18+
[profile.dev]
19+
lto = true
20+
21+
[profile.release]
22+
lto = true

examples/hello/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ license = "MulanPSL-2.0"
1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111

1212
[lib]
13+
crate-type = ["lib", "cdylib"]
14+
15+
# This example is hack to used for integration tests.
16+
[[example]]
17+
name = "hello_reexport"
18+
path = "src/_reexport.rs"
1319
crate-type = ["cdylib"]
1420

1521
[dependencies]

examples/hello/src/_reexport.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2019 jmjoy
2+
// PHPER is licensed under Mulan PSL v2.
3+
// You can use this software according to the terms and conditions of the Mulan
4+
// PSL v2. You may obtain a copy of Mulan PSL v2 at:
5+
// http://license.coscl.org.cn/MulanPSL2
6+
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
7+
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8+
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9+
// See the Mulan PSL v2 for more details.
10+
11+
pub use hello::*;

phper-test/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ Integration test tool for [phper](https://crates.io/crates/phper).
44

55
The `php-config` is needed. You can set environment `PHP_CONFIG` to specify the path.
66

7+
## Notice
8+
9+
Because the `phper-test` depends on the `cdylib` to do integration test, but now `cargo test` don't build `cdylib` in `[lib]`, so you must call `cargo build` before `cargo test`.
10+
11+
Maybe, when the feature [artifact-dependencies](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies) becomes stable, or the [issue](https://github.com/rust-lang/cargo/issues/8628) be solved, you don't have to call `cargo build` in advance, but I think it will be a long long stage.
12+
713
## License
814

915
[MulanPSL-2.0](https://github.com/jmjoy/phper/blob/master/LICENSE).

phper-test/src/cli.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ pub fn test_php_scripts(exe_path: impl AsRef<Path>, scripts: &[&dyn AsRef<Path>]
3737
test_php_scripts_with_condition(exe_path, &*scripts);
3838
}
3939

40+
/// Check your extension by executing the php script, if the all executing
41+
/// return success, than the test is pass.
42+
///
43+
/// - `exec_path` is the path of the make executable, which will be used to
44+
/// detect the path of
45+
/// extension lib.
46+
///
47+
/// - `scripts` is the path of your php test scripts.
48+
///
49+
/// See [example hello integration test](https://github.com/jmjoy/phper/blob/master/examples/hello/tests/integration.rs).
50+
pub fn test_php_scripts_with_lib(lib_path: impl AsRef<Path>, scripts: &[&dyn AsRef<Path>]) {
51+
let condition = |output: Output| output.status.success();
52+
let scripts = scripts
53+
.iter()
54+
.map(|s| (*s, &condition as _))
55+
.collect::<Vec<_>>();
56+
test_php_scripts_with_condition_and_lib(lib_path, &*scripts);
57+
}
58+
4059
/// Script and condition pair.
4160
pub type ScriptCondition<'a> = (&'a dyn AsRef<Path>, &'a dyn Fn(Output) -> bool);
4261

@@ -54,8 +73,14 @@ pub type ScriptCondition<'a> = (&'a dyn AsRef<Path>, &'a dyn Fn(Output) -> bool)
5473
pub fn test_php_scripts_with_condition(
5574
exe_path: impl AsRef<Path>, scripts: &[ScriptCondition<'_>],
5675
) {
57-
let context = Context::get_global();
5876
let lib_path = utils::get_lib_path(exe_path);
77+
test_php_scripts_with_condition_and_lib(lib_path, scripts)
78+
}
79+
80+
pub fn test_php_scripts_with_condition_and_lib(
81+
lib_path: impl AsRef<Path>, scripts: &[ScriptCondition<'_>],
82+
) {
83+
let context = Context::get_global();
5984
let tmp_php_ini_file = context.create_tmp_php_ini_file(&lib_path);
6085

6186
for (script, condition) in scripts {

phper-test/src/fpm.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tokio::{io, net::TcpStream, runtime::Handle, task::block_in_place};
2727
static FPM_HANDLE: OnceCell<Mutex<FpmHandle>> = OnceCell::new();
2828

2929
struct FpmHandle {
30-
exe_path: PathBuf,
30+
lib_path: PathBuf,
3131
fpm_child: Child,
3232
php_ini_file: ManuallyDrop<NamedTempFile>,
3333
fpm_conf_file: ManuallyDrop<NamedTempFile>,
@@ -36,6 +36,13 @@ struct FpmHandle {
3636
/// Start php-fpm process and tokio runtime.
3737
pub fn setup(exe_path: impl AsRef<Path>) {
3838
let exe_path = exe_path.as_ref();
39+
let lib_path = utils::get_lib_path(exe_path);
40+
setup_lib(lib_path)
41+
}
42+
43+
/// Start php-fpm process and tokio runtime.
44+
pub fn setup_lib(lib_path: impl AsRef<Path>) {
45+
let lib_path = lib_path.as_ref().to_owned();
3946

4047
let handle = FPM_HANDLE.get_or_init(|| {
4148
// shutdown hook.
@@ -55,7 +62,6 @@ pub fn setup(exe_path: impl AsRef<Path>) {
5562

5663
// Run php-fpm.
5764
let context = Context::get_global();
58-
let lib_path = utils::get_lib_path(exe_path);
5965
let php_fpm = context.find_php_fpm().unwrap();
6066
let php_ini_file = context.create_tmp_php_ini_file(&lib_path);
6167
let fpm_conf_file = context.create_tmp_fpm_conf_file();
@@ -77,14 +83,14 @@ pub fn setup(exe_path: impl AsRef<Path>) {
7783
// fs::remove_file("/tmp/.php-fpm.log").unwrap();
7884

7985
Mutex::new(FpmHandle {
80-
exe_path: exe_path.into(),
86+
lib_path: lib_path.clone(),
8187
fpm_child: child,
8288
php_ini_file: ManuallyDrop::new(php_ini_file),
8389
fpm_conf_file: ManuallyDrop::new(fpm_conf_file),
8490
})
8591
});
8692

87-
assert_eq!(&handle.lock().unwrap().exe_path, exe_path);
93+
assert_eq!(handle.lock().unwrap().lib_path, &*lib_path);
8894
}
8995

9096
extern "C" fn teardown() {

phper-test/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ mod context;
1717
#[cfg(feature = "fpm")]
1818
#[cfg_attr(docsrs, doc(cfg(feature = "fpm")))]
1919
pub mod fpm;
20-
mod utils;
20+
pub mod utils;

phper-test/src/utils.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::{
1818
time::Duration,
1919
};
2020

21-
pub fn execute_command<S: AsRef<OsStr> + Debug>(argv: &[S]) -> String {
21+
pub(crate) fn execute_command<S: AsRef<OsStr> + Debug>(argv: &[S]) -> String {
2222
let mut command = Command::new(&argv[0]);
2323
command.args(&argv[1..]);
2424
let output = command
@@ -28,7 +28,9 @@ pub fn execute_command<S: AsRef<OsStr> + Debug>(argv: &[S]) -> String {
2828
String::from_utf8(output).unwrap().trim().to_owned()
2929
}
3030

31-
pub fn spawn_command<S: AsRef<OsStr> + Debug>(argv: &[S], wait_time: Option<Duration>) -> Child {
31+
pub(crate) fn spawn_command<S: AsRef<OsStr> + Debug>(
32+
argv: &[S], wait_time: Option<Duration>,
33+
) -> Child {
3234
let mut command = Command::new(&argv[0]);
3335
let child = command
3436
.args(&argv[1..])
@@ -58,6 +60,14 @@ pub fn spawn_command<S: AsRef<OsStr> + Debug>(argv: &[S], wait_time: Option<Dura
5860
}
5961

6062
pub fn get_lib_path(exe_path: impl AsRef<Path>) -> PathBuf {
63+
get_lib_path_inner(exe_path, false)
64+
}
65+
66+
pub fn get_lib_path_by_example(exe_path: impl AsRef<Path>) -> PathBuf {
67+
get_lib_path_inner(exe_path, true)
68+
}
69+
70+
fn get_lib_path_inner(exe_path: impl AsRef<Path>, use_example: bool) -> PathBuf {
6171
let exe_path = exe_path.as_ref();
6272
let exe_stem = exe_path
6373
.file_stem()
@@ -78,5 +88,9 @@ pub fn get_lib_path(exe_path: impl AsRef<Path>) -> PathBuf {
7888
#[cfg(target_os = "windows")]
7989
ext_name.push(".dll");
8090

81-
target_dir.join(ext_name)
91+
if use_example {
92+
target_dir.join("examples").join(ext_name)
93+
} else {
94+
target_dir.join(ext_name)
95+
}
8296
}

phper/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub struct TypeError {
121121
}
122122

123123
#[derive(Debug, thiserror::Error, crate::Throwable, Constructor)]
124-
#[error("must be of type {expect_type}, {actual_type} given")]
124+
#[error("type error: must be of type {expect_type}, {actual_type} given")]
125125
#[throwable_class("TypeError")]
126126
pub struct ExpectTypeError {
127127
expect_type: TypeInfo,

phper/src/types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,18 @@ impl Display for TypeInfo {
150150
"null"
151151
} else if self.is_bool() {
152152
"bool"
153+
} else if self.is_long() {
154+
"int"
155+
} else if self.is_double() {
156+
"float"
157+
} else if self.is_string() {
158+
"string"
159+
} else if self.is_array() {
160+
"array"
161+
} else if self.is_object() {
162+
"object"
163+
} else if self.is_resource() {
164+
"resource"
153165
} else {
154166
"unknown"
155167
};

0 commit comments

Comments
 (0)