Skip to content

Commit 5b154ca

Browse files
emyllerclaude
andauthored
fix: Align numeric trait conditions with flagsmith-engine (#118)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 51544ab commit 5b154ca

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

‎lib/flagsmith/engine/segments/models.rb‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ class Condition
4242
LESS_THAN => ->(other_value, self_value) { (other_value || false) && other_value < self_value },
4343
LESS_THAN_INCLUSIVE => ->(other_value, self_value) { (other_value || false) && other_value <= self_value },
4444
NOT_EQUAL => ->(other_value, self_value) { other_value != self_value },
45-
CONTAINS => ->(other_value, self_value) { (other_value || false) && other_value.include?(self_value) },
45+
CONTAINS => ->(other_value, self_value) { other_value.is_a?(String) && other_value.include?(self_value) },
4646

47-
NOT_CONTAINS => ->(other_value, self_value) { (other_value || false) && !other_value.include?(self_value) },
47+
NOT_CONTAINS => ->(other_value, self_value) { other_value.is_a?(String) && !other_value.include?(self_value) },
4848
REGEX => ->(other_value, self_value) { (other_value || false) && other_value.to_s.match?(self_value) }
4949
}.freeze
5050

@@ -77,21 +77,17 @@ def match_with_type_conversion(trait_value)
7777
type_as_trait_value = format_to_type_of(trait_value)
7878
formatted_value = type_as_trait_value ? type_as_trait_value.call(@value) : @value
7979
MATCHING_FUNCTIONS[operator]&.call(trait_value, formatted_value)
80+
rescue ArgumentError # Rule value not coercible to the trait value's type, e.g. 2 > '1.5'
81+
false
8082
end
8183

8284
TYPE_CONVERTERS = {
8385
'String' => ->(v) { v.to_s },
8486
'Semantic::Version' => ->(v) { Semantic::Version.new(v.to_s.gsub(/:semver$/, '')) },
8587
'TrueClass' => ->(v) { ['True', 'true', 'TRUE', true, 1, '1'].include?(v) },
8688
'FalseClass' => ->(v) { !['False', 'false', 'FALSE', false].include?(v) },
87-
'Integer' => lambda { |v|
88-
i = v.to_i
89-
i.to_s == v.to_s ? i : v
90-
},
91-
'Float' => lambda { |v|
92-
f = v.to_f
93-
f.to_s == v.to_s ? f : v
94-
}
89+
'Integer' => ->(v) { Integer(v.to_s, 10) },
90+
'Float' => ->(v) { Float(v.to_s) }
9591
}.freeze
9692

9793
def format_to_type_of(input)

‎spec/engine/unit/segments/models_spec.rb‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,43 @@
1313
['EQUAL', true, 'false', false],
1414
['EQUAL', 1.23, '1.23', true],
1515
['EQUAL', 1.23, '4.56', false],
16+
['EQUAL', 1.0, '1', true],
1617
['GREATER_THAN', nil, '1', false],
1718
['GREATER_THAN', 2, '1', true],
1819
['GREATER_THAN', 1, '1', false],
1920
['GREATER_THAN', 0, '1', false],
2021
['GREATER_THAN', 2.1, '2.0', true],
2122
['GREATER_THAN', 2.1, '2.1', false],
2223
['GREATER_THAN', 2.0, '2.1', false],
24+
['GREATER_THAN', 2.1, '2', true],
25+
['GREATER_THAN', 2, '1.5', false],
2326
['GREATER_THAN_INCLUSIVE', nil, '1', false],
2427
['GREATER_THAN_INCLUSIVE', 2, '1', true],
2528
['GREATER_THAN_INCLUSIVE', 1, '1', true],
2629
['GREATER_THAN_INCLUSIVE', 0, '1', false],
2730
['GREATER_THAN_INCLUSIVE', 2.1, '2.0', true],
2831
['GREATER_THAN_INCLUSIVE', 2.1, '2.1', true],
2932
['GREATER_THAN_INCLUSIVE', 2.0, '2.1', false],
33+
['GREATER_THAN_INCLUSIVE', 2.0, '2', true],
34+
['GREATER_THAN_INCLUSIVE', 2, '1.5', false],
3035
['LESS_THAN', nil, '2', false],
3136
['LESS_THAN', 1, '2', true],
3237
['LESS_THAN', 1, '1', false],
3338
['LESS_THAN', 1, '0', false],
3439
['LESS_THAN', 2.0, '2.1', true],
3540
['LESS_THAN', 2.1, '2.1', false],
3641
['LESS_THAN', 2.1, '2.0', false],
42+
['LESS_THAN', 1.9, '2', true],
43+
['LESS_THAN', 1, '1.5', false],
3744
['LESS_THAN_INCLUSIVE', nil, '2', false],
3845
['LESS_THAN_INCLUSIVE', 1, '2', true],
3946
['LESS_THAN_INCLUSIVE', 1, '1', true],
4047
['LESS_THAN_INCLUSIVE', 1, '0', false],
4148
['LESS_THAN_INCLUSIVE', 2.0, '2.1', true],
4249
['LESS_THAN_INCLUSIVE', 2.1, '2.1', true],
4350
['LESS_THAN_INCLUSIVE', 2.1, '2.0', false],
51+
['LESS_THAN_INCLUSIVE', 2.0, '2', true],
52+
['LESS_THAN_INCLUSIVE', 1, '1.5', false],
4453
['NOT_EQUAL', 'bar', 'baz', true],
4554
['NOT_EQUAL', 'bar', 'bar', false],
4655
['NOT_EQUAL', 1, '2', true],
@@ -49,14 +58,19 @@
4958
['NOT_EQUAL', false, 'true', true],
5059
['NOT_EQUAL', false, 'false', false],
5160
['NOT_EQUAL', true, 'true', false],
61+
['NOT_EQUAL', 95, '90.5', false],
62+
['NOT_EQUAL', 1, 'foo', false],
63+
['NOT_EQUAL', 1.5, 'foo', false],
5264
['CONTAINS', nil, 'b', false],
5365
['CONTAINS', 'bar', 'b', true],
5466
['CONTAINS', 'bar', 'bar', true],
5567
['CONTAINS', 'bar', 'baz', false],
68+
['CONTAINS', 95, '9', false],
5669
['NOT_CONTAINS', nil, 'b', false],
5770
['NOT_CONTAINS', 'bar', 'b', false],
5871
['NOT_CONTAINS', 'bar', 'bar', false],
5972
['NOT_CONTAINS', 'bar', 'baz', true],
73+
['NOT_CONTAINS', 95, 'abc', false],
6074
['REGEX', nil, /[a-z]+/, false],
6175
['REGEX', 'foo', /[a-z]+/, true],
6276
['REGEX', 'FOO', /[a-z]+/, false],

0 commit comments

Comments
 (0)