-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/client spec constraint tests #116
Conversation
This makes us ignore the constraint if the constraint operator is unknown.
If input data to a constraint is missing, then its always not present in a set. Nothing is not a part of anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me but give me a bit of time to double check the client spec tests, this got crazy and I want to make sure we aren't crazy too
Okay, never mind, looked over the client spec, this does look correct and the failing client spec test cases are because... well... nothing can't be in anything - i.e. this is isolated to the oddities of the IN/NOT_IN operators The remaining failures are due to global constraints not being implemented and should be closed by #114 |
Pull Request Test Coverage Report for Build 3020655652
💛 - Coveralls |
Pull Request Test Coverage Report for Build 3036905670
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looks good but can we make Rubocop happy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left some suggestions.
but as @sighphyre commented, rubocop doesn't seem quite happy yet.
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I found a corner case that needs to be looked at, plus some other general comments.
lib/unleash/constraint.rb
Outdated
# when the operator is NOT_IN and there is no data, return true. In all other cases the operator doesn't match. | ||
return true if operator == :NOT_IN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think about it again, this seems to belong in matches_constraint? Method and not in the matches_context?
So for this operator the matches_constraint? Should not throw an exception. (But still should for all other operators).
Also note that this doesn't seem to respect the inverted method parameter. Noting it up the stack should solve that. But maybe add a trivial assert for NOT using the inverted parameter (in addition to the current one using)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest commit should solve all of this. The reversing happens in matches_context and in matches_constraint we are now handling the nil values.
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some more feedback. It is looking promising!
lib/unleash/constraint.rb
Outdated
# when the operator is NOT_IN and there is no data, return true. In all other cases the operator doesn't match. | ||
return self.operator == :NOT_IN unless context.property?(self.context_name) | ||
|
||
Unleash.logger.debug "Unleash::Constraint matches_context? value: #{self.value} context.get_by_name(#{self.context_name})" \ | ||
" #{context.get_by_name(self.context_name)} " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should switch order here, and rename the method name within the log message / rewrite it to the log messages current context.
# when the operator is NOT_IN and there is no data, return true. In all other cases the operator doesn't match. | |
return self.operator == :NOT_IN unless context.property?(self.context_name) | |
Unleash.logger.debug "Unleash::Constraint matches_context? value: #{self.value} context.get_by_name(#{self.context_name})" \ | |
" #{context.get_by_name(self.context_name)} " | |
Unleash.logger.debug "Unleash::Constraint matches_constraint? value: #{self.value} constraint: #{self.operator} context.get_by_name(#{self.context_name})" \ | |
" #{context.get_by_name(self.context_name)} " | |
# when the operator is NOT_IN and there is no data, return true. In all other cases the operator doesn't match. | |
return self.operator == :NOT_IN unless context.property?(self.context_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cant log it before we validate that it is set. This is the reason the log is behind the check if property is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not? context.get_by_name()
should return nil if no value is found.
We would like to get this debug message for all operators, including the :NOT_IN
, and even if the value is not in the context.
Also the node regarding having matches_constraint?
instead of matches_context?
within the log message is still valid.
spec/unleash/constraint_spec.rb
Outdated
Unleash::Constraint.new('env', operator_name, '') | ||
end.to raise_error | ||
expect(Unleash.logger).to receive(:warn).with("value is a String, operator is expecting an Array") | ||
Unleash::Constraint.new('env', operator_name, '') | ||
end | ||
|
||
string_constraints = ['NUM_EQ', 'NUM_GT', 'NUM_GTE', 'NUM_LT', 'NUM_LTE', | ||
'DATE_AFTER', 'DATE_BEFORE', 'SEMVER_EQ', 'SEMVER_GT', 'SEMVER_LT'] | ||
string_constraints.each do |operator_name| | ||
Unleash::Constraint.new('env', operator_name, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to test that the creation of the object succeeded w/o an exception anymore. It now should be a safe assumption.
Unleash::Constraint.new('env', operator_name, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this test based on review you had earlier. Its not testing the object creation, its checking that unleash logs a warn message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have two Unleash::Constraint.new
in this test (per operator_name
). We only need to test the "sad" path, that the logger is getting called. No need to test the happy path....
That is at least what I meant to say.
spec/unleash/constraint_spec.rb
Outdated
expect(constraint.matches_context?(context)).to be true | ||
end | ||
|
||
it 'warns about constraint construction for invalid value types for operator' do | ||
array_constraints = ['STR_CONTAINS', 'STR_ENDS_WITH', 'STR_STARTS_WITH', 'IN', 'NOT_IN'] | ||
|
||
array_constraints.each do |operator_name| | ||
Unleash::Constraint.new('env', operator_name, []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to test that the creation of the object succeeded w/o an exception anymore. It now should be a safe assumption.
Unleash::Constraint.new('env', operator_name, []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this test based on review you had earlier. Its not testing the object creation, its checking that unleash logs a warn message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have two Unleash::Constraint.new
in this test (per operator_name
). We only need to test the "sad" path, that the logger is getting called. No need to test the happy path....
That is at least what I meant to say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, done.
Co-authored-by: Renato Arruda <rarruda@rarruda.org>
This reverts commit a8c65ac.
spec/unleash/constraint_spec.rb
Outdated
expect(constraint.matches_context?(context)).to be true | ||
end | ||
|
||
it 'warns about constraint construction for invalid value types for operator' do | ||
array_constraints = ['STR_CONTAINS', 'STR_ENDS_WITH', 'STR_STARTS_WITH', 'IN', 'NOT_IN'] | ||
|
||
array_constraints.each do |operator_name| | ||
Unleash::Constraint.new('env', operator_name, []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have two Unleash::Constraint.new
in this test (per operator_name
). We only need to test the "sad" path, that the logger is getting called. No need to test the happy path....
That is at least what I meant to say.
spec/unleash/constraint_spec.rb
Outdated
Unleash::Constraint.new('env', operator_name, '') | ||
end.to raise_error | ||
expect(Unleash.logger).to receive(:warn).with("value is a String, operator is expecting an Array") | ||
Unleash::Constraint.new('env', operator_name, '') | ||
end | ||
|
||
string_constraints = ['NUM_EQ', 'NUM_GT', 'NUM_GTE', 'NUM_LT', 'NUM_LTE', | ||
'DATE_AFTER', 'DATE_BEFORE', 'SEMVER_EQ', 'SEMVER_GT', 'SEMVER_LT'] | ||
string_constraints.each do |operator_name| | ||
Unleash::Constraint.new('env', operator_name, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have two Unleash::Constraint.new
in this test (per operator_name
). We only need to test the "sad" path, that the logger is getting called. No need to test the happy path....
That is at least what I meant to say.
lib/unleash/constraint.rb
Outdated
# when the operator is NOT_IN and there is no data, return true. In all other cases the operator doesn't match. | ||
return self.operator == :NOT_IN unless context.property?(self.context_name) | ||
|
||
Unleash.logger.debug "Unleash::Constraint matches_context? value: #{self.value} context.get_by_name(#{self.context_name})" \ | ||
" #{context.get_by_name(self.context_name)} " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not? context.get_by_name()
should return nil if no value is found.
We would like to get this debug message for all operators, including the :NOT_IN
, and even if the value is not in the context.
Also the node regarding having matches_constraint?
instead of matches_context?
within the log message is still valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woot!
This makes us pass the test cases for constraints in:
https://github.com/Unleash/client-specification/blob/main/specifications/13-constraint-operators.json