$resources Mapping of schema IDs to local files, * to avoid loading schemas over the network during testing. */ private function assertMatchesJsonSchema( $schema, $json, array $resources = [] ): void { if ( is_string( $json ) ) { try { $json = json_decode( $json, false, JSON_THROW_ON_ERROR ); } catch ( JsonException $ex ) { self::fail( 'Invalid JSON: ' . $ex->getMessage() ); } } if ( is_string( $schema ) ) { // Let the JsonException propagate, this indicates a bug in the test, // not a test failure. $schema = self::loadJsonData( $schema ); } $factory = new Factory(); foreach ( $resources as $id => $rc ) { $factory->getSchemaStorage()->addSchema( rtrim( $id, '#' ), self::loadJsonData( $rc ) ); } $validator = new Validator( $factory ); $validator->validate( $json, $schema, Constraint::CHECK_MODE_TYPE_CAST ); if ( !$validator->isValid() ) { foreach ( $validator->getErrors() as $error ) { $error = json_encode( $error ); self::fail( "JSON schema validation failed: $error" ); } } $this->addToAssertionCount( 1 ); } /** * Validate a JSON schema. * * Currently only works for schemas that match Draft-4. * * @param array $schema The schema to validate. * @throws LogicException if the schema is invalid */ public function assertValidJsonSchema( array $schema ): void { // Load the draft-04 schema from the local file $metaSchema = MW_INSTALL_PATH . '/vendor/justinrainbow/json-schema/dist/' . 'schema/json-schema-draft-04.json'; self::assertMatchesJsonSchema( $metaSchema, $schema ); } }