Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Commit 3ae9b28

Browse files
authored
Expose the currently hovered token and support disabling pinning (#106)
1 parent 02c7f13 commit 3ae9b28

File tree

3 files changed

+251
-59
lines changed

3 files changed

+251
-59
lines changed

src/hoverifier.test.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe('Hoverifier', () => {
4545
hoverOverlayRerenders: EMPTY,
4646
getHover: createStubHoverProvider({ range: hoverRange }, LOADER_DELAY + delayTime),
4747
getActions: () => of(null),
48+
pinningEnabled: true,
4849
})
4950

5051
const positionJumps = new Subject<PositionJump>()
@@ -106,6 +107,7 @@ describe('Hoverifier', () => {
106107
hoverOverlayRerenders: EMPTY,
107108
getHover: createStubHoverProvider(hover, delayTime),
108109
getActions: createStubActionsProvider(['foo', 'bar'], delayTime),
110+
pinningEnabled: true,
109111
})
110112

111113
const positionJumps = new Subject<PositionJump>()
@@ -180,6 +182,146 @@ describe('Hoverifier', () => {
180182
}
181183
})
182184

185+
it('does not pin the overlay on click when pinningEnabled is false', () => {
186+
for (const codeView of testcases) {
187+
const scheduler = new TestScheduler((a, b) => chai.assert.deepEqual(a, b))
188+
189+
const hover = {}
190+
const delayTime = 10
191+
192+
scheduler.run(({ cold, expectObservable }) => {
193+
const hoverifier = createHoverifier({
194+
closeButtonClicks: NEVER,
195+
hoverOverlayElements: of(null),
196+
hoverOverlayRerenders: EMPTY,
197+
getHover: createStubHoverProvider(hover, delayTime),
198+
getActions: createStubActionsProvider(['foo', 'bar'], delayTime),
199+
pinningEnabled: false,
200+
})
201+
202+
const positionJumps = new Subject<PositionJump>()
203+
204+
const positionEvents = of(codeView.codeView).pipe(findPositionsFromEvents(codeView))
205+
206+
const subscriptions = new Subscription()
207+
208+
subscriptions.add(hoverifier)
209+
subscriptions.add(
210+
hoverifier.hoverify({
211+
dom: codeView,
212+
positionEvents,
213+
positionJumps,
214+
resolveContext: () => codeView.revSpec,
215+
})
216+
)
217+
218+
const hoverAndDefinitionUpdates = hoverifier.hoverStateUpdates.pipe(
219+
map(hoverState => !!hoverState.hoverOverlayProps),
220+
distinctUntilChanged(isEqual)
221+
)
222+
223+
const delayAfterMouseover = 100
224+
const outputDiagram = `${MOUSEOVER_DELAY}ms a ${delayTime - 1}ms b ${MOUSEOVER_DELAY +
225+
delayAfterMouseover +
226+
100 -
227+
1}ms c ${delayTime - 1}ms d`
228+
const outputValues: {
229+
[key: string]: boolean
230+
} = {
231+
a: false,
232+
b: true,
233+
c: false,
234+
d: true,
235+
}
236+
237+
// Mouseover https://sourcegraph.sgdev.org/github.com/gorilla/mux@cb4698366aa625048f3b815af6a0dea8aef9280a/-/blob/mux.go#L24:6
238+
cold('a').subscribe(() =>
239+
dispatchMouseEventAtPositionImpure('mouseover', codeView, {
240+
line: 24,
241+
character: 6,
242+
})
243+
)
244+
245+
// Click (should not get pinned) https://sourcegraph.sgdev.org/github.com/gorilla/mux@cb4698366aa625048f3b815af6a0dea8aef9280a/-/blob/mux.go#L24:6
246+
cold(`${MOUSEOVER_DELAY + delayTime + delayAfterMouseover}ms c`).subscribe(() =>
247+
dispatchMouseEventAtPositionImpure('click', codeView, {
248+
line: 24,
249+
character: 6,
250+
})
251+
)
252+
253+
// Mouseover something else and ensure it doesn't get pinned.
254+
cold(`${MOUSEOVER_DELAY + delayTime + delayAfterMouseover + 100}ms d`).subscribe(() =>
255+
dispatchMouseEventAtPositionImpure('mouseover', codeView, {
256+
line: 25,
257+
character: 3,
258+
})
259+
)
260+
261+
expectObservable(hoverAndDefinitionUpdates).toBe(outputDiagram, outputValues)
262+
})
263+
}
264+
})
265+
266+
it('emits the currently hovered token', () => {
267+
for (const codeView of testcases) {
268+
const scheduler = new TestScheduler((a, b) => chai.assert.deepEqual(a, b))
269+
270+
const hover = {}
271+
const delayTime = 10
272+
273+
scheduler.run(({ cold, expectObservable }) => {
274+
const hoverifier = createHoverifier({
275+
closeButtonClicks: NEVER,
276+
hoverOverlayElements: of(null),
277+
hoverOverlayRerenders: EMPTY,
278+
getHover: createStubHoverProvider(hover, delayTime),
279+
getActions: createStubActionsProvider(['foo', 'bar'], delayTime),
280+
pinningEnabled: false,
281+
})
282+
283+
const positionJumps = new Subject<PositionJump>()
284+
285+
const positionEvents = of(codeView.codeView).pipe(findPositionsFromEvents(codeView))
286+
287+
const subscriptions = new Subscription()
288+
289+
subscriptions.add(hoverifier)
290+
subscriptions.add(
291+
hoverifier.hoverify({
292+
dom: codeView,
293+
positionEvents,
294+
positionJumps,
295+
resolveContext: () => codeView.revSpec,
296+
})
297+
)
298+
299+
const hoverAndDefinitionUpdates = hoverifier.hoverStateUpdates.pipe(
300+
map(hoverState => hoverState.hoveredTokenElement && hoverState.hoveredTokenElement.textContent),
301+
distinctUntilChanged(isEqual)
302+
)
303+
304+
const outputDiagram = `${MOUSEOVER_DELAY}ms a ${delayTime - 1}ms b`
305+
const outputValues: {
306+
[key: string]: string | undefined
307+
} = {
308+
a: undefined,
309+
b: 'Router',
310+
}
311+
312+
// Mouseover https://sourcegraph.sgdev.org/github.com/gorilla/mux@cb4698366aa625048f3b815af6a0dea8aef9280a/-/blob/mux.go#L24:6
313+
cold('a').subscribe(() =>
314+
dispatchMouseEventAtPositionImpure('mouseover', codeView, {
315+
line: 48,
316+
character: 10,
317+
})
318+
)
319+
320+
expectObservable(hoverAndDefinitionUpdates).toBe(outputDiagram, outputValues)
321+
})
322+
}
323+
})
324+
183325
describe('pinning', () => {
184326
it('unpins upon clicking on a different position', () => {
185327
for (const codeView of testcases) {
@@ -199,6 +341,7 @@ describe('Hoverifier', () => {
199341
position.line === 24
200342
? createStubActionsProvider(['foo', 'bar'], delayTime)(position)
201343
: of(null),
344+
pinningEnabled: true,
202345
})
203346

204347
const positionJumps = new Subject<PositionJump>()
@@ -268,6 +411,7 @@ describe('Hoverifier', () => {
268411
getHover: position => (position.line === 24 ? createStubHoverProvider({})(position) : of(null)),
269412
getActions: position =>
270413
position.line === 24 ? createStubActionsProvider(['foo', 'bar'])(position) : of(null),
414+
pinningEnabled: true,
271415
})
272416

273417
const positionJumps = new Subject<PositionJump>()
@@ -346,6 +490,7 @@ describe('Hoverifier', () => {
346490
hoverOverlayRerenders: EMPTY,
347491
getHover: createStubHoverProvider(hover, LOADER_DELAY + hoverDelayTime),
348492
getActions: createStubActionsProvider(actions, LOADER_DELAY + actionsDelayTime),
493+
pinningEnabled: true,
349494
})
350495

351496
const positionJumps = new Subject<PositionJump>()
@@ -417,6 +562,7 @@ describe('Hoverifier', () => {
417562
hoverOverlayRerenders: EMPTY,
418563
getHover: createStubHoverProvider(hover),
419564
getActions: () => of(null),
565+
pinningEnabled: true,
420566
})
421567

422568
const positionJumps = new Subject<PositionJump>()
@@ -478,6 +624,7 @@ describe('Hoverifier', () => {
478624
hoverOverlayRerenders: EMPTY,
479625
getHover: createStubHoverProvider(hover),
480626
getActions: () => of(null),
627+
pinningEnabled: true,
481628
})
482629

483630
const positionJumps = new Subject<PositionJump>()
@@ -560,6 +707,7 @@ describe('Hoverifier', () => {
560707
hoverOverlayRerenders: EMPTY,
561708
getHover,
562709
getActions,
710+
pinningEnabled: true,
563711
})
564712

565713
const positionJumps = new Subject<PositionJump>()
@@ -615,6 +763,7 @@ describe('Hoverifier', () => {
615763
// It's important that getHover() and getActions() emit something
616764
getHover: createStubHoverProvider({}),
617765
getActions: () => of([{}]).pipe(delay(50)),
766+
pinningEnabled: true,
618767
})
619768
const positionJumps = new Subject<PositionJump>()
620769
const positionEvents = of(codeView.codeView).pipe(findPositionsFromEvents(codeView))
@@ -655,6 +804,7 @@ describe('Hoverifier', () => {
655804
hoverOverlayRerenders: EMPTY,
656805
getHover: createStubHoverProvider(),
657806
getActions: () => of(null),
807+
pinningEnabled: true,
658808
})
659809
const positionJumps = new Subject<PositionJump>()
660810
const positionEvents = of(codeViewProps.codeView).pipe(findPositionsFromEvents(codeViewProps))

0 commit comments

Comments
 (0)