-
Notifications
You must be signed in to change notification settings - Fork 93
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
[KListWithOverflow]: Add unit tests #920
base: develop
Are you sure you want to change the base?
[KListWithOverflow]: Add unit tests #920
Conversation
…fit within available space.
…isplays "more" button when items do not fit
… items to "more" slot
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 a lot @you-think-you-know-me! This looks super good! I have left just some minor comments, and requested a couple of additional test cases, but apart from that everything else looks good!
const MORE_BUTTON_WIDTH = 20; | ||
|
||
// Utility function to wait for two nextTicks after mounting | ||
async function waitForNextTicks(wrapper) { |
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.
Is this method actually needed? I just removed it and all tests kept working fine.
const wrapper = mount(KListWithOverflow, { | ||
propsData: { items }, | ||
slots: { | ||
item: '<div class="list-item">{{ typeof item === "object" ? item.label : item }}</div>', |
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 dont need this ternary here, because when we have a divider we dont render the item slot.
|
||
expect(wrapper.vm.overflowItems).toEqual(['Item 3']); | ||
expect(wrapper.vm.isMoreButtonVisible).toBe(true); | ||
expect(listItems.at(1).element).toHaveStyle({ visibility: 'hidden' }); |
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 can be a little bit more explicit with the code so its easier to understand for other people. For example here, we can tweak this code extracting variables and adding comments to be more expressive with the intention. For example:
const divider = listItems.at(1).element;
// The divider its the last non-overflowed item, it should be hidden
expect(divider).toHaveStyle({ visibility: 'hidden' });
expect(wrapper.vm.isMoreButtonVisible).toBe(true); | ||
expect(listItems.at(1).element).toHaveStyle({ visibility: 'hidden' }); | ||
}); | ||
}); |
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.
Lets add just a couple of tests more:
- It renders the divider slot if we pass a divider object.
- The first overflowed item shouldnt be a divider
- All items are shown if they fit if we dont render the more button
- This means: If our
LIST_WRAPPER_WIDTH
is 101, we can still render two items of width 50 for example. - With this we will find an error because in this line we set the item visibility to
visible
but we dont restore the position tounset
. So if you can include this line too it would be nice.
- This means: If our
Hi! I was passing by and felt that the way we are trying to test this component is a bit counter-intuitive: we are trying to set the sizes of the elements via JS, which is not the way the component would be used! Most probably, the user would have a pre-defined markup for the Something like following perhaps? import { mount } from '@vue/test-utils';
import KListWithOverflow from '../KListWithOverflow.vue';
// Constants for styling
const LIST_STYLES = `
.list-item {
display: inline-block;
white-space: nowrap;
}
.list-item.fits {
width: 80px;
height: 20px;
}
.list-item.overflows {
width: 25px;
height: 20px;
}
.list-item.medium {
width: 60px;
height: 20px;
}
.list-item.small {
width: 20px;
height: 20px;
}
`;
describe('KListWithOverflow.vue', () => {
// Add styles to document before tests
// TODO: Check if it actually works with Enzyme
beforeAll(() => {
const styleElement = document.createElement('style');
styleElement.textContent = LIST_STYLES;
document.head.appendChild(styleElement);
});
it('renders all items when they fit within available space', async () => {
const items = ['Item 1'];
const wrapper = mount(KListWithOverflow, {
propsData: { items },
slots: {
// Can now just use the class on the list item to control its size
// The class clearly indicates the size of the item and the intent of the test
item: '<div class="list-item fits">{{ item }}</div>',
more: '<button class="more-button">More</button>',
},
});
await wrapper.vm.$nextTick();
expect(wrapper.vm.overflowItems).toEqual([]);
expect(wrapper.vm.isMoreButtonVisible).toBe(false);
const listItem = wrapper.find('.list-item');
expect(listItem.element).toHaveStyle({
visibility: 'visible',
position: 'unset'
});
});
// Can easily write more tests by switching the class of the list item
}); This is just a brief idea, and I have never actually ran this code to ensure it works! but we probably should spend some time But seeing this PR, I thought that it might be worthwhile to look at this alternative approach. I would like to advocate for it as it does not make use of JS to control the sizing of the elements, and thus helps us to get rid of many "magic constants" that appear throughout the tests, or of having to manage the rendering ourselves from inside the tests. What do you think about this @AlexVelezLl @you-think-you-know-me? |
Hey @EshaanAgg, thanks for jumping in. Yes! This is a very good alternative too, although Im not a big fan of having to scroll up to the definition of A cons of overwiting the I think we could implement something more complicated like defining unique classes dynamically in each test case and assigning them to the items inside a |
Thanks, @AlexVelezLl, for the detailed response. Even I do agree that having to scroll to the top of the document breaks the encapsulation of the test logic in the test itself approach and thus might be a bit counterintuitive. We can definitely ideate better ways to do the same later. Meanwhile, we will currently keep the main aim of this PR to introduce a test suite that covers all the edge cases! Thank a lot again :) |
Description
We currently don't have unit tests for KListWithOverflow. It adds unit tests for KListWithOverflow.
Issue addressed
Closes #833
Changelog
Testing checklist
Reviewer guidance
Comments
😄