Module: Feature

Defined in:
lib/feature.rb,
lib/feature/testing.rb,
lib/feature/repository.rb,
lib/feature/repository/yaml_repository.rb,
lib/feature/repository/redis_repository.rb,
lib/feature/generators/install_generator.rb,
lib/feature/repository/simple_repository.rb,
lib/feature/repository/active_record_repository.rb

Overview

This file provides functionality for testing your code with features activated or deactivated. This file should only be required in test/spec code!

To enable Feature testing capabilities do:

require 'feature/testing'

Defined Under Namespace

Modules: Repository Classes: InstallGenerator

Class Method Summary collapse

Class Method Details

.active?(feature) ⇒ Boolean

Requests if feature is active

Parameters:

  • feature (Symbol)

Returns:

  • (Boolean)


60
61
62
63
64
65
66
# File 'lib/feature.rb', line 60

def self.active?(feature)
  fail 'missing Repository for obtaining feature lists' unless @repository

  refresh! if @auto_refresh || @perform_initial_refresh

  @active_features.include?(feature)
end

.inactive?(feature) ⇒ Boolean

Requests if feature is inactive (or unknown)

Parameters:

  • feature (Symbol)

Returns:

  • (Boolean)


73
74
75
# File 'lib/feature.rb', line 73

def self.inactive?(feature)
  !active?(feature)
end

.refresh!Object

Refreshes list of active features from repository. Useful when using an repository with external source.



49
50
51
52
# File 'lib/feature.rb', line 49

def self.refresh!
  @active_features = @repository.active_features
  @perform_initial_refresh = false
end

.run_with_activated(*features, &blk) ⇒ Object

Execute the code block with the given features active

Example usage:

Feature.run_with_activated(:feature, :another_feature) do
  # your test code here
end


16
17
18
19
20
21
22
23
# File 'lib/feature/testing.rb', line 16

def self.run_with_activated(*features, &blk)
  with_stashed_config do
    @active_features.concat(features).uniq!
    @auto_refresh = false
    @perform_initial_refresh = false
    blk.call
  end
end

.run_with_deactivated(*features, &blk) ⇒ Object

Execute the code block with the given features deactive

Example usage:

Feature.run_with_deactivated(:feature, :another_feature) do
  # your test code here
end


31
32
33
34
35
36
37
38
# File 'lib/feature/testing.rb', line 31

def self.run_with_deactivated(*features, &blk)
  with_stashed_config do
    @active_features -= features
    @auto_refresh = false
    @perform_initial_refresh = false
    blk.call
  end
end

.set_repository(repository, auto_refresh = false) ⇒ Object

Set the feature repository The given repository has to respond to method ‘active_features’ with an array of symbols

Parameters:

  • repository (Object)

    the repository to get the features from

  • auto_refresh (Boolean) (defaults to: false)

    optional (default: false) - refresh feature toggles on every check if set true



36
37
38
39
40
41
42
43
44
# File 'lib/feature.rb', line 36

def self.set_repository(repository, auto_refresh = false)
  unless repository.respond_to?(:active_features)
    fail ArgumentError, 'given repository does not respond to active_features'
  end

  @auto_refresh = auto_refresh
  @perform_initial_refresh = true
  @repository = repository
end

.switch(feature, l1, l2) ⇒ Object

Return value or execute Proc/lambda depending on Feature status.

Parameters:

  • feature (Symbol)
  • value (Object)

    / lambda to use if feature is active

  • value (Object)

    / lambda to use if feature is inactive



103
104
105
106
107
108
109
# File 'lib/feature.rb', line 103

def self.switch(feature, l1, l2)
  if active?(feature)
    l1.instance_of?(Proc) ? l1.call : l1
  else
    l2.instance_of?(Proc) ? l2.call : l2
  end
end

.with(feature) ⇒ Object

Execute the given block if feature is active

Parameters:

  • feature (Symbol)


81
82
83
84
85
# File 'lib/feature.rb', line 81

def self.with(feature)
  fail ArgumentError, "no block given to #{__method__}" unless block_given?

  yield if active?(feature)
end

.with_stashed_configObject

Execute the given code block and store + restore the feature configuration before/after the execution



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/feature/testing.rb', line 42

def self.with_stashed_config
  @active_features = [] if @active_features.nil?
  old_features = @active_features.dup
  old_auto_refresh = @auto_refresh
  old_perform_initial_refresh = @perform_initial_refresh
  yield
ensure
  @active_features = old_features
  @auto_refresh = old_auto_refresh
  @perform_initial_refresh = old_perform_initial_refresh
end

.without(feature) ⇒ Object

Execute the given block if feature is inactive

Parameters:

  • feature (Symbol)


91
92
93
94
95
# File 'lib/feature.rb', line 91

def self.without(feature)
  fail ArgumentError, "no block given to #{__method__}" unless block_given?

  yield if inactive?(feature)
end