expectException( \LogicException::class ); $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->registerSimpleRequirement( 'requirementA', true ); $featureManager->registerSimpleRequirement( 'requirementA', true ); } public static function provideInvalidFeatureConfig() { return [ // ::registerFeature( string, int[] ) will throw an exception. [ \Wikimedia\Assert\ParameterAssertionException::class, [ 1 ], ], // The "bar" requirement hasn't been registered. [ \InvalidArgumentException::class, [ 'bar', ], ], ]; } /** * @dataProvider provideInvalidFeatureConfig * @covers ::registerFeature */ public function testRegisterFeatureValidatesConfig( $expectedExceptionType, $config ) { $this->expectException( $expectedExceptionType ); $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->registerSimpleRequirement( 'requirement', true ); $featureManager->registerFeature( 'feature', $config ); } /** * @covers ::isRequirementMet */ public function testIsRequirementMet() { $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->registerSimpleRequirement( 'enabled', true ); $featureManager->registerSimpleRequirement( 'disabled', false ); $this->assertTrue( $featureManager->isRequirementMet( 'enabled' ) ); $this->assertFalse( $featureManager->isRequirementMet( 'disabled' ) ); } /** * @covers ::isRequirementMet */ public function testIsRequirementMetThrowsExceptionWhenRequirementIsntRegistered() { $this->expectException( \InvalidArgumentException::class ); $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->isRequirementMet( 'foo' ); } /** * @covers ::registerFeature */ public function testRegisterFeatureThrowsExceptionWhenFeatureIsRegisteredTwice() { $this->expectException( \LogicException::class ); $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->registerFeature( 'featureA', [] ); $featureManager->registerFeature( 'featureA', [] ); } /** * @covers ::isFeatureEnabled */ public function testIsFeatureEnabled() { $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->registerSimpleRequirement( 'foo', false ); $featureManager->registerFeature( 'requiresFoo', 'foo' ); $this->assertFalse( $featureManager->isFeatureEnabled( 'requiresFoo' ), 'A feature is disabled when the requirement that it requires is disabled.' ); // --- $featureManager->registerSimpleRequirement( 'bar', true ); $featureManager->registerSimpleRequirement( 'baz', true ); $featureManager->registerFeature( 'requiresFooBar', [ 'foo', 'bar' ] ); $featureManager->registerFeature( 'requiresBarBaz', [ 'bar', 'baz' ] ); $this->assertFalse( $featureManager->isFeatureEnabled( 'requiresFooBar' ), 'A feature is disabled when at least one requirement that it requires is disabled.' ); $this->assertTrue( $featureManager->isFeatureEnabled( 'requiresBarBaz' ) ); } /** * @covers ::isFeatureEnabled */ public function testIsFeatureEnabledThrowsExceptionWhenFeatureIsntRegistered() { $this->expectException( \InvalidArgumentException::class ); $featureManager = new FeatureManager( $this->createMock( UserOptionsLookup::class ), new RequestContext() ); $featureManager->isFeatureEnabled( 'foo' ); } }