Repository: mui/material-ui (TypeScript)
Date: 2019-08-26 13:54:44+00:00
Task type: Bug Fix

Issue:
Tooltip is not working properly
On hovering next element showing the previously hovered element tooltip.

## Current Behavior 😯

Showing previous element tooltip

![chrome-capture](https://user-images.githubusercontent.com/42739670/63593652-076e8b80-c5d2-11e9-9771-9ec5ac3481b0.gif)


## Expected Behavior 🤔

Currently hovered element tooltip has to show. (Which is ALIEN in the given example of sandbox)

## Steps to Reproduce 🕹

**Hover on the "Middle of the first element in the sandbox " after that move the cursor to down to vertically "through the tooltip ("DOCUMENT" which is in the example of the sandbox) to next element" it shows previously hovered element tooltip. Actually, it has to show "ALIEN"**

https://codesandbox.io/s/material-ui-tooltip-disable-restore-focus-trigger-94jg5

Environment 🌎

| Tech        | Version |
| ----------- | ------- |
| material-ui | "^0.20.2", |
| @material-ui/core |"^3.5.1" |
| React       |    "^16.8.6"     |
| Browser     |   chrome - Version 76.0.3809.100 (Official Build) (64-bit)      |



Issue discussion:
@skirankumar7 Thanks for the report. What do you think of this fix?
```diff
diff --git a/packages/material-ui/src/Tooltip/Tooltip.js b/packages/material-ui/src/Tooltip/Tooltip.js
index bb716b431..ee2224c26 100644
--- a/packages/material-ui/src/Tooltip/Tooltip.js
+++ b/packages/material-ui/src/Tooltip/Tooltip.js
@@ -261,14 +261,10 @@ function Tooltip(props) {

     clearTimeout(enterTimer.current);
     clearTimeout(leaveTimer.current);
-    if (leaveDelay) {
-      event.persist();
-      leaveTimer.current = setTimeout(() => {
-        handleClose(event);
-      }, leaveDelay);
-    } else {
+    event.persist();
+    leaveTimer.current = setTimeout(() => {
       handleClose(event);
-    }
+    }, leaveDelay);
   };

   const handleTouchStart = event => {
```

It has the advantage of removing code, we would need to make sure it doesn't have side-effects, adding a test case would be perfect. Do you want to work on the issue? :)
One thing I found is on removing the interactive will make the Tooltip works properly

But found in the API docs that

![image](https://user-images.githubusercontent.com/42739670/63669688-5433ab80-c7f8-11e9-8816-b88421f01805.png)

Here leaveDelay has 0 millisec means it should not have an effect with interactive if I am right? else interactive will consider "enterDelay" also.

is code removed regarding leaveDelay when it will release????
regarding test case writing don't know much about writing the test cases.


> is code removed regarding leaveDelay when it will release????

@skirankumar7 No, the fix I'm proposing should keep the existing feature. Regarding the test case, it's something I can handle, if needed. So, what do you think, do you want to give it a try?
> > is code removed regarding leaveDelay when it will release????
> 
> @skirankumar7 No, the fix I'm proposing should keep the existing feature. Regarding the test case, it's something I can handle, if needed. So, what do you think, do you want to give it a try?

I'm not getting what you are asking exactly.
1. Based on the changes you made is it working properly? how do I check that?
@skirankumar7 I'm asking:
1. Do you confirm that the proposed change works correctly?
1. If they do, could you open a pull request?

For 1, you can clone the repository locally, run the documentation, copy and past your reproduction in `/docs/pages/index.js`, apply the diff in the correct files (it's in blue)
For 2, it's about making a commit, pushing it in a fork, and finally opening a pull request

Solution patch:
diff --git a/packages/material-ui/src/Tooltip/Tooltip.js b/packages/material-ui/src/Tooltip/Tooltip.js
--- a/packages/material-ui/src/Tooltip/Tooltip.js
+++ b/packages/material-ui/src/Tooltip/Tooltip.js
@@ -261,14 +261,10 @@ function Tooltip(props) {
 
     clearTimeout(enterTimer.current);
     clearTimeout(leaveTimer.current);
-    if (leaveDelay) {
-      event.persist();
-      leaveTimer.current = setTimeout(() => {
-        handleClose(event);
-      }, leaveDelay);
-    } else {
+    event.persist();
+    leaveTimer.current = setTimeout(() => {
       handleClose(event);
-    }
+    }, leaveDelay);
   };
 
   const handleTouchStart = event => {


Test patch:
diff --git a/packages/material-ui/src/Tooltip/Tooltip.test.js b/packages/material-ui/src/Tooltip/Tooltip.test.js
--- a/packages/material-ui/src/Tooltip/Tooltip.test.js
+++ b/packages/material-ui/src/Tooltip/Tooltip.test.js
@@ -101,6 +101,8 @@ describe('<Tooltip />', () => {
     children.simulate('mouseOver');
     assert.strictEqual(wrapper.find('[role="tooltip"]').exists(), true);
     children.simulate('mouseLeave');
+    clock.tick(0);
+    wrapper.update();
     assert.strictEqual(wrapper.find(Popper).props().open, false);
     assert.strictEqual(wrapper.find(Popper).props().open, false);
   });
@@ -119,6 +121,7 @@ describe('<Tooltip />', () => {
     assert.strictEqual(handleRequestOpen.callCount, 1);
     assert.strictEqual(handleClose.callCount, 0);
     children.simulate('mouseLeave');
+    clock.tick(0);
     assert.strictEqual(handleRequestOpen.callCount, 1);
     assert.strictEqual(handleClose.callCount, 1);
   });
@@ -142,6 +145,7 @@ describe('<Tooltip />', () => {
       children.simulate('touchEnd');
       children.simulate('blur');
       clock.tick(1500);
+      wrapper.update();
       assert.strictEqual(wrapper.find(Popper).props().open, false);
     });
   });
@@ -301,6 +305,28 @@ describe('<Tooltip />', () => {
       clock.tick(111);
       assert.strictEqual(wrapper.find(Popper).props().open, true);
     });
+
+    it('should not animate twice', () => {
+      const wrapper = mount(
+        <Tooltip title="Hello World" interactive enterDelay={500}>
+          <button id="testChild" type="submit">
+            Hello World
+          </button>
+        </Tooltip>,
+      );
+
+      const children = wrapper.find('#testChild');
+      children.simulate('mouseOver', { type: 'mouseOver' });
+      clock.tick(500);
+      wrapper.update();
+      assert.strictEqual(wrapper.find(Popper).props().open, true);
+      const popper = wrapper.find(Popper);
+      children.simulate('mouseLeave', { type: 'mouseleave' });
+      assert.strictEqual(wrapper.find(Popper).props().open, true);
+      popper.simulate('mouseOver', { type: 'mouseover' });
+      clock.tick(0);
+      assert.strictEqual(wrapper.find(Popper).props().open, true);
+    });
   });
 
   describe('forward', () => {