File: feature_spec.rb

package info (click to toggle)
ruby-feature 1.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 184 kB
  • sloc: ruby: 760; sh: 20; makefile: 9
file content (231 lines) | stat: -rw-r--r-- 6,960 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
require 'spec_helper'

describe Feature do
  context 'without FeatureRepository' do
    it 'should raise an exception when calling active?' do
      expect do
        Feature.active?(:feature_a)
      end.to raise_error('missing Repository for obtaining feature lists')
    end

    it 'should raise an exception when calling inactive?' do
      expect do
        Feature.inactive?(:feature_a)
      end.to raise_error('missing Repository for obtaining feature lists')
    end

    it 'should raise an exception when calling with' do
      expect do
        Feature.with(:feature_a) do
        end
      end.to raise_error('missing Repository for obtaining feature lists')
    end

    it 'should raise an exception when calling without' do
      expect do
        Feature.without(:feature_a) do
        end
      end.to raise_error('missing Repository for obtaining feature lists')
    end

    it 'should raise an exception when calling active_features' do
      expect do
        Feature.active_features
      end.to raise_error('missing Repository for obtaining feature lists')
    end
  end

  context 'setting Repository' do
    before(:each) do
      @repository = Feature::Repository::SimpleRepository.new
    end

    context 'with auto_refresh set to false' do
      before(:each) do
        Feature.set_repository @repository
      end
      it 'should raise an exception when add repository with wrong class' do
        expect do
          Feature.set_repository('not a repository')
        end.to raise_error(ArgumentError, 'given repository does not respond to active_features')
      end

      it 'should get active features lazy on first usage' do
        @repository.add_active_feature(:feature_a)
        # the line below will be the first usage of feature in this case
        expect(Feature.active?(:feature_a)).to be_truthy
      end

      it 'should get active features from repository once' do
        Feature.active?(:does_not_matter)
        @repository.add_active_feature(:feature_a)
        expect(Feature.active?(:feature_a)).to be_falsey
      end

      it 'should reload active features on first call only' do
        @repository.add_active_feature(:feature_a)
        expect(@repository).to receive(:active_features).once.and_return(@repository.active_features)
        Feature.active?(:feature_a)
        Feature.active?(:feature_a)
      end
    end

    context 'with auto_refresh set to true' do
      before(:each) do
        Feature.set_repository @repository, true
      end
      it 'should reload active features on every call' do
        @repository.add_active_feature(:feature_a)
        expect(@repository).to receive(:active_features).twice.and_return(@repository.active_features)
        Feature.active?(:feature_a)
        Feature.active?(:feature_a)
      end
    end

    context 'with timeout set to 30 seconds' do
      before(:each) do
        Timecop.freeze(Time.now)
        Feature.set_repository @repository, 30
        @repository.add_active_feature(:feature_a)
        Feature.active?(:feature_a)
      end

      after(:each) do
        Timecop.return
      end

      it 'should not update after 10 seconds' do
        Timecop.freeze(Time.now + 10)
        expect(@repository).not_to receive(:active_features)
        Feature.active?(:feature_a)
      end

      it 'should update after 40 seconds' do
        Timecop.freeze(Time.now + 40)
        expect(@repository).to receive(:active_features).and_return(@repository.active_features)
        Feature.active?(:feature_a)
      end
    end
  end

  context 'refresh features' do
    before(:each) do
      @repository = Feature::Repository::SimpleRepository.new
      Feature.set_repository @repository
    end

    it 'should refresh active feature lists from repository' do
      @repository.add_active_feature(:feature_a)
      Feature.refresh!
      expect(Feature.active?(:feature_a)).to be_truthy
    end
  end

  context 'request features' do
    before(:each) do
      repository = Feature::Repository::SimpleRepository.new
      repository.add_active_feature :feature_active
      Feature.set_repository repository
    end

    it 'should affirm active feature is active' do
      expect(Feature.active?(:feature_active)).to be_truthy
    end

    it 'should not affirm active feature is inactive' do
      expect(Feature.inactive?(:feature_active)).to be_falsey
    end

    it 'should affirm inactive feature is inactive' do
      expect(Feature.inactive?(:feature_inactive)).to be_truthy
    end

    it 'should not affirm inactive feature is active' do
      expect(Feature.active?(:feature_inactive)).to be_falsey
    end

    it 'should call block with active feature in active list' do
      reached = false

      Feature.with(:feature_active) do
        reached = true
      end

      expect(reached).to be_truthy
    end

    it 'should not call block with active feature not in active list' do
      reached = false

      Feature.with(:feature_inactive) do
        reached = true
      end

      expect(reached).to be_falsey
    end

    it 'should raise exception when no block given to with' do
      expect do
        Feature.with(:feature_active)
      end.to raise_error(ArgumentError, 'no block given to with')
    end

    it 'should call block without inactive feature in inactive list' do
      reached = false

      Feature.without(:feature_inactive) do
        reached = true
      end

      expect(reached).to be_truthy
    end

    it 'should not call block without inactive feature in inactive list' do
      reached = false

      Feature.without(:feature_active) do
        reached = true
      end

      expect(reached).to be_falsey
    end

    it 'should raise exception when no block given to without' do
      expect do
        Feature.without(:feature_inactive)
      end.to raise_error(ArgumentError, 'no block given to without')
    end

    describe 'switch()' do
      context 'given a value' do
        it 'should return the first value if the feature is active' do
          retval = Feature.switch(:feature_active, 1, 2)
          expect(retval).to eq(1)
        end

        it 'should return the second value if the feature is inactive' do
          retval = Feature.switch(:feature_inactive, 1, 2)
          expect(retval).to eq(2)
        end
      end

      context 'given a proc/lambda' do
        it 'should call the first proc/lambda if the feature is active' do
          retval = Feature.switch(:feature_active, -> { 1 }, -> { 2 })
          expect(retval).to eq(1)
        end

        it 'should call the second proc/lambda if the feature is active' do
          retval = Feature.switch(:feature_inactive, -> { 1 }, -> { 2 })
          expect(retval).to eq(2)
        end
      end
    end

    describe 'active_features' do
      it 'should return an array of active feature flags' do
        expect(Feature.active_features).to eq([:feature_active])
      end
    end
  end
end