/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/unit/core/dom/layout/test-layout.js
633 строки
22 KB
Justin Ridgewell
Lint remaining static enums in src (#36821)
16 ноя 2021, 01:07
Не верифицирован
16 ноя 2021, 01:07
556e94a
Код
Авторство
О чём код?
import { Layout_Enum, assertLength, assertLengthOrPercent, getLengthNumeral, getLengthUnits, isLoadingAllowed, parseLayout, parseLength, } from '#core/dom/layout'; import {applyStaticLayout} from '#core/static-layout'; describes.sandboxed('DOM - layout', {}, () => { let div; beforeEach(() => { div = document.createElement('div'); }); it('parseLayout', () => { expect(parseLayout('nodisplay')).to.equal('nodisplay'); expect(parseLayout('fixed')).to.equal('fixed'); expect(parseLayout('fixed-height')).to.equal('fixed-height'); expect(parseLayout('responsive')).to.equal('responsive'); expect(parseLayout('container')).to.equal('container'); expect(parseLayout('fill')).to.equal('fill'); expect(parseLayout('fluid')).to.equal('fluid'); }); it('are loading components allowed', () => { const el = { tagName: 'hold', }; const elementsValidTagNames = [ // in allowlist. 'AMP-AD', 'AMP-ANIM', 'AMP-EMBED', 'AMP-FACEBOOK', 'AMP-FACEBOOK-COMMENTS', 'AMP-FACEBOOK-PAGE', 'AMP-GOOGLE-DOCUMENT-EMBED', 'AMP-IFRAME', 'AMP-IMG', 'AMP-INSTAGRAM', 'AMP-LIST', 'AMP-PINTEREST', 'AMP-PLAYBUZZ', 'AMP-TWITTER', // matched by video player naming convention (fake) 'AMP-FOO-PLAYER', 'AMP-VIDEO-FOO', // matched by video player naming convention (actual) 'AMP-JWPLAYER', 'AMP-OOYALA-PLAYER', 'AMP-VIDEO-IFRAME', 'AMP-YOUTUBE', 'AMP-VIMEO', 'AMP-BRIGHTCOVE', 'AMP-DAILYMOTION', ]; elementsValidTagNames.forEach(function (tag) { el.tagName = tag; expect(isLoadingAllowed(el)).to.be.true; }); // This isn't an exhaustive list of elements that aren't allowed // to have loading indicators. const elementsInvalidTagNames = [ 'AMP-POSITION-OBSERVER', 'AMP-BODYMOVIN-ANIMATION', 'AMP-VIDEO', 'AMP-REDDIT', 'AMP-GITHUB', ]; elementsInvalidTagNames.forEach(function (tag) { el.tagName = tag; expect(isLoadingAllowed(el)).to.be.false; }); }); it('parseLayout - failure', () => { expect(parseLayout('abc')).to.be.undefined; expect(parseLayout('xyz')).to.be.undefined; }); it('parseLength', () => { expect(parseLength(10)).to.equal('10px'); expect(parseLength('10')).to.equal('10px'); expect(parseLength('10px')).to.equal('10px'); expect(parseLength('10em')).to.equal('10em'); expect(parseLength('10vmin')).to.equal('10vmin'); expect(parseLength('10cm')).to.equal('10cm'); expect(parseLength('10mm')).to.equal('10mm'); expect(parseLength('10in')).to.equal('10in'); expect(parseLength('10pt')).to.equal('10pt'); expect(parseLength('10pc')).to.equal('10pc'); expect(parseLength('10q')).to.equal('10q'); expect(parseLength(10.1)).to.equal('10.1px'); expect(parseLength('10.2')).to.equal('10.2px'); expect(parseLength('10.1px')).to.equal('10.1px'); expect(parseLength('10.1em')).to.equal('10.1em'); expect(parseLength('10.1vmin')).to.equal('10.1vmin'); expect(parseLength(undefined)).to.equal(undefined); expect(parseLength(null)).to.equal(undefined); expect(parseLength('')).to.equal(undefined); }); it('getLengthUnits', () => { expect(getLengthUnits('10px')).to.equal('px'); expect(getLengthUnits('10em')).to.equal('em'); expect(getLengthUnits('10vmin')).to.equal('vmin'); expect(getLengthUnits('10.1px')).to.equal('px'); expect(getLengthUnits('10.1em')).to.equal('em'); expect(getLengthUnits('10.1vmin')).to.equal('vmin'); }); it('getLengthNumeral', () => { expect(getLengthNumeral('10')).to.equal(10); expect(getLengthNumeral('10px')).to.equal(10); expect(getLengthNumeral('10em')).to.equal(10); expect(getLengthNumeral('10vmin')).to.equal(10); expect(getLengthNumeral('10.1')).to.equal(10.1); expect(getLengthNumeral('10.1px')).to.equal(10.1); expect(getLengthNumeral('10.1em')).to.equal(10.1); expect(getLengthNumeral('10.1vmin')).to.equal(10.1); expect(getLengthNumeral(null)).to.equal(undefined); expect(getLengthNumeral('auto')).to.equal(undefined); }); it('assertLength', () => { expect(assertLength('10px')).to.equal('10px'); expect(assertLength('10em')).to.equal('10em'); expect(assertLength('10vmin')).to.equal('10vmin'); expect(assertLength('10cm')).to.equal('10cm'); expect(assertLength('10mm')).to.equal('10mm'); expect(assertLength('10in')).to.equal('10in'); expect(assertLength('10pt')).to.equal('10pt'); expect(assertLength('10pc')).to.equal('10pc'); expect(assertLength('10q')).to.equal('10q'); expect(assertLength('10.1px')).to.equal('10.1px'); expect(assertLength('10.1em')).to.equal('10.1em'); expect(assertLength('10.1vmin')).to.equal('10.1vmin'); allowConsoleError(() => { expect(function () { assertLength('10%'); }).to.throw(/Invalid length value/); }); allowConsoleError(() => { expect(function () { assertLength(10); }).to.throw(/Invalid length value/); }); allowConsoleError(() => { expect(function () { assertLength('10'); }).to.throw(/Invalid length value/); }); allowConsoleError(() => { expect(function () { assertLength(undefined); }).to.throw(/Invalid length value/); }); allowConsoleError(() => { expect(function () { assertLength(null); }).to.throw(/Invalid length value/); }); allowConsoleError(() => { expect(function () { assertLength(''); }).to.throw(/Invalid length value/); }); }); it('assertLengthOrPercent', () => { expect(assertLengthOrPercent('10px')).to.equal('10px'); expect(assertLengthOrPercent('10em')).to.equal('10em'); expect(assertLengthOrPercent('10vmin')).to.equal('10vmin'); expect(assertLengthOrPercent('10.1px')).to.equal('10.1px'); expect(assertLengthOrPercent('10.1em')).to.equal('10.1em'); expect(assertLengthOrPercent('10.1vmin')).to.equal('10.1vmin'); expect(assertLengthOrPercent('10.1%')).to.equal('10.1%'); allowConsoleError(() => { expect(function () { assertLengthOrPercent(10); }).to.throw(/Invalid length or percent value/); }); allowConsoleError(() => { expect(function () { assertLengthOrPercent('10'); }).to.throw(/Invalid length or percent value/); }); allowConsoleError(() => { expect(function () { assertLengthOrPercent(undefined); }).to.throw(/Invalid length or percent value/); }); allowConsoleError(() => { expect(function () { assertLengthOrPercent(null); }).to.throw(/Invalid length or percent value/); }); allowConsoleError(() => { expect(function () { assertLengthOrPercent(''); }).to.throw(/Invalid length or percent value/); }); }); it('layout=nodisplay', () => { div.setAttribute('layout', 'nodisplay'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.NODISPLAY); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); document.body.appendChild(div); expect(div).to.have.display('none'); document.body.removeChild(div); expect(div).to.have.class('i-amphtml-layout-nodisplay'); expect(div).to.not.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=fixed', () => { div.setAttribute('layout', 'fixed'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED); expect(div.style.width).to.equal('100px'); expect(div.style.height).to.equal('200px'); expect(div).to.have.class('i-amphtml-layout-fixed'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=fixed - default with width/height', () => { div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED); expect(div.style.width).to.equal('100px'); expect(div.style.height).to.equal('200px'); }); it('layout=fixed - requires width/height', () => { div.setAttribute('layout', 'fixed'); allowConsoleError(() => { expect(() => applyStaticLayout(div)).to.throw( /The "height" attribute is missing/ ); }); }); it('layout=fixed-height', () => { div.setAttribute('layout', 'fixed-height'); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED_HEIGHT); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal('200px'); expect(div).to.have.class('i-amphtml-layout-fixed-height'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=fixed-height, with width=auto', () => { div.setAttribute('layout', 'fixed-height'); div.setAttribute('height', 200); div.setAttribute('width', 'auto'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED_HEIGHT); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal('200px'); expect(div).to.have.class('i-amphtml-layout-fixed-height'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=fixed-height, prohibit width!=auto', () => { div.setAttribute('layout', 'fixed-height'); div.setAttribute('height', 200); div.setAttribute('width', 300); allowConsoleError(() => { expect(function () { applyStaticLayout(div); }).to.throw(/The "width" attribute must be missing or "auto"/); }); }); it('layout=fixed-height - default with height', () => { div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED_HEIGHT); expect(div.style.height).to.equal('200px'); expect(div.style.width).to.equal(''); }); it('layout=fixed-height - default with height and width=auto', () => { div.setAttribute('height', 200); div.setAttribute('width', 'auto'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FIXED_HEIGHT); expect(div.style.height).to.equal('200px'); expect(div.style.width).to.equal(''); }); it('layout=fixed-height - requires height', () => { div.setAttribute('layout', 'fixed-height'); allowConsoleError(() => { expect(() => applyStaticLayout(div)).to.throw( /The "height" attribute is missing/ ); }); }); it('layout=responsive', () => { div.setAttribute('layout', 'responsive'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-responsive'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(1); expect(div.children[0].tagName.toLowerCase()).to.equal('i-amphtml-sizer'); expect(div.children[0].getAttribute('slot')).to.equal('i-amphtml-svc'); expect(div.children[0].style.paddingTop).to.equal('200%'); }); it('layout=responsive - default with sizes', () => { div.setAttribute('sizes', '50vw'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-responsive'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(1); expect(div.children[0].tagName.toLowerCase()).to.equal('i-amphtml-sizer'); expect(div.children[0].getAttribute('slot')).to.equal('i-amphtml-svc'); expect(div.children[0].style.paddingTop).to.equal('200%'); }); it('layout=intrinsic', () => { div.setAttribute('layout', 'intrinsic'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.INTRINSIC); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-intrinsic'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(1); expect(div.children[0].tagName.toLowerCase()).to.equal('i-amphtml-sizer'); expect(div.children[0].getAttribute('slot')).to.equal('i-amphtml-svc'); expect(div.children[0].children.length).to.equal(1); expect(div.children[0].children[0].tagName.toLowerCase()).to.equal('img'); expect(div.children[0].children[0].src).to.equal( 'data:image/svg+xml;charset=utf-8,<svg height="200px" width="100px" xmlns="http://www.w3.org/2000/svg" version="1.1"/>' ); }); it('layout=intrinsic - default with sizes', () => { div.setAttribute('layout', 'intrinsic'); div.setAttribute('sizes', '50vw'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.INTRINSIC); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-intrinsic'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(1); expect(div.children[0].tagName.toLowerCase()).to.equal('i-amphtml-sizer'); expect(div.children[0].getAttribute('slot')).to.equal('i-amphtml-svc'); expect(div.children[0].children.length).to.equal(1); expect(div.children[0].children[0].tagName.toLowerCase()).to.equal('img'); expect(div.children[0].children[0].src).to.equal( 'data:image/svg+xml;charset=utf-8,<svg height="200px" width="100px" xmlns="http://www.w3.org/2000/svg" version="1.1"/>' ); }); it('layout=fill', () => { div.setAttribute('layout', 'fill'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FILL); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-fill'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=container', () => { div.setAttribute('layout', 'container'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.CONTAINER); expect(div.style.width).to.equal(''); expect(div.style.height).to.equal(''); expect(div).to.have.class('i-amphtml-layout-container'); expect(div).to.not.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=flex-item', () => { div.setAttribute('layout', 'flex-item'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FLEX_ITEM); expect(div.style.width).to.equal('100px'); expect(div.style.height).to.equal('200px'); expect(div).to.have.class('i-amphtml-layout-flex-item'); expect(div).to.have.class('i-amphtml-layout-size-defined'); expect(div.children.length).to.equal(0); }); it('layout=fluid - default', () => { div.setAttribute('height', 'fluid'); const parentDiv = document.createElement('div'); parentDiv.appendChild(div); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FLUID); expect(div).to.have.class('i-amphtml-layout-awaiting-size'); expect(div.children.length).to.equal(0); }); it('layout=fluid - default with width', () => { div.setAttribute('height', 'fluid'); div.setAttribute('width', 300); expect(applyStaticLayout(div)).to.equal(Layout_Enum.FLUID); expect(div).to.have.class('i-amphtml-layout-awaiting-size'); expect(div.style.width).to.equal('300px'); expect(div.children.length).to.equal(0); }); it('layout=unknown', () => { div.setAttribute('layout', 'foo'); allowConsoleError(() => { expect(function () { applyStaticLayout(div); }).to.throw(/Invalid "layout" value: foo/); }); }); it('should configure natural dimensions; default layout', () => { const pixel = document.createElement('amp-pixel'); expect(applyStaticLayout(pixel)).to.equal(Layout_Enum.FIXED); expect(pixel.style.width).to.equal('0px'); expect(pixel.style.height).to.equal('0px'); }); it('should configure natural dimensions; default layout; with width', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('width', '11'); expect(applyStaticLayout(pixel)).to.equal(Layout_Enum.FIXED); expect(pixel.style.width).to.equal('11px'); expect(pixel.style.height).to.equal('0px'); }); it('should configure natural dimensions; default layout; with height', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('height', '11'); expect(applyStaticLayout(pixel)).to.equal(Layout_Enum.FIXED); expect(pixel.style.width).to.equal('0px'); expect(pixel.style.height).to.equal('11px'); }); it('should configure natural dimensions; layout=fixed', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('layout', 'fixed'); expect(applyStaticLayout(pixel)).to.equal(Layout_Enum.FIXED); expect(pixel.style.width).to.equal('0px'); expect(pixel.style.height).to.equal('0px'); }); it('should configure natural dimensions; layout=fixed-height', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('layout', 'fixed-height'); expect(applyStaticLayout(pixel)).to.equal(Layout_Enum.FIXED_HEIGHT); expect(pixel.style.height).to.equal('0px'); expect(pixel.style.width).to.equal(''); }); it('should layout with pixel values', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('width', '1px'); pixel.setAttribute('height', '1px'); expect(() => { applyStaticLayout(pixel); }).to.not.throw(); }); it('should layout with valid with auto width value', () => { const pixel = document.createElement('amp-pixel'); pixel.setAttribute('width', 'auto'); pixel.setAttribute('height', '1px'); expect(() => { applyStaticLayout(pixel); }).to.not.throw(); }); it('should fail invalid width', () => { const pixel = document.createElement('amp-pixel'); // Width=X is invalid. pixel.setAttribute('width', 'X'); pixel.setAttribute('height', '1px'); allowConsoleError(() => { expect(() => { applyStaticLayout(pixel); }).to.throw(/Invalid "width" value: X/); }); }); it('should fail invalid height', () => { const pixel = document.createElement('amp-pixel'); // Height=X is invalid. pixel.setAttribute('width', '1px'); pixel.setAttribute('height', 'X'); allowConsoleError(() => { expect(() => { applyStaticLayout(pixel); }).to.throw(/Invalid "height" value: X/); }); }); it('should trust server layout', () => { div.setAttribute('i-amphtml-layout', 'flex-item'); div.setAttribute('layout', 'responsive'); div.setAttribute('width', 'invalid'); div.setAttribute('height', 'invalid'); div.className = 'other'; div.style.width = '111px'; div.style.height = '112px'; expect(applyStaticLayout(div)).to.equal(Layout_Enum.FLEX_ITEM); // No other attributes are read or changed. expect(div.style.width).to.equal('111px'); expect(div.style.height).to.equal('112px'); expect(div.className).to.equal('other'); expect(div.style.display).to.equal(''); expect(div.children.length).to.equal(0); }); it('should read sizer for responsive layout', () => { div.setAttribute('i-amphtml-layout', 'responsive'); const sizer = document.createElement('i-amphtml-sizer'); div.appendChild(sizer); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); expect(div.sizerElement).to.equal(sizer); expect(div.sizerElement.getAttribute('slot')).to.equal('i-amphtml-svc'); }); it('should allow sizer to be missing', () => { div.setAttribute('i-amphtml-layout', 'responsive'); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); expect(div.sizerElement).to.be.undefined; }); it('should allow sizer to be missing even if other children there', () => { div.setAttribute('i-amphtml-layout', 'responsive'); const other = document.createElement('div'); div.appendChild(other); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); expect(div.sizerElement).to.be.undefined; }); it('should fail when server generates invalid layout', () => { div.setAttribute('i-amphtml-layout', 'invalid'); allowConsoleError(() => { expect(() => applyStaticLayout(div)).to.throw(/failed/); }); }); it('should not re-layout cloned content', () => { div.setAttribute('layout', 'responsive'); div.setAttribute('width', 100); div.setAttribute('height', 200); expect(applyStaticLayout(div)).to.equal(Layout_Enum.RESPONSIVE); const clone = div.cloneNode(true); expect(applyStaticLayout(clone)).to.equal(Layout_Enum.RESPONSIVE); expect(div.querySelectorAll('i-amphtml-sizer')).to.have.length(1); expect(clone.querySelectorAll('i-amphtml-sizer')).to.have.length(1); }); }); describes.realWin('ampshared.css', {amp: true}, function (env) { let win, doc; let element; beforeEach(() => { win = env.win; doc = win.document; element = doc.createElement('amp-element'); element.classList.add('i-amphtml-element'); doc.body.appendChild(element); }); describe('overflow', function () { let overflow; beforeEach(() => { overflow = doc.createElement('div'); overflow.setAttribute('overflow', ''); overflow.style.height = '20px'; element.appendChild(overflow); }); it('should not allow overflow element to distort a size-defined layout', () => { element.setAttribute('layout', 'responsive'); element.setAttribute('width', 100); element.setAttribute('height', 100); expect(applyStaticLayout(element)).to.equal(Layout_Enum.RESPONSIVE); expect(element.offsetWidth).to.equal(element.offsetHeight); expect(overflow.offsetHeight).to.equal(20); expect(win.getComputedStyle(overflow).position).to.equal('absolute'); }); it('should allow overflow element to distort container layout', () => { element.setAttribute('layout', 'container'); overflow.text = 'test'; expect(applyStaticLayout(element)).to.equal(Layout_Enum.CONTAINER); expect(element.offsetHeight).to.equal(overflow.offsetHeight); expect(win.getComputedStyle(overflow).position).to.equal('relative'); }); }); });