Skip to content

Commit 8a557aa

Browse files
committed
Add integration tests for function arguments.
1 parent f7fd7c2 commit 8a557aa

File tree

5 files changed

+110
-3
lines changed

5 files changed

+110
-3
lines changed

phper/src/arrays.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ impl Array {
3131
&mut self.inner
3232
}
3333

34+
// TODO key should be int or string.
3435
pub fn insert(&mut self, key: impl AsRef<str>, value: Val) {
3536
let key = key.as_ref();
3637
let value = EBox::new(value);
@@ -64,3 +65,13 @@ impl Drop for Array {
6465
}
6566
}
6667
}
68+
69+
impl Clone for Array {
70+
fn clone(&self) -> Self {
71+
let mut other = Self::new();
72+
unsafe {
73+
zend_hash_copy(other.as_mut_ptr(), self.as_ptr() as *mut _, None);
74+
}
75+
other
76+
}
77+
}

phper/src/objects.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
values::{SetVal, Val},
55
ClassNotFoundError,
66
};
7+
use phper_alloc::EBox;
78
use std::{
89
mem::{forget, zeroed},
910
ptr::null_mut,
@@ -109,6 +110,13 @@ impl Object {
109110
}
110111
}
111112
}
113+
114+
pub fn clone_obj(&self) -> EBox<Self> {
115+
unsafe {
116+
let new_obj = zend_objects_clone_obj(self.as_ptr() as *mut _).cast();
117+
EBox::from_raw(new_obj)
118+
}
119+
}
112120
}
113121

114122
impl Drop for Object {

phper/src/values.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl Val {
149149
if self.get_type().is_long() {
150150
unsafe { Ok(self.inner.value.lval) }
151151
} else {
152-
Err(self.must_be_type_error("long").into())
152+
Err(self.must_be_type_error("int").into())
153153
}
154154
}
155155

tests/integration/src/arguments.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use phper::{functions::Argument, modules::Module, values::Val};
1+
use phper::{
2+
alloc::EBox, arrays::Array, functions::Argument, modules::Module, objects::Object, values::Val,
3+
};
24

35
pub fn integrate(module: &mut Module) {
46
integrate_arguments(module);
@@ -8,6 +10,68 @@ fn integrate_arguments(module: &mut Module) {
810
module.add_function(
911
"integrate_arguments_null",
1012
|arguments: &mut [Val]| arguments[0].as_null(),
11-
vec![Argument::by_val("n")],
13+
vec![Argument::by_val("a")],
14+
);
15+
16+
module.add_function(
17+
"integrate_arguments_long",
18+
|arguments: &mut [Val]| -> phper::Result<i64> {
19+
let a = arguments[0].as_long()?;
20+
let b = arguments[1].as_long_value();
21+
Ok(a + b)
22+
},
23+
vec![Argument::by_val("a"), Argument::by_val("b")],
24+
);
25+
26+
module.add_function(
27+
"integrate_arguments_double",
28+
|arguments: &mut [Val]| arguments[0].as_double(),
29+
vec![Argument::by_val("a")],
30+
);
31+
32+
module.add_function(
33+
"integrate_arguments_string",
34+
|arguments: &mut [Val]| -> phper::Result<String> {
35+
let a = arguments[0].as_string()?;
36+
let b = arguments[1].as_string_value()?;
37+
Ok(format!("{}, {}", a, b))
38+
},
39+
vec![Argument::by_val("a"), Argument::by_val("b")],
40+
);
41+
42+
module.add_function(
43+
"integrate_arguments_array",
44+
|arguments: &mut [Val]| -> phper::Result<EBox<Array>> {
45+
let a = arguments[0].as_array()?;
46+
let mut a = a.clone();
47+
a.insert("foo", Val::new("bar"));
48+
Ok(EBox::new(a))
49+
},
50+
vec![Argument::by_val("a")],
51+
);
52+
53+
module.add_function(
54+
"integrate_arguments_object",
55+
|arguments: &mut [Val]| -> phper::Result<EBox<Object>> {
56+
let a = arguments[0].as_object()?;
57+
let mut a = a.clone_obj();
58+
a.set_property("foo", Val::new("bar"));
59+
Ok(a)
60+
},
61+
vec![Argument::by_val("a")],
62+
);
63+
64+
module.add_function(
65+
"integrate_arguments_optional",
66+
|arguments: &mut [Val]| -> phper::Result<String> {
67+
let a = arguments[0].as_string()?;
68+
let b = arguments
69+
.get(1)
70+
.map(|b| b.as_bool())
71+
.transpose()?
72+
.unwrap_or_default();
73+
Ok(format!("{}: {}", a, b))
74+
},
75+
vec![Argument::by_val("a"), Argument::by_val_optional("b")],
1276
);
1377
}

tests/integration/tests/php/arguments.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,27 @@
55
assert_eq(integrate_arguments_null(null), null);
66
assert_throw(function () { integrate_arguments_null(); }, "ArgumentCountError", 0, "integrate_arguments_null(): expects at least 1 parameter(s), 0 given");
77
assert_throw(function () { integrate_arguments_null(1); }, "TypeError", 0, "type error: must be of type null, int given");
8+
9+
assert_eq(integrate_arguments_long(1, 2), 3);
10+
assert_eq(integrate_arguments_long(1, "2"), 3);
11+
assert_throw(function () { integrate_arguments_long("1", "2"); }, "TypeError", 0, "type error: must be of type int, string given");
12+
13+
assert_eq(integrate_arguments_double(1.0), 1.0);
14+
assert_throw(function () { integrate_arguments_double(1); }, "TypeError", 0, "type error: must be of type float, int given");
15+
16+
assert_eq(integrate_arguments_string("hello", "world"), "hello, world");
17+
assert_eq(integrate_arguments_string("hello", 123), "hello, 123");
18+
assert_throw(function () { integrate_arguments_string(1, 2); }, "TypeError", 0, "type error: must be of type string, int given");
19+
20+
assert_eq(integrate_arguments_array(["a" => 1]), ["a" => 1, "foo" => "bar"]);
21+
assert_throw(function () { integrate_arguments_array(null); }, "TypeError", 0, "type error: must be of type array, null given");
22+
23+
$obj = new stdClass();
24+
$obj->a = 1;
25+
assert_object(integrate_arguments_object($obj), "stdClass", ["a" => 1, "foo" => "bar"]);
26+
assert_throw(function () { integrate_arguments_object(1); }, "TypeError", 0, "type error: must be of type object, int given");
27+
28+
assert_throw(function () { integrate_arguments_optional(); }, "ArgumentCountError", 0, "integrate_arguments_optional(): expects at least 1 parameter(s), 0 given");
29+
assert_eq(integrate_arguments_optional("foo"), "foo: false");
30+
assert_eq(integrate_arguments_optional("foo", true), "foo: true");
31+
assert_eq(integrate_arguments_optional("foo", true, "bar"), "foo: true");

0 commit comments

Comments
 (0)