- Notifications
You must be signed in to change notification settings - Fork 467
Copy non-enumerable data transfer props #734
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
Copy non-enumerable data transfer props #734
Conversation
| This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit ea9a4bf:
|
Codecov Report
@@ Coverage Diff @@ ## master #734 +/- ## ========================================= Coverage 100.00% 100.00% ========================================= Files 24 24 Lines 657 657 Branches 173 173 ========================================= Hits 657 657
Continue to review full report at Codecov.
|
| Looks super! Thanks for this. For this one, a good test would be something that does what can't be done without these changes. |
thank you, I'll add tests. one more thing is there a guide on manual verification? |
Every PR is build in codesandbox. In the status list you can find ci/codesandbox. You could create a new codesandbox and then add That way you can share your manual test. Otherwise follow the "local install instructions". |
cdaac01 to 1ce3eee Compare
thanks, you helped me a lot |
| Thanks for working on this. The test seems to be testing something very specific. Is there a typical use case of a test that a developer would write that doesn't work without your changes? |
I have tests similar to this for a while on my project. But they started to fail when I upgraded react testing library from function FileUploader ({ onFileUpload }) { function handleDrop(e) { onFileUpload(e.dataTransfer.items); } return <div onDrop={handleDrop} /> } it('should upload file', () => { const onFileUploadSpy = jasmine.createSpy('onFileUploadSpy'); const component = render(<FileUploader onFileUpload={onFileUploadSpy}/>); const dragNdropZone = component.getByTestId('drag-n-drop-zone'); const dataTransfer = new DataTransfer(); Object.defineProperty(dataTransfer, 'items', {value: [{ name: 'test-file' }]}); expect(onFileUploadSpy).toHaveBeenCalledWith(dataTransfer.items); }) |
| Looks like the test is mocking how Did your test work in a browser or only in JSDOM? |
Basically I tested changes in karma env |
With your mock or in a browser that implements It seems to me that const dt = new DataTransfer(); const file = new File([], 'empty.png'); dt.items.add(file)would work in a browser. To get the correct functionality into an environment without a standard class File { constructor(fileBits, fileName, options = {}) { this._name = fileName; this._lastModified = options._lastModified || 0; } get name() { return this._name } get lastModified() { return this._lastModified } } class DataTransferItem { constructor(file) { // private this._file = file; } get kind() { return "file" } get type() { throw new Error('not implemented') } getAsString() { throw new Error('not implemented') } getAsFile() { return this._file } } class DataTransferItemList { constructor() { this._items = [] } // only implements DataTransferItem? add(File data); add(data) { const item = new DataTransferItem(data); this._items.push(item); return item; } } class DataTransfer { constructor() { this._items = new DataTransferItemList(); } get items() { return this._items } } |
unfortunately mocked
|
src/__tests__/events.js Outdated
| window.DataTransfer = function DataTransfer() {} | ||
| const node = document.createElement('div') | ||
| const spy = jest.fn() | ||
| const item = { |
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 this could just be an empty object to reduce the complexity and focus on whats relevant for this testcase
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.
good point
This is another problem in The conversion mechanism need to be placed before construction the event instance. But I think this is another bug and could be done in a second PR. |
yeah, I agree this is a different issue, my point is that I am not able to use a suggested solution on my test |
Yeah in a browser with a real |
| Ah, ok. I can't too. We just came across this exact problem. Our test looks like: it('shows overlay if file is dragged over drop zone', async () => { uploadType = { singular: 'Image', plural: 'Images', filter: ['image/png'], }; await setup({uploadType}); const fileZone = screen.getByTestId('drop-zone'); const dataTransfer = new DataTransfer(); Object.defineProperty(dataTransfer, 'types', { value: ['Files']}) fireEvent.dragEnter(fileZone, { dataTransfer }); const fileOverlay = screen.getByText('Upload images...'); expect(fileOverlay).toBeTruthy(); });After some debugging I came to mostly your solution. With your changes our tests work as expected. |
| Can anyone tell why the tests are failing? I don't see any relations to the changes made. |
I had the same issue locally after pulling the latest changes. I reinstalled node modules and the issue has gone. how can I reinstall dependencies for the build? |
| I just cleared the cache and restarted the build 👍 |
| Ok, so I'm thinking that because JSDOM doesn't support the DataTransfer constructor, this is probably the best we can do for a test and I'm ok with that. Anyone else have thoughts before we merge this as-is? |
micha149 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.
Wherever my prior approval has gone, I'm still fine with this change
🤦 Now I noticed the „with write access”. Never answer in issues before your first coffee. ☕ Sorry for that. |
kentcdodds 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 a bunch!
| @all-contributors please add @Snizhana for code and tests |
| I've put up a pull request to add @Snizhana! 🎉 |
| @all-contributors please add @micha149 for review |
| I've put up a pull request to add @micha149! 🎉 |
| @Snizhana, thanks so much for your help! I've added you as a collaborator on the project. Please make sure that you review the |
| Is someone already on a fix for the costructor error? If not I would give it a try, because it will make our tests a bit more readable… |
| 🎉 This PR is included in version 7.22.2 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
What:
Change the logic of copying
dataTransferpropsWhy:
At the moment
Object.assignis used to extend event object with passed data, but doesn't copy non-enumerable propsHow:
In order to iterate by non-enumerable props
getOwnPropertyNamesmethod is usedChecklist:
docs site