-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
fix(Slider): value may exceed max when step is large #13632
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
base: main
Are you sure you want to change the base?
Conversation
…t with the Chinese version under the English version
…y large, the component may return a value outside the max range.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #13632 +/- ##
==========================================
+ Coverage 89.60% 89.74% +0.14%
==========================================
Files 257 257
Lines 7013 7052 +39
Branches 1736 1746 +10
==========================================
+ Hits 6284 6329 +45
+ Misses 384 381 -3
+ Partials 345 342 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
chenjiahan
left a comment
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.
Thanks for your contribution! The code changes look good to me. However, the test code seems to have too many modifications and includes some unnecessary console.log statements. Could you simplify the test code a bit? (And make sure to use English for comments.)
Yes, Because the test coverage never reached 100%, the test was modified many times. I will make the necessary changes immediately. @chenjiahan |
|
If you’d like to help improve test coverage, feel free to submit a separate PR adding test cases — this will make the code review process easier. |
Okay, this test is already quite comprehensive. I will submit the simplified test code as you suggested shortly, and also remove the unnecessary console.log statements. It should take about 5 minutes. |
…y large, the component may return a value outside the max range test.
I have modified the test code to ensure there are no redundant console.logs. Please check it. Thank you. The test code is appended after the original test code to ensure that it does not affect the previous code. |
| if (steppedValue > max) { | ||
| const prevSteppedValue = addNumber(min, diff - step); | ||
| const distanceToMax = Math.abs(value - max); | ||
| const distanceToPrev = Math.abs(value - prevSteppedValue); | ||
|
|
||
| return distanceToMax <= distanceToPrev ? max : prevSteppedValue; | ||
| } |
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.
Under what circumstances would distanceToMax be greater than distanceToPrev?
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.
distanceToMax > distanceToPrev only occurs if prevSteppedValue is closer to value than max.
Specific conditions:
value must be between prevSteppedValue and max, and closer to prevSteppedValue.
Almost impossible
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.
Could you provide specific examples? Because it seems like the added unit tests don't cover it.
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 the added unit test cases are a bit excessive. In my opinion, it’s sufficient to add test cases for just two scenarios: distanceToMax <= distanceToPrev and distanceToMax > distanceToPrev.
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.
Could you provide specific examples? Because it seems like the added unit tests don't cover it.
@inottn Yes, in the description above I explained the problem of test coverage. Could you read it? #13632 (comment)
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 understand. What I mean is that the current PR adds 20 test cases, which seems excessive for a single fix. Refer to #13425 and #13008, for minor fixes, adding one or two test cases is usually sufficient. The changes involved in this fix aren't related to whether the Slider is in range or vertical mode. I think adding just 2 test cases would suffice—one to test the scenario where distanceToMax <= distanceToPrev, and another for distanceToMax > distanceToPrev.
We only need to ensure minimal test cases cover the logic of this fix, rather than increasing the test coverage of the entire component (which should be done in a separate PR).
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 understand. What I mean is that the current PR adds 20 test cases, which seems excessive for a single fix. Refer to #13425 and #13008, for minor fixes, adding one or two test cases is usually sufficient. The changes involved in this fix aren't related to whether the Slider is in range or vertical mode. I think adding just 2 test cases would suffice—one to test the scenario where distanceToMax <= distanceToPrev, and another for distanceToMax > distanceToPrev.
We only need to ensure minimal test cases cover the logic of this fix, rather than increasing the test coverage of the entire component (which should be done in a separate PR).
@inottn OK, I will modify it as you said. It will take 5 to 10 minutes.
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 understand. What I mean is that the current PR adds 20 test cases, which seems excessive for a single fix. Refer to #13425 and #13008, for minor fixes, adding one or two test cases is usually sufficient. The changes involved in this fix aren't related to whether the Slider is in range or vertical mode. I think adding just 2 test cases would suffice—one to test the scenario where distanceToMax <= distanceToPrev, and another for distanceToMax > distanceToPrev.
We only need to ensure minimal test cases cover the logic of this fix, rather than increasing the test coverage of the entire component (which should be done in a separate PR).
@inottn Hi I have modified it. Many test cases I wrote earlier were to improve patch coverage. Now they have been deleted and only 2 are kept, but the patch coverage has been reduced. If you think this is appropriate!
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.
@chenjiahan @inottn Hi, do I need to change something about this?
| afterEach(() => { | ||
| vi.clearAllTimers(); | ||
| }); |
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 was this file modified?
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.
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 didn't encounter this issue when running it locally. What's your operating system and the command you're running?
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 just used test coverage I did run npm run test:coverage,
Now that the test coverage is perfect, I've deleted this line. It's likely a problem with my environment. If you're wondering about the error, I can share it with you. I'm running Windows 11 and running Node v18.17.0. Adding this line allows me to test coverage locally, rather than uploading it to GitHub for Codecov to run. See the image below:
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.
| test('should return prevSteppedValue when distanceToMax > distanceToPrev', () => { | ||
| const wrapper = mount(Slider, { | ||
| props: { min: 0, max: 8, step: 12, modelValue: 2 }, | ||
| }); | ||
|
|
||
| const emitted = wrapper.emitted('update:modelValue'); | ||
| if (emitted && emitted.length > 0) { | ||
| const result = emitted[emitted.length - 1][0] as number; | ||
| expect(result).toBe(0); // Should return prevSteppedValue | ||
| } | ||
| }); |
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 newly added second test case did not enter the if(steppedValue > max) conditional branch. When I commented out the Slider-related modifications and ran the new test case, the test still passed.
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.
Yes, that's it. I updated this.
This new test corrected test cases:
test('should enter steppedValue > max branch', () => {
const wrapper = mount(Slider, {
props: { min: 0, max: 12, step: 20, modelValue: 0 },
});
wrapper.setProps({ modelValue: 11 });
const emitted = wrapper.emitted('update:modelValue');
if (emitted && emitted.length > 0) {
const result = emitted[emitted.length - 1][0] as number;
expect(result).toBeGreaterThanOrEqual(0);
expect(result).toBeLessThanOrEqual(12);
}
});
…y large, the component may return a value outside the max range test.
…y large, the component may return a value outside the max range test.


The issue #13625 has been confirmed to exist, here is a demo that reproduces the issue:

It has been fixed. Here is the demo after the fix:

Fixed an issue where the Slider component's
stepvalue might exceed themaxvalue when the step value is large #13625.Issue Description
When the Slider component's
stepvalue is relatively large, theformatfunction might return a value outside themaxrange.Steps to Reproduce:
min=20,max=100,step=30value=110, which exceeds the setmax=100Cause Analysis
Original
formatfunction logic:Problem: Although the input
valueis clamped to the[min, max]range, the result calculated based on the step size may exceed themaxvalue.Take
min=20, max=100, step=30as an example:20 + Math.round((95-20)/30) * 30 = 20 + 90 = 110Solution
Modify the
formatfunction to use a smart distance comparison strategy:Before:
After modification:
Core Changes
maxmax, compare the distance between the user's actual location andmaxand the distance to the previous valid step valuemaxTest Verification
Take
min=20, max=100, step=30as an example:Backward Compatibility
User Experience Improvements
max=100, they should expect to see 100 selected.This PR fix addresses edge issues with larger step sizes, making component behavior more consistent with user expectations while maintaining backward compatibility.