blob: 3ee3fbc7d7cf0b780f028f68b98849624946b7a9 [file] [log] [blame]
// Copyright 2020 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { aTimeout, fixtureCleanup } from '@open-wc/testing-helpers/index-no-side-effects';
import { fixture, html } from '@open-wc/testing/index-no-side-effects';
import { assert } from 'chai';
import { css, customElement, LitElement } from 'lit-element';
import './lazy_list';
import { LazyListElement, OnEnterList } from './lazy_list';
@customElement('milo-lazy-list-test-entry')
class LazyListTestEntryElement extends LitElement implements OnEnterList {
onEnterCallCount = 0;
onEnterList() {
this.onEnterCallCount++;
}
protected render() {
return html`
<div id="placeholder">A</div>
`;
}
static styles = css`
#placeholder {
height: 10px;
}
`;
}
describe('lazy_list_test', () => {
describe('lazy_list', () => {
let lazyList: LazyListElement;
let entries: NodeListOf<LazyListTestEntryElement>;
before(async () => {
lazyList = await fixture<LazyListElement>(html`
<milo-lazy-list style="height: 100px;">
${new Array(100).fill(0).map(() => html`
<milo-lazy-list-test-entry>
</milo-lazy-list-test-entry>
`)}
</milo-lazy-list>
`);
entries = lazyList.querySelectorAll<LazyListTestEntryElement>('milo-lazy-list-test-entry');
});
after(fixtureCleanup);
it('should notify entries in the view.', async () => {
await aTimeout(LazyListElement.MIN_INTERVAL);
entries.forEach((entry, i) => {
assert.equal(entry.onEnterCallCount, i <= 10 ? 1 : 0);
});
});
it('should notify new entries scrolls into the view.', async () => {
lazyList.scrollTop = 200;
lazyList.onscroll();
await aTimeout(LazyListElement.MIN_INTERVAL);
entries.forEach((entry, i) => {
assert.equal(entry.onEnterCallCount, i <= 30 ? 1 : 0);
});
});
it('should not re-notify old entries when scrolling back.', async () => {
lazyList.scrollTop = 0;
lazyList.onscroll();
await aTimeout(LazyListElement.MIN_INTERVAL);
entries.forEach((entry, i) => {
assert.equal(entry.onEnterCallCount, i <= 30 ? 1 : 0);
});
});
});
describe('lazy_list with growth', () => {
it('should notify entries in the view progressively', async () => {
after(fixtureCleanup);
const list = await fixture<LazyListElement>(html`
<milo-lazy-list .growth=${100} style="height: 100px;">
${new Array(100).fill(0).map(() => html`
<milo-lazy-list-test-entry>
</milo-lazy-list-test-entry>
`)}
</milo-lazy-list>
`);
const startTime = Date.now();
const entries = list.querySelectorAll<LazyListTestEntryElement>('milo-lazy-list-test-entry');
// Wait half of MIN_INTERVAL to avoid rounding errors when calculating
// ticks.
await aTimeout(LazyListElement.MIN_INTERVAL / 2);
let ticks = 0;
while (ticks <= 10) {
ticks = Math.floor((Date.now() - startTime) / LazyListElement.MIN_INTERVAL);
entries.forEach((entry, i) => {
// Renders 10 initially, then 10 more per iteration.
assert.equal(entry.onEnterCallCount, i <= 10 + ticks * 10 ? 1 : 0);
});
await aTimeout(LazyListElement.MIN_INTERVAL);
}
});
});
});