"use strict";

suite('rb/ui/views/ScrollManagerView', function () {
  function makeElement(dimensions = {}) {
    const scratchOffset = $testsScratch.offset();
    return $('<div>').css({
      position: 'absolute',
      left: -scratchOffset.left + (dimensions.left || 0),
      top: -scratchOffset.top + (dimensions.top || 0),
      width: dimensions.width || 20,
      height: dimensions.height || 20
    }).appendTo($testsScratch);
  }
  let scrollManager;
  beforeEach(function () {
    scrollManager = new RB.ScrollManagerView();
    scrollManager.window = {
      pageXOffset: 0,
      pageYOffset: 0,
      scrollTo(x, y) {
        this.pageXOffset = x;
        this.pageYOffset = y;
      },
      requestAnimationFrame(cb) {
        cb();
      }
    };
  });
  describe('scrollToPosition', function () {
    it('Without scroll offset', function () {
      scrollManager.scrollToPosition(100);
      expect(Math.round(scrollManager.window.pageYOffset)).toBe(100);
    });
    it('With scroll offset', function () {
      scrollManager.scrollYOffset = 40;
      scrollManager.scrollToPosition(100);
      expect(Math.round(scrollManager.window.pageYOffset)).toBe(60);
    });
  });
  describe('scrollToElement', function () {
    let $el;
    beforeEach(function () {
      $el = makeElement({
        top: 50
      });
    });
    it('Without scroll offset', function () {
      scrollManager.scrollToElement($el);
      expect(Math.round(scrollManager.window.pageYOffset)).toBe(50);
    });
    it('With scroll offset', function () {
      scrollManager.scrollYOffset = 40;
      scrollManager.scrollToElement($el);
      expect(Math.round(scrollManager.window.pageYOffset)).toBe(10);
    });
  });
  describe('markUpdated', function () {
    let $el;
    beforeEach(function () {
      $el = makeElement({
        top: 50
      });
    });
    it('First in a batch', function () {
      scrollManager.window.pageYOffset = 100;
      expect(scrollManager._oldScrollY).toBe(null);
      scrollManager.markForUpdate($el);
      const pendingElement = scrollManager._pendingElements.get($el[0]);
      expect(Math.round(pendingElement.oldHeight)).toEqual(20);
      expect(Math.round(pendingElement.oldOffset.top)).toEqual(50);
      expect(Math.round(pendingElement.oldOffset.left)).toEqual(0);
      expect(scrollManager._oldScrollY).toBe(100);
    });
    it('Subsequent entries', function () {
      scrollManager._oldScrollY = 100;
      scrollManager.window.pageYOffset = 200;
      scrollManager.markForUpdate($el);
      const pendingElement = scrollManager._pendingElements.get($el[0]);
      expect(Math.round(pendingElement.oldHeight)).toEqual(20);
      expect(Math.round(pendingElement.oldOffset.top)).toEqual(50);
      expect(Math.round(pendingElement.oldOffset.left)).toEqual(0);
      expect(scrollManager._oldScrollY).toBe(100);
    });
  });
  describe('markUpdated', function () {
    let $el;
    beforeEach(function () {
      $el = makeElement({
        top: 50
      });
    });
    it('Stores correct state', function () {
      /* Disable the actual updates for this test. */
      spyOn(scrollManager.window, 'requestAnimationFrame');
      scrollManager.markForUpdate($el);
      $el.height(40);
      $el.css('top', parseInt($el.css('top'), 10) - 10);
      scrollManager.markUpdated($el);
      const el = $el[0];
      expect(scrollManager._pendingElements.get(el)).toBe(undefined);
      const element = scrollManager._elements.get(el);
      expect(Math.round(element.oldHeight)).toEqual(20);
      expect(Math.round(element.oldOffset.top)).toEqual(50);
      expect(Math.round(element.oldOffset.left)).toEqual(0);
      expect(Math.round(element.newHeight)).toEqual(40);
      expect(Math.round(element.newOffset.top)).toEqual(40);
      expect(Math.round(element.newOffset.left)).toEqual(0);
      expect(scrollManager.window.requestAnimationFrame).toHaveBeenCalled();
    });
  });
  describe('Scroll updates', function () {
    beforeEach(function () {
      spyOn(scrollManager.window, 'requestAnimationFrame');
      scrollManager.window.pageYOffset = 200;
    });
    it('Includes updates before scroll position', function () {
      const $el1 = makeElement({
        top: 10
      });
      const $el2 = makeElement({
        top: 60
      });
      const $el3 = makeElement({
        top: 70
      });

      /* Grow by 50px. */
      scrollManager.markForUpdate($el1);
      $el1.height(70);
      scrollManager.markUpdated($el1);

      /* Shrink by 10px. */
      scrollManager.markForUpdate($el2);
      $el2.height(10);
      scrollManager.markUpdated($el2);

      /* Move up 5px. */
      scrollManager.markForUpdate($el3);
      $el3.css('top', parseInt($el3.css('top'), 10) - 5);
      scrollManager.markUpdated($el3);
      scrollManager._updateScrollPos();
      expect(Math.round(scrollManager.window.pageYOffset)).toBe(235);
    });
    it('Ignores updates after scroll position', function () {
      const $el1 = makeElement({
        top: 10
      });
      const $el2 = makeElement({
        top: scrollManager.window.pageYOffset
      });
      const $el3 = makeElement({
        top: 500
      });
      scrollManager.markForUpdate($el1);
      $el1.height(30);
      scrollManager.markUpdated($el1);
      scrollManager.markForUpdate($el2);
      $el2.height(90);
      scrollManager.markUpdated($el2);
      scrollManager.markForUpdate($el3);
      $el3.height(1000);
      scrollManager.markUpdated($el3);
      scrollManager._updateScrollPos();
      expect(scrollManager.window.pageYOffset).toBe(210);
    });
  });
});

//# sourceMappingURL=scrollManagerViewTests.js.map