-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>`cached-value` tests</title> | ||
<meta charset="utf8"> | ||
</head> | ||
<body></body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { parseHtml } from 'hydroactive/testing.js'; | ||
import { CachedValue } from './cached-value.js'; | ||
|
||
describe('cached-value', () => { | ||
afterEach(() => { | ||
for (const node of document.body.childNodes) node.remove(); | ||
}); | ||
|
||
function render({ count }: { count: number }) { | ||
return parseHtml(CachedValue, ` | ||
<cached-value> | ||
<div>The current count is: <span id="count">${count}</span>.</div> | ||
<div>Pi computed to that many decimal places is: | ||
<span id="pi">${computePiWithPrecision(count)}</span>. | ||
</div> | ||
<div> | ||
Pi is still: | ||
<span id="pi-again">${computePiWithPrecision(count)}</span>. | ||
</div> | ||
<button>+</button> | ||
</cached-value> | ||
`); | ||
} | ||
|
||
function computePiWithPrecision(precision: number): string { | ||
const length = '3.'.length + precision; | ||
return Math.PI.toFixed(48).slice(0, length).padEnd(length, '0'); | ||
} | ||
|
||
describe('CachedValue', () => { | ||
it('does not re-render on hydration', async () => { | ||
const el = render({ count: 5 }); | ||
document.body.appendChild(el); | ||
|
||
await el.stable(); | ||
|
||
expect(el.querySelector('#count')!.textContent).toBe('5'); | ||
expect(el.querySelector('#pi')!.textContent).toBe('3.14159'); | ||
expect(el.querySelector('#pi-again')!.textContent).toBe('3.14159'); | ||
}); | ||
|
||
it('increments on click', async () => { | ||
const el = render({ count: 5 }); | ||
document.body.appendChild(el); | ||
|
||
(el.querySelector('button')! as HTMLElement).click(); | ||
|
||
await el.stable(); | ||
|
||
expect(el.querySelector('#count')!.textContent).toBe('6'); | ||
expect(el.querySelector('#pi')!.textContent).toBe('3.141592'); | ||
expect(el.querySelector('#pi-again')!.textContent).toBe('3.141592'); | ||
}); | ||
|
||
it('reuses the PI computation', async () => { | ||
const consoleSpy = spyOn(console, 'log'); | ||
|
||
const el = render({ count: 5 }); | ||
document.body.appendChild(el); | ||
|
||
await el.stable(); | ||
|
||
expect(consoleSpy) | ||
.toHaveBeenCalledOnceWith('Computing PI to 5 digits...'); | ||
consoleSpy.calls.reset(); | ||
|
||
(el.querySelector('button')! as HTMLElement).click(); | ||
await el.stable(); | ||
|
||
expect(consoleSpy) | ||
.toHaveBeenCalledOnceWith('Computing PI to 6 digits...'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { defineComponent } from 'hydroactive'; | ||
import { cached } from 'hydroactive/signals.js'; | ||
|
||
/** Uses `cached` to avoid repeatedly executing an expensive computed signal. */ | ||
export const CachedValue = defineComponent('cached-value', (comp) => { | ||
const count = comp.live('#count', Number); | ||
comp.listen('button', 'click', () => { count.set(count() + 1); }); | ||
|
||
// Define a computed with `cached` to cache the result. No matter how many | ||
// times `pi()` is called, the result will be reused as long as `count` does | ||
// not change. | ||
const pi = cached(() => { | ||
console.log(`Computing PI to ${count()} digits...`); | ||
return computePiWithPrecision(count()); | ||
}); | ||
|
||
// `pi` is read twice here, and both will update automatically, but it will | ||
// only be computed once. | ||
comp.bind('#pi', () => pi()); | ||
comp.bind('#pi-again', () => pi()); | ||
}); | ||
|
||
declare global { | ||
interface HTMLElementTagNameMap { | ||
'cached-value': InstanceType<typeof CachedValue>; | ||
} | ||
} | ||
|
||
/** | ||
* Pretend this is computationally expensive and we don't want to run it more | ||
* than we need to. | ||
*/ | ||
function computePiWithPrecision(precision: number): string { | ||
const length = '3.'.length + precision; | ||
return Math.PI.toFixed(48).slice(0, length).padEnd(length, '0'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters