diff --git a/Cargo.toml b/Cargo.toml index 6ef2e83d83..a68852731e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ authors = ["David Cole "] edition = "2021" categories = ["api-bindings"] exclude = ["/.github", "/.crates"] +autotests = false [dependencies] bitflags = "2" @@ -39,6 +40,7 @@ zip = "4.0" [features] closure = [] embed = [] +anyhow = ["dep:anyhow"] [workspace] members = [ @@ -56,3 +58,16 @@ missing_docs = "warn" [[example]] name = "hello_world" crate-type = ["cdylib"] + +[[test]] +name = "guide_tests" +path = "tests/guide.rs" +required-features = ["embed", "closure", "anyhow"] + +[[test]] +name = "module_tests" +path = "tests/module.rs" + +[[test]] +name = "sapi_tests" +path = "tests/sapi.rs" diff --git a/guide/src/advanced/async_impl.md b/guide/src/advanced/async_impl.md index f4fe50518f..a95922d36f 100644 --- a/guide/src/advanced/async_impl.md +++ b/guide/src/advanced/async_impl.md @@ -18,7 +18,11 @@ This allows full compatibility with [amphp](https://amphp.org), [PSL](https://gi Make sure to require [php-tokio](https://github.com/danog/php-tokio) as a dependency before proceeding. -```rust,ignore + +```rust,no_run,ignore +# extern crate ext_php_rs; +# extern crate php_tokio; +# extern crate reqwest; use ext_php_rs::prelude::*; use php_tokio::{php_async_impl, EventLoop}; diff --git a/guide/src/macros/classes.md b/guide/src/macros/classes.md index 008581af98..e27124d895 100644 --- a/guide/src/macros/classes.md +++ b/guide/src/macros/classes.md @@ -121,7 +121,7 @@ pub fn get_module(module: ModuleBuilder) -> ModuleBuilder { To implement an interface, use `#[php(implements(ce = ce_fn, stub = "InterfaceName")]` where `ce_fn` is an function returning a `ClassEntry`. The following example implements [`ArrayAccess`](https://www.php.net/manual/en/class.arrayaccess.php): -````rust,no_run +```rust,no_run # #![cfg_attr(windows, feature(abi_vectorcall))] # extern crate ext_php_rs; use ext_php_rs::{ diff --git a/guide/src/types/functions.md b/guide/src/types/functions.md index 475a27b794..8a24a2be91 100644 --- a/guide/src/types/functions.md +++ b/guide/src/types/functions.md @@ -1,9 +1,9 @@ # Functions & methods -PHP functions and methods are represented by the `Function` struct. +PHP functions and methods are represented by the `Function` struct. -You can use the `try_from_function` and `try_from_method` methods to obtain a Function struct corresponding to the passed function or static method name. -It's heavily recommended you reuse returned `Function` objects, to avoid the overhead of looking up the function/method name. +You can use the `try_from_function` and `try_from_method` methods to obtain a Function struct corresponding to the passed function or static method name. +It's heavily recommended you reuse returned `Function` objects, to avoid the overhead of looking up the function/method name. ```rust,no_run # #![cfg_attr(windows, feature(abi_vectorcall))] diff --git a/guide/src/types/iterable.md b/guide/src/types/iterable.md index fec8072e3f..9fa1bdf68c 100644 --- a/guide/src/types/iterable.md +++ b/guide/src/types/iterable.md @@ -6,7 +6,7 @@ |---------------|----------------|-----------------| ---------------- |----------------------------------| | Yes | No | No | No | `ZendHashTable` or `ZendIterator` | -Converting from a zval to a `Iterable` is valid when the value is either an array or an object +Converting from a zval to a `Iterable` is valid when the value is either an array or an object that implements the `Traversable` interface. This means that any value that can be used in a `foreach` loop can be converted into a `Iterable`. diff --git a/guide/src/types/iterator.md b/guide/src/types/iterator.md index 4c53e6727d..d6d694e587 100644 --- a/guide/src/types/iterator.md +++ b/guide/src/types/iterator.md @@ -6,12 +6,12 @@ |---------------| -------------- |-----------------| ---------------- | ------------------ | | No | Yes | No | No | `ZendIterator` | -Converting from a zval to a `ZendIterator` is valid when there is an associated iterator to -the variable. This means that any value, at the exception of an `array`, that can be used in +Converting from a zval to a `ZendIterator` is valid when there is an associated iterator to +the variable. This means that any value, at the exception of an `array`, that can be used in a `foreach` loop can be converted into a `ZendIterator`. As an example, a `Generator` can be used but also a the result of a `query` call with `PDO`. -If you want a more universal `iterable` type that also supports arrays, see [Iterable](./iterable.md). +If you want a more universal `iterable` type that also supports arrays, see [Iterable](./iterable.md). ## Rust example diff --git a/src/args.rs b/src/args.rs index 832f7b8e2b..b275075e52 100644 --- a/src/args.rs +++ b/src/args.rs @@ -306,6 +306,8 @@ impl<'a, 'b> ArgParser<'a, 'b> { #[cfg(test)] mod tests { #![allow(clippy::unwrap_used)] + #[cfg(feature = "embed")] + use crate::embed::Embed; use super::*; @@ -427,12 +429,14 @@ mod tests { #[test] #[cfg(feature = "embed")] fn test_try_call_not_callable() { - let mut arg = Arg::new("test", DataType::Long); - let mut zval = Zval::from(42); - arg.zval = Some(&mut zval); - - let result = arg.try_call(vec![]); - assert!(result.is_err()); + Embed::run(|| { + let mut arg = Arg::new("test", DataType::Long); + let mut zval = Zval::from(42); + arg.zval = Some(&mut zval); + + let result = arg.try_call(vec![]); + assert!(result.is_err()); + }); } // TODO: Test the callable case diff --git a/src/zend/try_catch.rs b/src/zend/try_catch.rs index 2871ed9987..c9e8c3165d 100644 --- a/src/zend/try_catch.rs +++ b/src/zend/try_catch.rs @@ -190,20 +190,22 @@ mod tests { #[test] fn test_memory_leak() { - let mut ptr = null_mut(); + Embed::run(|| { + let mut ptr = null_mut(); - let _ = try_catch(|| { - let mut result = "foo".to_string(); - ptr = &mut result; + let _ = try_catch(|| { + let mut result = "foo".to_string(); + ptr = &mut result; - unsafe { - bailout(); - } - }); + unsafe { + bailout(); + } + }); - // Check that the string is never released - let result = unsafe { &*ptr as &str }; + // Check that the string is never released + let result = unsafe { &*ptr as &str }; - assert_eq!(result, "foo"); + assert_eq!(result, "foo"); + }); } }