Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / ParamValidator / TypeDef / TypeDefTestCase.php
1 <?php
2
3 namespace Wikimedia\ParamValidator\TypeDef;
4
5 use Wikimedia\ParamValidator\ParamValidator;
6 use Wikimedia\ParamValidator\SimpleCallbacks;
7 use Wikimedia\ParamValidator\TypeDef;
8 use Wikimedia\ParamValidator\ValidationException;
9
10 /**
11 * Test case infrastructure for TypeDef subclasses
12 *
13 * Generally you'll only need to override static::$testClass and data providers
14 * for methods the TypeDef actually implements.
15 */
16 abstract class TypeDefTestCase extends \PHPUnit\Framework\TestCase {
17
18 /** @var string|null TypeDef class name being tested */
19 protected static $testClass = null;
20
21 /**
22 * Create a SimpleCallbacks for testing
23 *
24 * The object created here should result in a call to the TypeDef's
25 * `getValue( 'test' )` returning an appropriate result for testing.
26 *
27 * @param mixed $value Value to return for 'test'
28 * @param array $options Options array.
29 * @return SimpleCallbacks
30 */
31 protected function getCallbacks( $value, array $options ) {
32 return new SimpleCallbacks( [ 'test' => $value ] );
33 }
34
35 /**
36 * Create an instance of the TypeDef subclass being tested
37 *
38 * @param SimpleCallbacks $callbacks From $this->getCallbacks()
39 * @param array $options Options array.
40 * @return TypeDef
41 */
42 protected function getInstance( SimpleCallbacks $callbacks, array $options ) {
43 if ( static::$testClass === null ) {
44 throw new \LogicException( 'Either assign static::$testClass or override ' . __METHOD__ );
45 }
46
47 return new static::$testClass( $callbacks );
48 }
49
50 /**
51 * @dataProvider provideValidate
52 * @param mixed $value Value for getCallbacks()
53 * @param mixed|ValidationException $expect Expected result from TypeDef::validate().
54 * If a ValidationException, it is expected that a ValidationException
55 * with matching failure code and data will be thrown. Otherwise, the return value must be equal.
56 * @param array $settings Settings array.
57 * @param array $options Options array
58 * @param array[] $expectConds Expected conditions reported. Each array is
59 * `[ $ex->getFailureCode() ] + $ex->getFailureData()`.
60 */
61 public function testValidate(
62 $value, $expect, array $settings = [], array $options = [], array $expectConds = []
63 ) {
64 $callbacks = $this->getCallbacks( $value, $options );
65 $typeDef = $this->getInstance( $callbacks, $options );
66
67 if ( $expect instanceof ValidationException ) {
68 try {
69 $v = $typeDef->getValue( 'test', $settings, $options );
70 $typeDef->validate( 'test', $v, $settings, $options );
71 $this->fail( 'Expected exception not thrown' );
72 } catch ( ValidationException $ex ) {
73 $this->assertEquals( $expect->getFailureCode(), $ex->getFailureCode() );
74 $this->assertEquals( $expect->getFailureData(), $ex->getFailureData() );
75 }
76 } else {
77 $v = $typeDef->getValue( 'test', $settings, $options );
78 $this->assertEquals( $expect, $typeDef->validate( 'test', $v, $settings, $options ) );
79 }
80
81 $conditions = [];
82 foreach ( $callbacks->getRecordedConditions() as $ex ) {
83 $conditions[] = array_merge( [ $ex->getFailureCode() ], $ex->getFailureData() );
84 }
85 $this->assertSame( $expectConds, $conditions );
86 }
87
88 /**
89 * @return array|Iterable
90 */
91 abstract public function provideValidate();
92
93 /**
94 * @dataProvider provideNormalizeSettings
95 * @param array $settings
96 * @param array $expect
97 * @param array $options Options array
98 */
99 public function testNormalizeSettings( array $settings, array $expect, array $options = [] ) {
100 $typeDef = $this->getInstance( new SimpleCallbacks( [] ), $options );
101 $this->assertSame( $expect, $typeDef->normalizeSettings( $settings ) );
102 }
103
104 /**
105 * @return array|Iterable
106 */
107 public function provideNormalizeSettings() {
108 return [
109 'Basic test' => [ [ 'param-foo' => 'bar' ], [ 'param-foo' => 'bar' ] ],
110 ];
111 }
112
113 /**
114 * @dataProvider provideGetEnumValues
115 * @param array $settings
116 * @param array|null $expect
117 * @param array $options Options array
118 */
119 public function testGetEnumValues( array $settings, $expect, array $options = [] ) {
120 $typeDef = $this->getInstance( new SimpleCallbacks( [] ), $options );
121 $this->assertSame( $expect, $typeDef->getEnumValues( 'test', $settings, $options ) );
122 }
123
124 /**
125 * @return array|Iterable
126 */
127 public function provideGetEnumValues() {
128 return [
129 'Basic test' => [ [], null ],
130 ];
131 }
132
133 /**
134 * @dataProvider provideStringifyValue
135 * @param mixed $value
136 * @param string|null $expect
137 * @param array $settings
138 * @param array $options Options array
139 */
140 public function testStringifyValue( $value, $expect, array $settings = [], array $options = [] ) {
141 $typeDef = $this->getInstance( new SimpleCallbacks( [] ), $options );
142 $this->assertSame( $expect, $typeDef->stringifyValue( 'test', $value, $settings, $options ) );
143 }
144
145 /**
146 * @return array|Iterable
147 */
148 public function provideStringifyValue() {
149 return [
150 'Basic test' => [ 123, '123' ],
151 ];
152 }
153
154 /**
155 * @dataProvider provideDescribeSettings
156 * @param array $settings
157 * @param array $expectNormal
158 * @param array $expectCompact
159 * @param array $options Options array
160 */
161 public function testDescribeSettings(
162 array $settings, array $expectNormal, array $expectCompact, array $options = []
163 ) {
164 $typeDef = $this->getInstance( new SimpleCallbacks( [] ), $options );
165 $this->assertSame(
166 $expectNormal,
167 $typeDef->describeSettings( 'test', $settings, $options ),
168 'Normal mode'
169 );
170 $this->assertSame(
171 $expectCompact,
172 $typeDef->describeSettings( 'test', $settings, [ 'compact' => true ] + $options ),
173 'Compact mode'
174 );
175 }
176
177 /**
178 * @return array|Iterable
179 */
180 public function provideDescribeSettings() {
181 yield 'Basic test' => [ [], [], [] ];
182
183 foreach ( $this->provideStringifyValue() as $i => $v ) {
184 yield "Default value (from provideStringifyValue data set \"$i\")" => [
185 [ ParamValidator::PARAM_DEFAULT => $v[0] ] + ( $v[2] ?? [] ),
186 [ 'default' => $v[1] ],
187 [ 'default' => [ 'value' => $v[1] ] ],
188 $v[3] ?? [],
189 ];
190 }
191 }
192
193 }