diff --git a/src/service/resources-impl.js b/src/service/resources-impl.js index e3f142d3a984..76060d9d5822 100644 --- a/src/service/resources-impl.js +++ b/src/service/resources-impl.js @@ -257,7 +257,7 @@ export class ResourcesImpl { // When user scrolling stops, run pass to check newly in-viewport elements. // When viewport is resized, we have to re-measure everything. this.viewport_.onChanged((event) => { - this.lastScrollTime_ = Date.now(); + this.lastScrollTime_ = this.win.Date.now(); this.lastVelocity_ = event.velocity; if (event.relayoutAll) { this.relayoutAll_ = true; @@ -274,14 +274,14 @@ export class ResourcesImpl { this.schedulePass(); }); this.viewport_.onScroll(() => { - this.lastScrollTime_ = Date.now(); + this.lastScrollTime_ = this.win.Date.now(); }); // When document becomes visible, e.g. from "prerender" mode, do a // simple pass. this.ampdoc.onVisibilityChanged(() => { if (this.firstVisibleTime_ == -1 && this.ampdoc.isVisible()) { - this.firstVisibleTime_ = Date.now(); + this.firstVisibleTime_ = this.win.Date.now(); } this.schedulePass(); }); @@ -858,7 +858,7 @@ export class ResourcesImpl { // scroll adjustment to avoid active viewport changing without user's // action. The elements in the active viewport are not resized and instead // the overflow callbacks are called. - const now = Date.now(); + const now = this.win.Date.now(); const viewportRect = this.viewport_.getRect(); const topOffset = viewportRect.height / 10; const bottomOffset = viewportRect.height / 10; @@ -1186,7 +1186,7 @@ export class ResourcesImpl { discoverWork_() { // TODO(dvoytenko): vsync separation may be needed for different phases - const now = Date.now(); + const now = this.win.Date.now(); // Ensure all resources layout phase complete; when relayoutAll is requested // force re-layout. @@ -1460,7 +1460,7 @@ export class ResourcesImpl { * @private */ work_() { - const now = Date.now(); + const now = this.win.Date.now(); let timeout = -1; let task = this.queue_.peek(this.boundTaskScorer_); @@ -1613,7 +1613,7 @@ export class ResourcesImpl { * @private */ calcTaskTimeout_(task) { - const now = Date.now(); + const now = this.win.Date.now(); if (this.exec_.getSize() == 0) { // If we've never been visible, return 0. This follows the previous @@ -1787,7 +1787,7 @@ export class ResourcesImpl { Math.max(resource.getLayoutPriority(), parentPriority) + priorityOffset, forceOutsideViewport, callback, - scheduleTime: Date.now(), + scheduleTime: this.win.Date.now(), startTime: 0, promise: null, }; diff --git a/test/unit/test-mutator.js b/test/unit/test-mutator.js index eae03defb1c0..14f213ab370b 100644 --- a/test/unit/test-mutator.js +++ b/test/unit/test-mutator.js @@ -14,6 +14,7 @@ * limitations under the License. */ +import * as lolex from 'lolex'; import {AmpDocSingle} from '../../src/service/ampdoc-impl'; import {LayoutPriority} from '../../src/layout'; import {MutatorImpl} from '../../src/service/mutator-impl'; @@ -29,7 +30,54 @@ import {layoutRectLtwh} from '../../src/layout-rect'; /** @type {?Event|undefined} */ const NO_EVENT = undefined; -describe('mutator changeSize', () => { +describes.realWin('mutator changeSize', {amp: true}, (env) => { + let window, document; + let clock; + let viewportMock; + let resources, mutator; + let resource1, resource2; + + beforeEach(() => { + window = env.win; + document = window.document; + delete window.requestIdleCallback; + delete window.cancelIdleCallback; + clock = lolex.install({target: window}); + const ampdoc = new AmpDocSingle(window); + resources = new ResourcesImpl(ampdoc); + resources.isRuntimeOn_ = false; + resources.win = { + location: { + href: 'https://example.org/doc1', + }, + Date: window.Date, + getComputedStyle: (el) => { + return el.fakeComputedStyle + ? el.fakeComputedStyle + : window.getComputedStyle(el); + }, + }; + mutator = new MutatorImpl(ampdoc); + mutator.win = resources.win; + mutator.resources_ = resources; + + installPlatformService(resources.win); + const platform = Services.platformFor(resources.win); + env.sandbox.stub(platform, 'isIe').returns(false); + + installInputService(resources.win); + + viewportMock = env.sandbox.mock(mutator.viewport_); + + resource1 = createResource(1, layoutRectLtwh(10, 10, 100, 100)); + resource2 = createResource(2, layoutRectLtwh(10, 1010, 100, 100)); + resources.owners_ = [resource1, resource2]; + }); + + afterEach(() => { + viewportMock.verify(); + }); + function createElement(rect) { const signals = new Signals(); return { @@ -57,7 +105,7 @@ describe('mutator changeSize', () => { /* eslint-disable google-camelcase/google-camelcase */ contains: (unused_otherElement) => false, updateLayoutBox: () => {}, - togglePlaceholder: () => window.sandbox.spy(), + togglePlaceholder: () => env.sandbox.spy(), overflowCallback: ( unused_overflown, unused_requestedHeight, @@ -80,51 +128,10 @@ describe('mutator changeSize', () => { resource.element['__AMP__RESOURCE'] = resource; resource.state_ = ResourceState.READY_FOR_LAYOUT; resource.initialLayoutBox_ = resource.layoutBox_ = rect; - resource.changeSize = window.sandbox.spy(); + resource.changeSize = env.sandbox.spy(); return resource; } - let clock; - let viewportMock; - let resources, mutator; - let resource1, resource2; - - beforeEach(() => { - clock = window.sandbox.useFakeTimers(); - const ampdoc = new AmpDocSingle(window); - resources = new ResourcesImpl(ampdoc); - resources.isRuntimeOn_ = false; - resources.win = { - location: { - href: 'https://example.org/doc1', - }, - getComputedStyle: (el) => { - return el.fakeComputedStyle - ? el.fakeComputedStyle - : window.getComputedStyle(el); - }, - }; - mutator = new MutatorImpl(ampdoc); - mutator.win = resources.win; - mutator.resources_ = resources; - - installPlatformService(resources.win); - const platform = Services.platformFor(resources.win); - window.sandbox.stub(platform, 'isIe').returns(false); - - installInputService(resources.win); - - viewportMock = window.sandbox.mock(mutator.viewport_); - - resource1 = createResource(1, layoutRectLtwh(10, 10, 100, 100)); - resource2 = createResource(2, layoutRectLtwh(10, 1010, 100, 100)); - resources.owners_ = [resource1, resource2]; - }); - - afterEach(() => { - viewportMock.verify(); - }); - it('should schedule separate requests', () => { mutator.scheduleChangeSize_( resource1, @@ -294,8 +301,8 @@ describe('mutator changeSize', () => { it('should measure non-measured elements', () => { resource1.initialLayoutBox_ = null; - resource1.measure = window.sandbox.spy(); - resource2.measure = window.sandbox.spy(); + resource1.measure = env.sandbox.spy(); + resource2.measure = env.sandbox.spy(); mutator.scheduleChangeSize_(resource1, 111, 200, undefined, NO_EVENT, true); mutator.scheduleChangeSize_(resource2, 111, 222, undefined, NO_EVENT, true); @@ -323,7 +330,7 @@ describe('mutator changeSize', () => { let viewportRect; beforeEach(() => { - overflowCallbackSpy = window.sandbox.spy(); + overflowCallbackSpy = env.sandbox.spy(); resource1.element.overflowCallback = overflowCallbackSpy; viewportRect = {top: 2, left: 0, right: 100, bottom: 200, height: 200}; @@ -335,12 +342,12 @@ describe('mutator changeSize', () => { bottom: 50, height: 50, }; - vsyncSpy = window.sandbox.stub(mutator.vsync_, 'run'); + vsyncSpy = env.sandbox.stub(mutator.vsync_, 'run'); resources.visible_ = true; }); it('should NOT change size when height is unchanged', () => { - const callback = window.sandbox.spy(); + const callback = env.sandbox.spy(); resource1.layoutBox_ = { top: 10, left: 0, @@ -365,7 +372,7 @@ describe('mutator changeSize', () => { }); it('should NOT change size when height and margins are unchanged', () => { - const callback = window.sandbox.spy(); + const callback = env.sandbox.spy(); resource1.layoutBox_ = { top: 10, left: 0, @@ -401,7 +408,7 @@ describe('mutator changeSize', () => { }); it('should change size when margins but not height changed', () => { - const callback = window.sandbox.spy(); + const callback = env.sandbox.spy(); resource1.layoutBox_ = { top: 10, left: 0, @@ -454,7 +461,7 @@ describe('mutator changeSize', () => { .skipSafari() .run('should change size when document is invisible', () => { resources.visible_ = false; - window.sandbox + env.sandbox .stub(resources.ampdoc, 'getVisibilityState') .returns(VisibilityState.PRERENDER); mutator.scheduleChangeSize_( @@ -611,7 +618,7 @@ describe('mutator changeSize', () => { () => { viewportMock.expects('getContentHeight').returns(10000).atLeast(1); - const callback = window.sandbox.spy(); + const callback = env.sandbox.spy(); resource1.layoutBox_ = { top: 100, left: 0, diff --git a/test/unit/test-resources.js b/test/unit/test-resources.js index a0c4495d9264..6aa0fc847cab 100644 --- a/test/unit/test-resources.js +++ b/test/unit/test-resources.js @@ -14,6 +14,7 @@ * limitations under the License. */ +import * as lolex from 'lolex'; import {AmpDocSingle} from '../../src/service/ampdoc-impl'; import {LayoutPriority} from '../../src/layout'; import {Resource, ResourceState} from '../../src/service/resource'; @@ -25,12 +26,17 @@ import {layoutRectLtwh} from '../../src/layout-rect'; import {loadPromise} from '../../src/event-helper'; /*eslint "google-camelcase/google-camelcase": 0*/ -describe('Resources', () => { +describes.realWin('Resources', {amp: true}, (env) => { + let window, document; let clock; let resources; beforeEach(() => { - clock = window.sandbox.useFakeTimers(); + window = env.win; + document = window.document; + delete window.requestIdleCallback; + delete window.cancelIdleCallback; + clock = lolex.install({target: window}); resources = new ResourcesImpl(new AmpDocSingle(window)); resources.isRuntimeOn_ = false; }); @@ -41,7 +47,7 @@ describe('Resources', () => { it('should calculate correct calcTaskScore', () => { const viewportRect = layoutRectLtwh(0, 100, 300, 400); - window.sandbox.stub(resources.viewport_, 'getRect').returns(viewportRect); + env.sandbox.stub(resources.viewport_, 'getRect').returns(viewportRect); // Task 1 is right in the middle of the viewport and priority 0 const task_in_viewport_p0 = { @@ -272,7 +278,7 @@ describe('Resources', () => { applySizesAndMediaQuery: () => {}, }; resources.visible_ = false; - window.sandbox + env.sandbox .stub(resources.ampdoc, 'getVisibilityState') .returns(VisibilityState.PRERENDER); resources.scheduleLayoutOrPreload(resource, true); @@ -295,7 +301,7 @@ describe('Resources', () => { applySizesAndMediaQuery: () => {}, }; resources.visible_ = false; - window.sandbox + env.sandbox .stub(resources.ampdoc, 'getVisibilityState') .returns(VisibilityState.PRERENDER); resources.scheduleLayoutOrPreload(resource, true); @@ -318,7 +324,7 @@ describe('Resources', () => { applySizesAndMediaQuery: () => {}, }; resources.visible_ = false; - window.sandbox + env.sandbox .stub(resources.ampdoc, 'getVisibilityState') .returns(VisibilityState.HIDDEN); resources.scheduleLayoutOrPreload(resource, true);