Support runtime exclusions in exclude matcher

Support runtime exclusions in exclude matcher

Add .when_executing chain method to the exclude matcher to enable testing of exclude! calls made inside experiment blocks.

This enhancement:

  • Adds .when_executing chain method that captures a block
  • Block is executed before checking exclusion state
  • Maintains backward compatibility (existing tests unchanged)
  • Only resets @_excluded when NOT testing runtime exclusions
  • Provides semantic testing for both declarative and runtime patterns

Usage:

Production code:

experiment(:premium_trial_positioning, actor: user) do |e|
  e.exclude! if user.admin?
  e.track(:assignment, namespace: group)
end

Before

Test - forced to test implementation:

it 'excludes admin users' do
  expect_any_instance_of(PremiumTrialPositioningExperiment) do |instance|
    expect(instance).to receive(:exclude!)
  end

  service.execute
end

After

Test - can test behavior:

it 'excludes admin users' do
  admin = create(:user, :admin)
  exp = experiment(:premium_trial_positioning, actor: admin)

  execute
  
  expect(exp).to exclude(actor: admin)
end

Note: Must use curly braces {} with .when_executing due to Ruby block precedence rules. do...end blocks will not work correctly.

Documentation updated with usage examples and best practices.

Closes #88

Edited by Doug Stull

Merge request reports

Loading