3 namespace MediaWiki\Tests\Api
;
5 use AllowDynamicProperties
;
7 use InvalidArgumentException
;
8 use MediaWiki\Api\ApiErrorFormatter
;
9 use MediaWiki\Api\ApiResult
;
10 use MediaWiki\Title\Title
;
11 use MediaWikiIntegrationTestCase
;
14 use UnexpectedValueException
;
17 * @covers \MediaWiki\Api\ApiResult
20 class ApiResultTest
extends MediaWikiIntegrationTestCase
{
23 * @covers \MediaWiki\Api\ApiResult
25 public function testStaticDataMethods() {
28 ApiResult
::setValue( $arr, 'setValue', '1' );
30 ApiResult
::setValue( $arr, null, 'unnamed 1' );
31 ApiResult
::setValue( $arr, null, 'unnamed 2' );
33 ApiResult
::setValue( $arr, 'deleteValue', '2' );
34 ApiResult
::unsetValue( $arr, 'deleteValue' );
36 ApiResult
::setContentValue( $arr, 'setContentValue', '3' );
42 ApiResult
::META_CONTENT
=> 'setContentValue',
43 'setContentValue' => '3',
46 ApiResult
::setValue( $arr, 'setValue', '1' );
47 $this->assertSame( '1', $arr['setValue'] );
50 ApiResult
::setValue( $arr, 'setValue', '99' );
51 $this->fail( 'Expected exception not thrown' );
52 } catch ( RuntimeException
$ex ) {
54 'Attempting to add element setValue=99, existing value is 1',
61 ApiResult
::setContentValue( $arr, 'setContentValue2', '99' );
62 $this->fail( 'Expected exception not thrown' );
63 } catch ( RuntimeException
$ex ) {
65 'Attempting to set content element as setContentValue2 when setContentValue ' .
66 'is already set as the content element',
72 ApiResult
::setValue( $arr, 'setValue', '99', ApiResult
::OVERRIDE
);
73 $this->assertSame( '99', $arr['setValue'] );
75 ApiResult
::setContentValue( $arr, 'setContentValue2', '99', ApiResult
::OVERRIDE
);
76 $this->assertSame( 'setContentValue2', $arr[ApiResult
::META_CONTENT
] );
78 $arr = [ 'foo' => 1, 'bar' => 1 ];
79 ApiResult
::setValue( $arr, 'top', '2', ApiResult
::ADD_ON_TOP
);
80 ApiResult
::setValue( $arr, null, '2', ApiResult
::ADD_ON_TOP
);
81 ApiResult
::setValue( $arr, 'bottom', '2' );
82 ApiResult
::setValue( $arr, 'foo', '2', ApiResult
::OVERRIDE
);
83 ApiResult
::setValue( $arr, 'bar', '2', ApiResult
::OVERRIDE | ApiResult
::ADD_ON_TOP
);
84 $this->assertSame( [ 0, 'top', 'foo', 'bar', 'bottom' ], array_keys( $arr ) );
87 ApiResult
::setValue( $arr, 'sub', [ 'foo' => 1 ] );
88 ApiResult
::setValue( $arr, 'sub', [ 'bar' => 1 ] );
89 $this->assertSame( [ 'sub' => [ 'foo' => 1, 'bar' => 1 ] ], $arr );
92 ApiResult
::setValue( $arr, 'sub', [ 'foo' => 2, 'baz' => 2 ] );
93 $this->fail( 'Expected exception not thrown' );
94 } catch ( RuntimeException
$ex ) {
96 'Conflicting keys (foo) when attempting to merge element sub',
103 $title = Title
::makeTitle( NS_MEDIAWIKI
, "Foobar" );
104 $obj = (object)[ 'foo' => 1, 'bar' => 2 ];
105 ApiResult
::setValue( $arr, 'title', $title );
106 ApiResult
::setValue( $arr, 'obj', $obj );
108 'title' => (string)$title,
109 'obj' => [ 'foo' => 1, 'bar' => 2, ApiResult
::META_TYPE
=> 'assoc' ],
114 ApiResult
::setValue( $arr, 'file', $fh );
115 $this->fail( 'Expected exception not thrown' );
116 } catch ( InvalidArgumentException
$ex ) {
118 'Cannot add resource (stream) to ApiResult',
124 ApiResult
::setValue( $arr, null, $fh );
125 $this->fail( 'Expected exception not thrown' );
126 } catch ( InvalidArgumentException
$ex ) {
128 'Cannot add resource (stream) to ApiResult',
135 ApiResult
::setValue( $arr, 'sub', $obj );
136 $this->fail( 'Expected exception not thrown' );
137 } catch ( InvalidArgumentException
$ex ) {
139 'Cannot add resource (stream) to ApiResult',
146 ApiResult
::setValue( $arr, null, $obj );
147 $this->fail( 'Expected exception not thrown' );
148 } catch ( InvalidArgumentException
$ex ) {
150 'Cannot add resource (stream) to ApiResult',
158 ApiResult
::setValue( $arr, 'inf', INF
);
159 $this->fail( 'Expected exception not thrown' );
160 } catch ( InvalidArgumentException
$ex ) {
162 'Cannot add non-finite floats to ApiResult',
168 ApiResult
::setValue( $arr, null, INF
);
169 $this->fail( 'Expected exception not thrown' );
170 } catch ( InvalidArgumentException
$ex ) {
172 'Cannot add non-finite floats to ApiResult',
178 ApiResult
::setValue( $arr, 'nan', NAN
);
179 $this->fail( 'Expected exception not thrown' );
180 } catch ( InvalidArgumentException
$ex ) {
182 'Cannot add non-finite floats to ApiResult',
188 ApiResult
::setValue( $arr, null, NAN
);
189 $this->fail( 'Expected exception not thrown' );
190 } catch ( InvalidArgumentException
$ex ) {
192 'Cannot add non-finite floats to ApiResult',
198 ApiResult
::setValue( $arr, null, NAN
, ApiResult
::NO_VALIDATE
);
201 ApiResult
::setValue( $arr, null, NAN
, ApiResult
::NO_SIZE_CHECK
);
202 $this->fail( 'Expected exception not thrown' );
203 } catch ( InvalidArgumentException
$ex ) {
205 'Cannot add non-finite floats to ApiResult',
212 $result2 = new ApiResult( 8_388_608
);
213 $result2->addValue( null, 'foo', 'bar' );
214 ApiResult
::setValue( $arr, 'baz', $result2 );
217 ApiResult
::META_TYPE
=> 'assoc',
223 ApiResult
::setValue( $arr, 'foo', "foo\x80bar" );
224 ApiResult
::setValue( $arr, 'bar', "a\xcc\x81" );
225 ApiResult
::setValue( $arr, 'baz', 74 );
226 ApiResult
::setValue( $arr, null, "foo\x80bar" );
227 ApiResult
::setValue( $arr, null, "a\xcc\x81" );
229 'foo' => "foo\xef\xbf\xbdbar",
232 0 => "foo\xef\xbf\xbdbar",
236 $obj = (object)[ 1 => 'one' ];
238 ApiResult
::setValue( $arr, 'foo', $obj );
242 ApiResult
::META_TYPE
=> 'assoc',
248 * @covers \MediaWiki\Api\ApiResult
250 public function testInstanceDataMethods() {
251 $result = new ApiResult( 8_388_608
);
253 $result->addValue( null, 'setValue', '1' );
255 $result->addValue( null, null, 'unnamed 1' );
256 $result->addValue( null, null, 'unnamed 2' );
258 $result->addValue( null, 'deleteValue', '2' );
259 $result->removeValue( null, 'deleteValue' );
261 $result->addValue( [ 'a', 'b' ], 'deleteValue', '3' );
262 $result->removeValue( [ 'a', 'b', 'deleteValue' ], null, '3' );
264 $result->addContentValue( null, 'setContentValue', '3' );
270 'a' => [ 'b' => [] ],
271 'setContentValue' => '3',
272 ApiResult
::META_TYPE
=> 'assoc',
273 ApiResult
::META_CONTENT
=> 'setContentValue',
274 ], $result->getResultData() );
275 $this->assertSame( 20, $result->getSize() );
278 $result->addValue( null, 'setValue', '99' );
279 $this->fail( 'Expected exception not thrown' );
280 } catch ( RuntimeException
$ex ) {
282 'Attempting to add element setValue=99, existing value is 1',
289 $result->addContentValue( null, 'setContentValue2', '99' );
290 $this->fail( 'Expected exception not thrown' );
291 } catch ( RuntimeException
$ex ) {
293 'Attempting to set content element as setContentValue2 when setContentValue ' .
294 'is already set as the content element',
300 $result->addValue( null, 'setValue', '99', ApiResult
::OVERRIDE
);
301 $this->assertSame( '99', $result->getResultData( [ 'setValue' ] ) );
303 $result->addContentValue( null, 'setContentValue2', '99', ApiResult
::OVERRIDE
);
304 $this->assertSame( 'setContentValue2',
305 $result->getResultData( [ ApiResult
::META_CONTENT
] ) );
309 ApiResult
::META_TYPE
=> 'assoc',
310 ], $result->getResultData() );
311 $this->assertSame( 0, $result->getSize() );
313 $result->addValue( null, 'foo', 1 );
314 $result->addValue( null, 'bar', 1 );
315 $result->addValue( null, 'top', '2', ApiResult
::ADD_ON_TOP
);
316 $result->addValue( null, null, '2', ApiResult
::ADD_ON_TOP
);
317 $result->addValue( null, 'bottom', '2' );
318 $result->addValue( null, 'foo', '2', ApiResult
::OVERRIDE
);
319 $result->addValue( null, 'bar', '2', ApiResult
::OVERRIDE | ApiResult
::ADD_ON_TOP
);
320 $this->assertSame( [ 0, 'top', 'foo', 'bar', 'bottom', ApiResult
::META_TYPE
],
321 array_keys( $result->getResultData() ) );
324 $result->addValue( null, 'foo', [ 'bar' => 1 ] );
325 $result->addValue( [ 'foo', 'top' ], 'x', 2, ApiResult
::ADD_ON_TOP
);
326 $result->addValue( [ 'foo', 'bottom' ], 'x', 2 );
327 $this->assertSame( [ 'top', 'bar', 'bottom' ],
328 array_keys( $result->getResultData( [ 'foo' ] ) ) );
331 $result->addValue( null, 'sub', [ 'foo' => 1 ] );
332 $result->addValue( null, 'sub', [ 'bar' => 1 ] );
334 'sub' => [ 'foo' => 1, 'bar' => 1 ],
335 ApiResult
::META_TYPE
=> 'assoc',
336 ], $result->getResultData() );
339 $result->addValue( null, 'sub', [ 'foo' => 2, 'baz' => 2 ] );
340 $this->fail( 'Expected exception not thrown' );
341 } catch ( RuntimeException
$ex ) {
343 'Conflicting keys (foo) when attempting to merge element sub',
350 $title = Title
::makeTitle( NS_MEDIAWIKI
, "Foobar" );
351 $obj = (object)[ 'foo' => 1, 'bar' => 2 ];
352 $result->addValue( null, 'title', $title );
353 $result->addValue( null, 'obj', $obj );
355 'title' => (string)$title,
356 'obj' => [ 'foo' => 1, 'bar' => 2, ApiResult
::META_TYPE
=> 'assoc' ],
357 ApiResult
::META_TYPE
=> 'assoc',
358 ], $result->getResultData() );
362 $result->addValue( null, 'file', $fh );
363 $this->fail( 'Expected exception not thrown' );
364 } catch ( InvalidArgumentException
$ex ) {
366 'Cannot add resource (stream) to ApiResult',
372 $result->addValue( null, null, $fh );
373 $this->fail( 'Expected exception not thrown' );
374 } catch ( InvalidArgumentException
$ex ) {
376 'Cannot add resource (stream) to ApiResult',
383 $result->addValue( null, 'sub', $obj );
384 $this->fail( 'Expected exception not thrown' );
385 } catch ( InvalidArgumentException
$ex ) {
387 'Cannot add resource (stream) to ApiResult',
394 $result->addValue( null, null, $obj );
395 $this->fail( 'Expected exception not thrown' );
396 } catch ( InvalidArgumentException
$ex ) {
398 'Cannot add resource (stream) to ApiResult',
406 $result->addValue( null, 'inf', INF
);
407 $this->fail( 'Expected exception not thrown' );
408 } catch ( InvalidArgumentException
$ex ) {
410 'Cannot add non-finite floats to ApiResult',
416 $result->addValue( null, null, INF
);
417 $this->fail( 'Expected exception not thrown' );
418 } catch ( InvalidArgumentException
$ex ) {
420 'Cannot add non-finite floats to ApiResult',
426 $result->addValue( null, 'nan', NAN
);
427 $this->fail( 'Expected exception not thrown' );
428 } catch ( InvalidArgumentException
$ex ) {
430 'Cannot add non-finite floats to ApiResult',
436 $result->addValue( null, null, NAN
);
437 $this->fail( 'Expected exception not thrown' );
438 } catch ( InvalidArgumentException
$ex ) {
440 'Cannot add non-finite floats to ApiResult',
446 $result->addValue( null, null, NAN
, ApiResult
::NO_VALIDATE
);
449 $result->addValue( null, null, NAN
, ApiResult
::NO_SIZE_CHECK
);
450 $this->fail( 'Expected exception not thrown' );
451 } catch ( InvalidArgumentException
$ex ) {
453 'Cannot add non-finite floats to ApiResult',
460 $result->addParsedLimit( 'foo', 12 );
462 'limits' => [ 'foo' => 12 ],
463 ApiResult
::META_TYPE
=> 'assoc',
464 ], $result->getResultData() );
465 $result->addParsedLimit( 'foo', 13 );
467 'limits' => [ 'foo' => 13 ],
468 ApiResult
::META_TYPE
=> 'assoc',
469 ], $result->getResultData() );
470 $this->assertSame( null, $result->getResultData( [ 'foo', 'bar', 'baz' ] ) );
471 $this->assertSame( 13, $result->getResultData( [ 'limits', 'foo' ] ) );
473 $result->getResultData( [ 'limits', 'foo', 'bar' ] );
474 $this->fail( 'Expected exception not thrown' );
475 } catch ( InvalidArgumentException
$ex ) {
477 'Path limits.foo is not an array',
483 // Add two values and some metadata, but ensure metadata is not counted
484 $result = new ApiResult( 100 );
485 $obj = [ 'attr' => '12345' ];
486 ApiResult
::setContentValue( $obj, 'content', '1234567890' );
487 $this->assertTrue( $result->addValue( null, 'foo', $obj ) );
488 $this->assertSame( 15, $result->getSize() );
490 $result = new ApiResult( 10 );
491 $formatter = new ApiErrorFormatter( $result,
492 $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' ),
494 $result->setErrorFormatter( $formatter );
495 $this->assertFalse( $result->addValue( null, 'foo', '12345678901' ) );
496 $this->assertTrue( $result->addValue( null, 'foo', '12345678901', ApiResult
::NO_SIZE_CHECK
) );
497 $this->assertSame( 0, $result->getSize() );
499 $this->assertTrue( $result->addValue( null, 'foo', '1234567890' ) );
500 $this->assertFalse( $result->addValue( null, 'foo', '1' ) );
501 $result->removeValue( null, 'foo' );
502 $this->assertTrue( $result->addValue( null, 'foo', '1' ) );
504 $result = new ApiResult( 10 );
505 $obj = new ApiResultTestSerializableObject( 'ok' );
506 $obj->foobar
= 'foobaz';
507 $this->assertTrue( $result->addValue( null, 'foo', $obj ) );
508 $this->assertSame( 2, $result->getSize() );
510 $result = new ApiResult( 8_388_608
);
511 $result2 = new ApiResult( 8_388_608
);
512 $result2->addValue( null, 'foo', 'bar' );
513 $result->addValue( null, 'baz', $result2 );
517 ApiResult
::META_TYPE
=> 'assoc',
519 ApiResult
::META_TYPE
=> 'assoc',
520 ], $result->getResultData() );
522 $result = new ApiResult( 8_388_608
);
523 $result->addValue( null, 'foo', "foo\x80bar" );
524 $result->addValue( null, 'bar', "a\xcc\x81" );
525 $result->addValue( null, 'baz', 74 );
526 $result->addValue( null, null, "foo\x80bar" );
527 $result->addValue( null, null, "a\xcc\x81" );
529 'foo' => "foo\xef\xbf\xbdbar",
532 0 => "foo\xef\xbf\xbdbar",
534 ApiResult
::META_TYPE
=> 'assoc',
535 ], $result->getResultData() );
537 $result = new ApiResult( 8_388_608
);
538 $obj = (object)[ 1 => 'one' ];
540 $result->addValue( $arr, 'foo', $obj );
544 ApiResult
::META_TYPE
=> 'assoc',
546 ApiResult
::META_TYPE
=> 'assoc',
547 ], $result->getResultData() );
551 * @covers \MediaWiki\Api\ApiResult
553 public function testMetadata() {
554 $arr = [ 'foo' => [ 'bar' => [] ] ];
555 $result = new ApiResult( 8_388_608
);
556 $result->addValue( null, 'foo', [ 'bar' => [] ] );
561 ApiResult
::META_INDEXED_TAG_NAME
=> 'ritn',
562 ApiResult
::META_TYPE
=> 'default',
564 ApiResult
::META_INDEXED_TAG_NAME
=> 'ritn',
565 ApiResult
::META_TYPE
=> 'default',
567 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
568 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
569 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar' ],
570 ApiResult
::META_TYPE
=> 'array',
573 ApiResult
::setSubelementsList( $arr, 'foo' );
574 ApiResult
::setSubelementsList( $arr, [ 'bar', 'baz' ] );
575 ApiResult
::unsetSubelementsList( $arr, 'baz' );
576 ApiResult
::setIndexedTagNameRecursive( $arr, 'ritn' );
577 ApiResult
::setIndexedTagName( $arr, 'itn' );
578 ApiResult
::setPreserveKeysList( $arr, 'foo' );
579 ApiResult
::setPreserveKeysList( $arr, [ 'bar', 'baz' ] );
580 ApiResult
::unsetPreserveKeysList( $arr, 'baz' );
581 ApiResult
::setArrayTypeRecursive( $arr, 'default' );
582 ApiResult
::setArrayType( $arr, 'array' );
583 $this->assertSame( $expect, $arr );
585 $result->addSubelementsList( null, 'foo' );
586 $result->addSubelementsList( null, [ 'bar', 'baz' ] );
587 $result->removeSubelementsList( null, 'baz' );
588 $result->addIndexedTagNameRecursive( null, 'ritn' );
589 $result->addIndexedTagName( null, 'itn' );
590 $result->addPreserveKeysList( null, 'foo' );
591 $result->addPreserveKeysList( null, [ 'bar', 'baz' ] );
592 $result->removePreserveKeysList( null, 'baz' );
593 $result->addArrayTypeRecursive( null, 'default' );
594 $result->addArrayType( null, 'array' );
595 $this->assertEquals( $expect, $result->getResultData() );
597 $arr = [ 'foo' => [ 'bar' => [] ] ];
601 ApiResult
::META_TYPE
=> 'kvp',
602 ApiResult
::META_KVP_KEY_NAME
=> 'key',
604 ApiResult
::META_TYPE
=> 'kvp',
605 ApiResult
::META_KVP_KEY_NAME
=> 'key',
607 ApiResult
::META_TYPE
=> 'BCkvp',
608 ApiResult
::META_KVP_KEY_NAME
=> 'bc',
610 ApiResult
::setArrayTypeRecursive( $arr, 'kvp', 'key' );
611 ApiResult
::setArrayType( $arr, 'BCkvp', 'bc' );
612 $this->assertSame( $expect, $arr );
616 * @covers \MediaWiki\Api\ApiResult
618 public function testUtilityFunctions() {
621 'bar' => [ '_dummy' => 'foobaz' ],
622 'bar2' => (object)[ '_dummy' => 'foobaz' ],
624 '_dummy' => 'foobaz',
627 'bar' => [ '_dummy' => 'foobaz' ],
628 'bar2' => (object)[ '_dummy' => 'foobaz' ],
630 '_dummy' => 'foobaz',
632 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
633 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
634 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
635 ApiResult
::META_TYPE
=> 'array',
636 '_dummy' => 'foobaz',
637 '_dummy2' => 'foobaz!',
639 $this->assertEquals( [
642 'bar2' => (object)[],
647 'bar2' => (object)[],
650 '_dummy2' => 'foobaz!',
651 ], ApiResult
::stripMetadata( $arr ), 'ApiResult::stripMetadata' );
654 $data = ApiResult
::stripMetadataNonRecursive( $arr, $metadata );
655 $this->assertEquals( [
657 'bar' => [ '_dummy' => 'foobaz' ],
658 'bar2' => (object)[ '_dummy' => 'foobaz' ],
660 '_dummy' => 'foobaz',
663 'bar' => [ '_dummy' => 'foobaz' ],
664 'bar2' => (object)[ '_dummy' => 'foobaz' ],
666 '_dummy' => 'foobaz',
668 '_dummy2' => 'foobaz!',
669 ], $data, 'ApiResult::stripMetadataNonRecursive ($data)' );
670 $this->assertEquals( [
671 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
672 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
673 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
674 ApiResult
::META_TYPE
=> 'array',
675 '_dummy' => 'foobaz',
676 ], $metadata, 'ApiResult::stripMetadataNonRecursive ($metadata)' );
679 $data = ApiResult
::stripMetadataNonRecursive( (object)$arr, $metadata );
680 $this->assertEquals( (object)[
682 'bar' => [ '_dummy' => 'foobaz' ],
683 'bar2' => (object)[ '_dummy' => 'foobaz' ],
685 '_dummy' => 'foobaz',
688 'bar' => [ '_dummy' => 'foobaz' ],
689 'bar2' => (object)[ '_dummy' => 'foobaz' ],
691 '_dummy' => 'foobaz',
693 '_dummy2' => 'foobaz!',
694 ], $data, 'ApiResult::stripMetadataNonRecursive on object ($data)' );
695 $this->assertEquals( [
696 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
697 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
698 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
699 ApiResult
::META_TYPE
=> 'array',
700 '_dummy' => 'foobaz',
701 ], $metadata, 'ApiResult::stripMetadataNonRecursive on object ($metadata)' );
705 * @covers \MediaWiki\Api\ApiResult
706 * @dataProvider provideTransformations
707 * @param string $label
708 * @param array $input
709 * @param array $transforms
710 * @param array|Exception $expect
712 public function testTransformations( $label, $input, $transforms, $expect ) {
713 $result = new ApiResult( false );
714 $result->addValue( null, 'test', $input );
716 if ( $expect instanceof Exception
) {
718 $output = $result->getResultData( 'test', $transforms );
719 $this->fail( 'Expected exception not thrown', $label );
720 } catch ( Exception
$ex ) {
721 $this->assertEquals( $ex, $expect, $label );
724 $output = $result->getResultData( 'test', $transforms );
725 $this->assertEquals( $expect, $output, $label );
729 public function provideTransformations() {
730 $kvp = static function ( $keyKey, $key, $valKey, $value ) {
734 ApiResult
::META_PRESERVE_KEYS
=> [ $keyKey ],
735 ApiResult
::META_CONTENT
=> $valKey,
736 ApiResult
::META_TYPE
=> 'assoc',
740 'defaultArray' => [ 2 => 'a', 0 => 'b', 1 => 'c' ],
741 'defaultAssoc' => [ 'x' => 'a', 1 => 'b', 0 => 'c' ],
742 'defaultAssoc2' => [ 2 => 'a', 3 => 'b', 0 => 'c' ],
743 'array' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'array' ],
744 'BCarray' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'BCarray' ],
745 'BCassoc' => [ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'BCassoc' ],
746 'assoc' => [ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
747 'kvp' => [ 'x' => 'a', 'y' => 'b', 'z' => [ 'c' ], ApiResult
::META_TYPE
=> 'kvp' ],
748 'BCkvp' => [ 'x' => 'a', 'y' => 'b',
749 ApiResult
::META_TYPE
=> 'BCkvp',
750 ApiResult
::META_KVP_KEY_NAME
=> 'key',
752 'kvpmerge' => [ 'x' => 'a', 'y' => [ 'b' ], 'z' => [ 'c' => 'd' ],
753 ApiResult
::META_TYPE
=> 'kvp',
754 ApiResult
::META_KVP_MERGE
=> true,
756 'emptyDefault' => [ '_dummy' => 1 ],
757 'emptyAssoc' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
759 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
763 'bar' => [ '_dummy' => 'foobaz' ],
765 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
766 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
767 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
768 ApiResult
::META_TYPE
=> 'array',
771 '_dummy' => 'foobaz',
773 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
774 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
775 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
776 ApiResult
::META_TYPE
=> 'array',
777 '_dummy' => 'foobaz',
778 '_dummy2' => 'foobaz!',
789 ApiResult
::META_BC_BOOLS
=> [ 0, 'true', 'false' ],
796 ApiResult
::META_BC_BOOLS
=> [ 0, 'true', 'false' ],
800 'BC: META_BC_SUBELEMENTS',
804 ApiResult
::META_BC_SUBELEMENTS
=> [ 'bc' ],
810 ApiResult
::META_CONTENT
=> '*',
811 ApiResult
::META_TYPE
=> 'assoc',
814 ApiResult
::META_BC_SUBELEMENTS
=> [ 'bc' ],
821 ApiResult
::META_CONTENT
=> 'content',
826 ApiResult
::META_CONTENT
=> '*',
832 'foo' => 'foo value',
833 'bar' => 'bar value',
834 '_baz' => 'baz value',
835 ApiResult
::META_TYPE
=> 'BCkvp',
836 ApiResult
::META_KVP_KEY_NAME
=> 'key',
837 ApiResult
::META_PRESERVE_KEYS
=> [ '_baz' ],
841 $kvp( 'key', 'foo', '*', 'foo value' ),
842 $kvp( 'key', 'bar', '*', 'bar value' ),
843 $kvp( 'key', '_baz', '*', 'baz value' ),
844 ApiResult
::META_TYPE
=> 'array',
845 ApiResult
::META_KVP_KEY_NAME
=> 'key',
846 ApiResult
::META_PRESERVE_KEYS
=> [ '_baz' ],
852 ApiResult
::META_TYPE
=> 'BCarray',
856 ApiResult
::META_TYPE
=> 'default',
862 ApiResult
::META_TYPE
=> 'BCassoc',
866 ApiResult
::META_TYPE
=> 'default',
870 'BC: BCkvp exception',
872 ApiResult
::META_TYPE
=> 'BCkvp',
875 new UnexpectedValueException(
876 'Type "BCkvp" used without setting ApiResult::META_KVP_KEY_NAME metadata item'
880 'BC: nobool, no*, nosub',
884 'content' => 'content',
885 ApiResult
::META_CONTENT
=> 'content',
887 ApiResult
::META_BC_SUBELEMENTS
=> [ 'bc' ],
888 'BCarray' => [ ApiResult
::META_TYPE
=> 'BCarray' ],
889 'BCassoc' => [ ApiResult
::META_TYPE
=> 'BCassoc' ],
891 'foo' => 'foo value',
892 'bar' => 'bar value',
893 '_baz' => 'baz value',
894 ApiResult
::META_TYPE
=> 'BCkvp',
895 ApiResult
::META_KVP_KEY_NAME
=> 'key',
896 ApiResult
::META_PRESERVE_KEYS
=> [ '_baz' ],
899 [ 'BC' => [ 'nobool', 'no*', 'nosub' ] ],
903 'content' => 'content',
905 'BCarray' => [ ApiResult
::META_TYPE
=> 'default' ],
906 'BCassoc' => [ ApiResult
::META_TYPE
=> 'default' ],
908 $kvp( 'key', 'foo', '*', 'foo value' ),
909 $kvp( 'key', 'bar', '*', 'bar value' ),
910 $kvp( 'key', '_baz', '*', 'baz value' ),
911 ApiResult
::META_TYPE
=> 'array',
912 ApiResult
::META_KVP_KEY_NAME
=> 'key',
913 ApiResult
::META_PRESERVE_KEYS
=> [ '_baz' ],
915 ApiResult
::META_CONTENT
=> 'content',
916 ApiResult
::META_BC_SUBELEMENTS
=> [ 'bc' ],
921 'Types: Normal transform',
925 'defaultArray' => [ 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
926 'defaultAssoc' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
927 'defaultAssoc2' => [ 2 => 'a', 3 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
928 'array' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
929 'BCarray' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
930 'BCassoc' => [ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'assoc' ],
931 'assoc' => [ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
932 'kvp' => [ 'x' => 'a', 'y' => 'b',
933 'z' => [ 'c', ApiResult
::META_TYPE
=> 'array' ],
934 ApiResult
::META_TYPE
=> 'assoc'
936 'BCkvp' => [ 'x' => 'a', 'y' => 'b',
937 ApiResult
::META_TYPE
=> 'assoc',
938 ApiResult
::META_KVP_KEY_NAME
=> 'key',
942 'y' => [ 'b', ApiResult
::META_TYPE
=> 'array' ],
943 'z' => [ 'c' => 'd', ApiResult
::META_TYPE
=> 'assoc' ],
944 ApiResult
::META_TYPE
=> 'assoc',
945 ApiResult
::META_KVP_MERGE
=> true,
947 'emptyDefault' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'array' ],
948 'emptyAssoc' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
950 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
951 ApiResult
::META_TYPE
=> 'assoc',
955 'Types: AssocAsObject',
957 [ 'Types' => [ 'AssocAsObject' => true ] ],
959 'defaultArray' => [ 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
960 'defaultAssoc' => (object)[ 'x' => 'a',
961 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc'
963 'defaultAssoc2' => (object)[ 2 => 'a', 3 => 'b',
964 0 => 'c', ApiResult
::META_TYPE
=> 'assoc'
966 'array' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
967 'BCarray' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
968 'BCassoc' => (object)[ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'assoc' ],
969 'assoc' => (object)[ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
970 'kvp' => (object)[ 'x' => 'a', 'y' => 'b',
971 'z' => [ 'c', ApiResult
::META_TYPE
=> 'array' ],
972 ApiResult
::META_TYPE
=> 'assoc'
974 'BCkvp' => (object)[ 'x' => 'a', 'y' => 'b',
975 ApiResult
::META_TYPE
=> 'assoc',
976 ApiResult
::META_KVP_KEY_NAME
=> 'key',
978 'kvpmerge' => (object)[
980 'y' => [ 'b', ApiResult
::META_TYPE
=> 'array' ],
981 'z' => (object)[ 'c' => 'd', ApiResult
::META_TYPE
=> 'assoc' ],
982 ApiResult
::META_TYPE
=> 'assoc',
983 ApiResult
::META_KVP_MERGE
=> true,
985 'emptyDefault' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'array' ],
986 'emptyAssoc' => (object)[ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
988 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
989 ApiResult
::META_TYPE
=> 'assoc',
995 [ 'Types' => [ 'ArmorKVP' => 'name' ] ],
997 'defaultArray' => [ 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
998 'defaultAssoc' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
999 'defaultAssoc2' => [ 2 => 'a', 3 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1000 'array' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
1001 'BCarray' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
1002 'BCassoc' => [ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1003 'assoc' => [ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1005 $kvp( 'name', 'x', 'value', 'a' ),
1006 $kvp( 'name', 'y', 'value', 'b' ),
1007 $kvp( 'name', 'z', 'value', [ 'c', ApiResult
::META_TYPE
=> 'array' ] ),
1008 ApiResult
::META_TYPE
=> 'array'
1011 $kvp( 'key', 'x', 'value', 'a' ),
1012 $kvp( 'key', 'y', 'value', 'b' ),
1013 ApiResult
::META_TYPE
=> 'array',
1014 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1017 $kvp( 'name', 'x', 'value', 'a' ),
1018 $kvp( 'name', 'y', 'value', [ 'b', ApiResult
::META_TYPE
=> 'array' ] ),
1022 ApiResult
::META_TYPE
=> 'assoc',
1023 ApiResult
::META_PRESERVE_KEYS
=> [ 'name' ]
1025 ApiResult
::META_TYPE
=> 'array',
1026 ApiResult
::META_KVP_MERGE
=> true,
1028 'emptyDefault' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'array' ],
1029 'emptyAssoc' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
1031 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
1032 ApiResult
::META_TYPE
=> 'assoc',
1036 'Types: ArmorKVP + BC',
1038 [ 'BC' => [], 'Types' => [ 'ArmorKVP' => 'name' ] ],
1040 'defaultArray' => [ 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
1041 'defaultAssoc' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1042 'defaultAssoc2' => [ 2 => 'a', 3 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1043 'array' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
1044 'BCarray' => [ 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1045 'BCassoc' => [ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'array' ],
1046 'assoc' => [ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1048 $kvp( 'name', 'x', '*', 'a' ),
1049 $kvp( 'name', 'y', '*', 'b' ),
1050 $kvp( 'name', 'z', '*', [ 'c', ApiResult
::META_TYPE
=> 'array' ] ),
1051 ApiResult
::META_TYPE
=> 'array'
1054 $kvp( 'key', 'x', '*', 'a' ),
1055 $kvp( 'key', 'y', '*', 'b' ),
1056 ApiResult
::META_TYPE
=> 'array',
1057 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1060 $kvp( 'name', 'x', '*', 'a' ),
1061 $kvp( 'name', 'y', '*', [ 'b', ApiResult
::META_TYPE
=> 'array' ] ),
1065 ApiResult
::META_TYPE
=> 'assoc',
1066 ApiResult
::META_PRESERVE_KEYS
=> [ 'name' ] ],
1067 ApiResult
::META_TYPE
=> 'array',
1068 ApiResult
::META_KVP_MERGE
=> true,
1070 'emptyDefault' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'array' ],
1071 'emptyAssoc' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
1073 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
1074 ApiResult
::META_TYPE
=> 'assoc',
1078 'Types: ArmorKVP + AssocAsObject',
1080 [ 'Types' => [ 'ArmorKVP' => 'name', 'AssocAsObject' => true ] ],
1082 'defaultArray' => [ 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
1083 'defaultAssoc' => (object)[ 'x' => 'a', 1 => 'b',
1084 0 => 'c', ApiResult
::META_TYPE
=> 'assoc'
1086 'defaultAssoc2' => (object)[ 2 => 'a', 3 => 'b',
1087 0 => 'c', ApiResult
::META_TYPE
=> 'assoc'
1089 'array' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
1090 'BCarray' => [ 'c', 'b', 'a', ApiResult
::META_TYPE
=> 'array' ],
1091 'BCassoc' => (object)[ 'a', 'b', 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1092 'assoc' => (object)[ 2 => 'a', 0 => 'b', 1 => 'c', ApiResult
::META_TYPE
=> 'assoc' ],
1094 (object)$kvp( 'name', 'x', 'value', 'a' ),
1095 (object)$kvp( 'name', 'y', 'value', 'b' ),
1096 (object)$kvp( 'name', 'z', 'value', [ 'c', ApiResult
::META_TYPE
=> 'array' ] ),
1097 ApiResult
::META_TYPE
=> 'array'
1100 (object)$kvp( 'key', 'x', 'value', 'a' ),
1101 (object)$kvp( 'key', 'y', 'value', 'b' ),
1102 ApiResult
::META_TYPE
=> 'array',
1103 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1106 (object)$kvp( 'name', 'x', 'value', 'a' ),
1107 (object)$kvp( 'name', 'y', 'value', [ 'b', ApiResult
::META_TYPE
=> 'array' ] ),
1111 ApiResult
::META_TYPE
=> 'assoc',
1112 ApiResult
::META_PRESERVE_KEYS
=> [ 'name' ]
1114 ApiResult
::META_TYPE
=> 'array',
1115 ApiResult
::META_KVP_MERGE
=> true,
1117 'emptyDefault' => [ '_dummy' => 1, ApiResult
::META_TYPE
=> 'array' ],
1118 'emptyAssoc' => (object)[ '_dummy' => 1, ApiResult
::META_TYPE
=> 'assoc' ],
1120 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy' ],
1121 ApiResult
::META_TYPE
=> 'assoc',
1125 'Types: BCkvp exception',
1127 ApiResult
::META_TYPE
=> 'BCkvp',
1130 new UnexpectedValueException(
1131 'Type "BCkvp" used without setting ApiResult::META_KVP_KEY_NAME metadata item'
1136 'Strip: With ArmorKVP + AssocAsObject transforms',
1138 [ 'Types' => [ 'ArmorKVP' => 'name', 'AssocAsObject' => true ], 'Strip' => 'all' ],
1140 'defaultArray' => [ 'b', 'c', 'a' ],
1141 'defaultAssoc' => (object)[ 'x' => 'a', 1 => 'b', 0 => 'c' ],
1142 'defaultAssoc2' => (object)[ 2 => 'a', 3 => 'b', 0 => 'c' ],
1143 'array' => [ 'c', 'b', 'a' ],
1144 'BCarray' => [ 'c', 'b', 'a' ],
1145 'BCassoc' => (object)[ 'a', 'b', 'c' ],
1146 'assoc' => (object)[ 2 => 'a', 0 => 'b', 1 => 'c' ],
1148 (object)[ 'name' => 'x', 'value' => 'a' ],
1149 (object)[ 'name' => 'y', 'value' => 'b' ],
1150 (object)[ 'name' => 'z', 'value' => [ 'c' ] ],
1153 (object)[ 'key' => 'x', 'value' => 'a' ],
1154 (object)[ 'key' => 'y', 'value' => 'b' ],
1157 (object)[ 'name' => 'x', 'value' => 'a' ],
1158 (object)[ 'name' => 'y', 'value' => [ 'b' ] ],
1159 (object)[ 'name' => 'z', 'c' => 'd' ],
1161 'emptyDefault' => [],
1162 'emptyAssoc' => (object)[],
1170 [ 'Strip' => 'all' ],
1177 '_dummy2' => 'foobaz!',
1183 [ 'Strip' => 'base' ],
1186 'bar' => [ '_dummy' => 'foobaz' ],
1188 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
1189 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
1190 ApiResult
::META_PRESERVE_KEYS
=> [ 'foo', 'bar', '_dummy2', 0 ],
1191 ApiResult
::META_TYPE
=> 'array',
1194 '_dummy' => 'foobaz',
1196 '_dummy2' => 'foobaz!',
1202 [ 'Strip' => 'bc' ],
1207 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
1208 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
1212 '_dummy2' => 'foobaz!',
1213 ApiResult
::META_SUBELEMENTS
=> [ 'foo', 'bar' ],
1214 ApiResult
::META_INDEXED_TAG_NAME
=> 'itn',
1226 ApiResult
::META_CONTENT
=> 'foo',
1227 ApiResult
::META_PRESERVE_KEYS
=> [ '_dummy2', '_dummy3' ],
1230 'Custom' => [ $this, 'customTransform' ],
1238 'baz' => [ 'a', 'b' ],
1239 '_dummy2' => '_DUMMY2',
1240 '_dummy3' => '_DUMMY3',
1241 ApiResult
::META_CONTENT
=> 'bar',
1246 'Types: Numeric keys in array and BCarray',
1254 ApiResult
::META_TYPE
=> 'array'
1262 ApiResult
::META_TYPE
=> 'BCarray'
1267 'array' => [ 'd', 'e', 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
1268 'BCarray' => [ 'd', 'e', 'b', 'c', 'a', ApiResult
::META_TYPE
=> 'array' ],
1269 ApiResult
::META_TYPE
=> 'assoc',
1276 * Custom transformer for testTransformations
1277 * @param array &$data
1278 * @param array &$metadata
1280 public function customTransform( &$data, &$metadata ) {
1281 // Prevent recursion
1282 if ( isset( $metadata['_added'] ) ) {
1283 $metadata[ApiResult
::META_TYPE
] = 'array';
1287 foreach ( $data as $k => $v ) {
1288 $data[$k] = strtoupper( $k );
1290 $data['baz'] = [ '_added' => 1, 'z' => 'b', 'y' => 'a' ];
1291 $metadata[ApiResult
::META_PRESERVE_KEYS
][0] = '_dummy';
1292 $data[ApiResult
::META_CONTENT
] = 'bar';
1296 * @covers \MediaWiki\Api\ApiResult
1298 public function testAddMetadataToResultVars() {
1303 'sequential_numeric_keys' => [ 'a', 'b', 'c' ],
1304 'non_sequential_numeric_keys' => [ 'a', 'b', 4 => 'c' ],
1309 'object_sequential_keys' => (object)[ 'a', 'b', 'c' ],
1310 '_type' => "should be overwritten in result",
1312 $this->assertSame( [
1313 ApiResult
::META_TYPE
=> 'kvp',
1314 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1315 ApiResult
::META_PRESERVE_KEYS
=> [
1317 'sequential_numeric_keys', 'non_sequential_numeric_keys',
1318 'string_keys', 'object_sequential_keys'
1320 ApiResult
::META_BC_BOOLS
=> [ 'b' ],
1321 ApiResult
::META_INDEXED_TAG_NAME
=> 'var',
1325 'sequential_numeric_keys' => [
1326 ApiResult
::META_TYPE
=> 'array',
1327 ApiResult
::META_BC_BOOLS
=> [],
1328 ApiResult
::META_INDEXED_TAG_NAME
=> 'value',
1333 'non_sequential_numeric_keys' => [
1334 ApiResult
::META_TYPE
=> 'kvp',
1335 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1336 ApiResult
::META_PRESERVE_KEYS
=> [ 0, 1, 4 ],
1337 ApiResult
::META_BC_BOOLS
=> [],
1338 ApiResult
::META_INDEXED_TAG_NAME
=> 'var',
1344 ApiResult
::META_TYPE
=> 'kvp',
1345 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1346 ApiResult
::META_PRESERVE_KEYS
=> [ 'one', 'two' ],
1347 ApiResult
::META_BC_BOOLS
=> [],
1348 ApiResult
::META_INDEXED_TAG_NAME
=> 'var',
1352 'object_sequential_keys' => [
1353 ApiResult
::META_TYPE
=> 'kvp',
1354 ApiResult
::META_KVP_KEY_NAME
=> 'key',
1355 ApiResult
::META_PRESERVE_KEYS
=> [ 0, 1, 2 ],
1356 ApiResult
::META_BC_BOOLS
=> [],
1357 ApiResult
::META_INDEXED_TAG_NAME
=> 'var',
1362 ], ApiResult
::addMetadataToResultVars( $arr ) );
1365 public function testObjectSerialization() {
1367 ApiResult
::setValue( $arr, 'foo', (object)[ 'a' => 1, 'b' => 2 ] );
1368 $this->assertSame( [
1371 ApiResult
::META_TYPE
=> 'assoc',
1375 ApiResult
::setValue( $arr, 'foo', new ApiResultTestStringifiableObject() );
1376 $this->assertSame( 'Ok', $arr['foo'] );
1379 ApiResult
::setValue( $arr, 'foo', new ApiResultTestSerializableObject( 'Ok' ) );
1380 $this->assertSame( 'Ok', $arr['foo'] );
1384 ApiResult
::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
1385 new ApiResultTestStringifiableObject()
1387 $this->fail( 'Expected exception not thrown' );
1388 } catch ( UnexpectedValueException
$ex ) {
1390 'MediaWiki\Tests\Api\ApiResultTestSerializableObject::serializeForApiResult() ' .
1391 'returned an object of class MediaWiki\Tests\Api\ApiResultTestStringifiableObject',
1393 'Expected exception'
1399 ApiResult
::setValue( $arr, 'foo', new ApiResultTestSerializableObject( NAN
) );
1400 $this->fail( 'Expected exception not thrown' );
1401 } catch ( UnexpectedValueException
$ex ) {
1403 'MediaWiki\Tests\Api\ApiResultTestSerializableObject::serializeForApiResult() ' .
1404 'returned an invalid value: Cannot add non-finite floats to ApiResult',
1406 'Expected exception'
1411 ApiResult
::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
1413 'one' => new ApiResultTestStringifiableObject( '1' ),
1414 'two' => new ApiResultTestSerializableObject( 2 ),
1417 $this->assertSame( [
1424 class ApiResultTestStringifiableObject
implements Stringable
{
1428 public function __construct( $ret = 'Ok' ) {
1432 public function __toString() {
1437 #[AllowDynamicProperties]
1438 class ApiResultTestSerializableObject
implements Stringable
{
1442 public function __construct( $ret ) {
1446 public function __toString() {
1450 public function serializeForApiResult() {