determinator 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d7789a1dadc2dd7a112279b38edf04c2c6c1e908dc70f28667f030653207e10
4
- data.tar.gz: 8b25552108ae67607d973e16354f4606ff709c72a6b88d426e6b55e5348383f7
3
+ metadata.gz: 64d1088dbb10e6ed41b2d1b03f381eb97ad45ffeeb44d44cbb4cd86c16f37eab
4
+ data.tar.gz: 051e42e160577f2d18bbe400ef65316a72e7208aa04fb7afdb56593ff675d347
5
5
  SHA512:
6
- metadata.gz: e0cb8a958af21db56878a78072b649f9e53ca27b688868255fab271bb6cfc99e20737df479bb08d4cdee89050c096843cd57a28eaf45bfaefd6113abcb25427f
7
- data.tar.gz: 16d0337dbaf25238c0f095498df13df9d4ba37b0aa7319c108d5bc05d11e2d582adeadceef7ce7b2e04839ed38c32ac85f7e23118a8a74ad18cac0bf9065e350
6
+ metadata.gz: ad601db1e2572791c02d691407d7f70e8a7c089b80d81308cb3249b69f2d74e62821b0a3019115abca8468dd20de845005f3a65ef0a03718e3d8ef2497deb373
7
+ data.tar.gz: db770901187876e66202799c2672cb991e0856d26ff87ace117e2d33637421d4b6103833bec91ec1708c6376421727a27be20a0f116acfd9e94c9ab21fc8e309
data/.gitignore CHANGED
@@ -7,4 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
- *.gem
10
+ *.gem
11
+ /.idea/
@@ -1,3 +1,8 @@
1
+ # v2.3.0 (2019-09-06)
2
+
3
+ Feature:
4
+ - `RSpec::Determinator` can apply `app_version` constraints but no longer supports multiple `forced_determination` calls on the same feature. [See the PR for an in-depth write-up.](https://github.com/deliveroo/determinator/pull/63)
5
+
1
6
  # v2.2.1 (2019-07-29)
2
7
 
3
8
  Bug fix:
@@ -1,6 +1,7 @@
1
1
  require 'digest/md5'
2
2
  require 'determinator/actor_control'
3
3
  require 'semantic'
4
+ require 'securerandom'
4
5
 
5
6
  module Determinator
6
7
  class Control
@@ -0,0 +1,27 @@
1
+ module Determinator
2
+ module Retrieve
3
+
4
+ # An retriever that returns features that were previously stored
5
+ # in the retriever. Useful for testing.
6
+ class InMemoryRetriever
7
+ def initialize
8
+ @features = {}
9
+ end
10
+
11
+ # @param name [string,symbol] The name of the feature to retrieve
12
+ def retrieve(name)
13
+ @features[name.to_s]
14
+ end
15
+
16
+ # @param feature [Determinator::Feature] The feature to store
17
+ def store(feature)
18
+ @features[feature.name] = feature
19
+ end
20
+
21
+ def clear!
22
+ @features.clear
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Determinator
2
- VERSION = '2.2.1'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -1,13 +1,22 @@
1
1
  require 'determinator'
2
+ require_relative '../determinator/retrieve/in_memory_retriever'
2
3
 
3
4
  module RSpec
4
5
  module Determinator
5
6
  def self.included(by)
6
7
  by.extend(DSL)
7
8
 
8
- by.let(:fake_determinator) { FakeControl.new }
9
- by.before do
10
- allow(::Determinator).to receive(:instance).and_return(fake_determinator)
9
+ by.let(:fake_retriever) { ::Determinator::Retrieve::InMemoryRetriever.new }
10
+ by.let(:fake_determinator) { ::RSpec::Determinator::FakeDeterminator.new(fake_retriever) }
11
+ by.around do |example|
12
+ old_retriever = ::Determinator.instance.retrieval
13
+ begin
14
+ fake_retriever.clear!
15
+ ::Determinator.configure(retrieval: fake_retriever)
16
+ example.run
17
+ ensure
18
+ ::Determinator.configure(retrieval: old_retriever)
19
+ end
11
20
  end
12
21
  end
13
22
 
@@ -18,62 +27,59 @@ module RSpec
18
27
  # If `outcome` or `only_for` are Symbols then the example-scoped variable of that name will be referenced (ie. those
19
28
  # variables created by `let` declarations)
20
29
  #
21
- # @params name [#to_s] The name of the Feature Flag or Experiment to mock
22
- # @params outcome [Boolean,String,Symbol] The outcome which should be supplied. Will look up an example variable if a Symbol is given.
23
- # @params :only_for [Hash,Symbol] The constraints that must be matched exactly in order for the determination to be applied.
24
- def forced_determination(name, outcome, only_for: {})
30
+ # @param [String,Symbol] name The name of the Feature Flag or Experiment to mock
31
+ # @param [Boolean,String,Symbol] outcome The outcome which should be supplied. Will look up an example variable if a Symbol is given.
32
+ # @param [Hash,Symbol] :only_for The constraints that must be matched exactly in order for the determination to be applied.
33
+ def forced_determination(name, outcome, bucket_type: 'single', only_for: {})
25
34
  before do
26
35
  outcome = send(outcome) if outcome.is_a?(Symbol)
27
36
  only_for = send(only_for) if only_for.is_a?(Symbol)
28
37
 
29
- fake_determinator.mock_result(
38
+ ::RSpec::Determinator::FakeDeterminator.new(fake_retriever).mock_result(
30
39
  name,
31
40
  outcome,
41
+ bucket_type: bucket_type,
32
42
  only_for: only_for
33
43
  )
34
44
  end
35
45
  end
36
- end
37
-
38
- class FakeControl
39
- def initialize
40
- @mocked_results = Hash.new { |h, k| h[k] = {} }
41
- end
42
46
 
43
- def for_actor(**args)
44
- ::Determinator::ActorControl.new(self, **args)
45
- end
46
-
47
- def mock_result(name, result, only_for: {})
48
- @mocked_results[name.to_s][normalize_properties(only_for)] = result
49
- end
50
-
51
- def fake_determinate(name, id: nil, guid: nil, properties: {})
52
- properties[:id] = id if id
53
- properties[:guid] = guid if guid
47
+ end
54
48
 
55
- outcome_for_feature_given_properties(name.to_s, normalize_properties(properties))
49
+ class FakeDeterminator
50
+ def initialize(in_memory_retriever)
51
+ @retriever = in_memory_retriever
56
52
  end
57
- alias_method :feature_flag_on?, :fake_determinate
58
- alias_method :which_variant, :fake_determinate
59
-
60
- private
61
53
 
62
- def outcome_for_feature_given_properties(feature_name, requirements)
63
- req_array = requirements.to_a
54
+ VALID_BUCKET_TYPES = %w{ id guid single }.freeze
64
55
 
65
- keys_in_priority_order = @mocked_results[feature_name].keys.reverse
66
- key = keys_in_priority_order.find do |given|
67
- (given.to_a - req_array).empty?
56
+ def mock_result(name, outcome, bucket_type: 'single', only_for: {})
57
+ if !VALID_BUCKET_TYPES.include?(bucket_type)
58
+ raise ArgumentError.new("bad bucket type #{bucket_type}, expected one of: #{VALID_BUCKET_TYPES.join(' ')}")
68
59
  end
69
60
 
70
- @mocked_results[feature_name][key] || false
71
- end
61
+ active = !!outcome
62
+ variants = case outcome
63
+ when true, false then
64
+ []
65
+ else
66
+ { outcome => 1 }
67
+ end
68
+ target_group = ::Determinator::TargetGroup.new(
69
+ rollout: 65_536,
70
+ constraints: only_for.map { |key, value| [key.to_s, Array(value).map(&:to_s)] }.to_h
71
+ )
72
72
 
73
- def normalize_properties(properties)
74
- properties.each_with_object({}) do |(key, value), hash|
75
- hash[key.to_s] = [*value].map(&:to_s)
76
- end
73
+ feature = ::Determinator::Feature.new(
74
+ name: name.to_s,
75
+ identifier: name.to_s,
76
+ bucket_type: bucket_type,
77
+ active: active,
78
+ variants: variants,
79
+ target_groups: [target_group]
80
+ )
81
+
82
+ @retriever.store(feature)
77
83
  end
78
84
  end
79
85
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: determinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JP Hastings-Spital
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-29 00:00:00.000000000 Z
11
+ date: 2019-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -198,6 +198,7 @@ files:
198
198
  - lib/determinator/retrieve/dynaconf.rb
199
199
  - lib/determinator/retrieve/file.rb
200
200
  - lib/determinator/retrieve/http_retriever.rb
201
+ - lib/determinator/retrieve/in_memory_retriever.rb
201
202
  - lib/determinator/retrieve/null_retriever.rb
202
203
  - lib/determinator/serializers/json.rb
203
204
  - lib/determinator/target_group.rb
@@ -222,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
223
  - !ruby/object:Gem::Version
223
224
  version: '0'
224
225
  requirements: []
225
- rubygems_version: 3.0.4
226
+ rubygems_version: 3.0.3
226
227
  signing_key:
227
228
  specification_version: 4
228
229
  summary: Determine which experiments and features a specific actor should see.