• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

10up / wp_mock / 13787625687

11 Mar 2025 12:07PM UTC coverage: 66.01% (-0.4%) from 66.446%
13787625687

push

github

web-flow
Add support for `withAnyArgs` method for `onFilter` calls. (#256)

# Summary <!-- Required -->

This PR implements a new method called `withAnyArgs` for `onFilter`
calls. This method is particularly useful in test cases where we do not
care about the filter arguments passed in but just its return value like
so:

```php
WP_Mock::onFilter('custom_content_filter')
    ->withAnyArgs()
    ->reply('This is filtered')
```

### Closes: #156 

## Details <!-- Optional -->

I have introduced a static array called `$filtersWithAnyArgs` that
basically acts as an associative array for filter names mapped to random
integer values.

This array will help us store random integers at the point where the
`withAnyArgs` method is called, so that we can check for those later in
the `apply` method and accurately set our passed in args.

Run tests:

```php
vendor/bin/phpunit ./tests/Unit/WP_MockTest.php 
```

<img width="490" alt="Screenshot 2025-03-09 at 12 16 12"
src="https://github.com/user-attachments/assets/ad15136e-b3a6-4d77-a70e-e83a5a7c90e1"
/>

## Contributor checklist <!-- Required -->

- [x] I agree to follow this project's [**Code of
Conduct**](https://github.com/10up/.github/blob/trunk/CODE_OF_CONDUCT.md).
- [x] I have updated the documentation accordingly 
- [x] I have added tests to cover changes introduced by this pull
request
- [x] All new and existing tests pass

## Testing <!-- Required -->

Create class like so:

```php
namespace MyPlugin;

class MyClass
{
    public function filterContent() : string
    {
        return apply_filters('custom_content_filter', 'This is unfiltered');
    }
}
```

Create Test like so:

```php
use MyPlugin\MyClass;
use WP_Mock;
use WP_Mock\Tools\TestCase as TestCase;

final class MyClassTest extends TestCase
{
    public function testCanFilterContent() : void 
    {
        WP_Mock::onFilter('custom_content_filter')
            ->withAnyArgs()
            ->reply('This is filtered');

        $content = (new MyClass())->filt... (continued)

0 of 5 new or added lines in 1 file covered. (0.0%)

503 of 762 relevant lines covered (66.01%)

2.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/php/WP_Mock/Filter.php
1
<?php
2

3
namespace WP_Mock;
4

5
/**
6
 * Mock representation of a WordPress filter as an object.
7
 *
8
 * Mocks WordPress filters by substituting each filter with an object capable of intercepting calls and returning predictable behavior.
9
 */
10
class Filter extends Hook
11
{
12
    /** @var array<mixed> Collection of filter names mapped to random integers. */
13
    protected static array $filtersWithAnyArgs = [];
14

15
    /**
16
     * Apply the stored filter.
17
     *
18
     * @param array $args Arguments passed to apply_filters()
19
     *
20
     * @return mixed
21
     */
22
    public function apply($args)
23
    {
NEW
24
        if (isset(static::$filtersWithAnyArgs[ $this->name ])) {
×
NEW
25
            $args = array_values(static::$filtersWithAnyArgs);
×
26
        }
27

28
        if ($args[0] === null && count($args) === 1) {
×
29
            if (isset($this->processors['argsnull'])) {
×
30
                return $this->processors['argsnull']->send();
×
31
            }
32
            $this->strict_check();
×
33

34
            return null;
×
35
        }
36

37
        $processors = $this->processors;
×
38
        foreach ($args as $arg) {
×
39
            $key = $this->safe_offset($arg);
×
40
            if (! is_array($processors) || ! isset($processors[ $key ])) {
×
41
                $this->strict_check();
×
42

43
                return $arg;
×
44
            }
45

46
            $processors = $processors[ $key ];
×
47
        }
48

49
        return call_user_func_array(array($processors, 'send'), $args);
×
50
    }
51

52
    /**
53
     * @return Filter_Responder
54
     */
55
    protected function new_responder()
56
    {
57
        return new Filter_Responder();
×
58
    }
59

60
    /**
61
     * @return string
62
     */
63
    protected function get_strict_mode_message()
64
    {
65
        return sprintf('Unexpected use of apply_filters for filter %s', $this->name);
×
66
    }
67

68
    /**
69
     * @return Action_Responder|Filter_Responder|HookedCallbackResponder
70
     */
71
    public function withAnyArgs()
72
    {
NEW
73
        $random_value = mt_rand();
×
NEW
74
        static::$filtersWithAnyArgs[ $this->name ] = $random_value;
×
75

NEW
76
        return $this->with($random_value);
×
77
    }
78
}
79

80
class Filter_Responder
81
{
82
    /**
83
     * @var mixed
84
     */
85
    protected $value;
86

87
    public function reply($value)
88
    {
89
        $this->value = $value;
×
90
    }
91

92
    public function send()
93
    {
94
        if ($this->value instanceof InvokedFilterValue) {
×
95
            return call_user_func_array($this->value, func_get_args());
×
96
        }
97

98
        return $this->value;
×
99
    }
100
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc