Skip to content

Commit 70e59b9

Browse files
Add IS_SET and IS_NOT_SET segment operators (#20)
* Add IS_SET and IS_NOT_SET segment operators * Simplify logic and disable rubocop * Fix rubocop * make logic clearer * Update test wording
1 parent c53b90a commit 70e59b9

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

lib/flagsmith/engine/segments/constants.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module Constants
2222
NOT_EQUAL = 'NOT_EQUAL'
2323
REGEX = 'REGEX'
2424
PERCENTAGE_SPLIT = 'PERCENTAGE_SPLIT'
25+
IS_SET = 'IS_SET'
26+
IS_NOT_SET = 'IS_NOT_SET'
2527
MODULO = 'MODULO'
2628

2729
CONDITION_OPERATORS = [

lib/flagsmith/engine/segments/evaluator.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,22 @@ def traits_match_segment_condition(identity_traits, condition, segment_id, ident
5858

5959
trait = identity_traits.find { |t| t.key.to_s == condition.property }
6060

61-
return condition.match_trait_value?(trait.value) if trait
61+
if [IS_SET, IS_NOT_SET].include?(condition.operator)
62+
return handle_trait_existence_conditions(trait, condition.operator)
63+
end
64+
65+
return condition.match_trait_value?(trait.trait_value) if trait
6266

6367
false
6468
end
69+
70+
private
71+
72+
def handle_trait_existence_conditions(matching_trait, operator)
73+
return operator == IS_NOT_SET if matching_trait.nil?
74+
75+
operator == IS_SET
76+
end
6577
end
6678
end
6779
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
# list of test cases containing: operator, property, value, traits (list of dicts), expected_result
6+
TEST_CASES = [
7+
['IS_SET', 'foo', nil, {}, false],
8+
['IS_SET', 'foo', nil, {'foo': 'bar'}, true],
9+
['IS_NOT_SET', 'foo', nil, {}, true],
10+
['IS_NOT_SET', 'foo', nil, {'foo': 'bar'}, false],
11+
]
12+
13+
RSpec.describe Flagsmith::Engine::Segments::Evaluator do
14+
subject { Class.new { extend Flagsmith::Engine::Segments::Evaluator } }
15+
16+
TEST_CASES.each do |(operator, property, value, traits, expected_result)|
17+
it "traits: #{traits} #traits_match_segment_condition(#{operator}, #{property}, #{value || 'No value'}) should be #{expected_result}" do
18+
condition = Flagsmith::Engine::Segments::Condition.new(
19+
operator: operator, property: property, value: value
20+
)
21+
trait_models = traits.map {
22+
|k,v| Flagsmith::Engine::Identities::Trait.new(trait_key: k, trait_value: v)
23+
}
24+
25+
expect(subject.traits_match_segment_condition(
26+
trait_models, condition, 1, 1)).to eq(expected_result)
27+
end
28+
end
29+
end

spec/sdk/flagsmith_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
end
111111

112112
describe '#get_identity_segments' do
113-
it 'returns an empty list given an identity with no traits' do
113+
it 'returns an empty list given an identity which matches no segment conditions' do
114114
polling_manager = Flagsmith::EnvironmentDataPollingManager.new(subject, 60)
115115
subject.update_environment()
116116
expect(subject.get_identity_segments("identifier")).to eq([])

0 commit comments

Comments
 (0)