<commit_before>{React, Testing, expect, _, sinon} = require './helpers/component-testing'

ScrollTo = require '../../src/components/scroll-to'

TestComponent = React.createClass
  mixins: [ScrollTo]

  render: ->
    React.createElement('div', {}, [
      React.createElement('div', {key: 'bar', id: 'bar', style: height: 1000},
        React.createElement('a', {href: '#foo'}, 'click me')
      )
      React.createElement('div', {key: 'foo', id: 'foo'}, 'a test of scrolling')
    ])
  getScrollTopOffset: 0
  getScrollDuration: 2 # speedy scroll for tests

describe 'ScrollTo Mixin', ->

  beforeEach ->
    @props =
      windowImpl:
        scroll: sinon.spy()
        location: { hash: '' }
        pageYOffset: 0
        addEventListener: sinon.spy()
        removeEventListener: sinon.spy()
        requestAnimationFrame: sinon.spy()

  it 'attaches event listeners when mounted', ->
    Testing.renderComponent( TestComponent, props: @props ).then ({element}) =>
      expect(@props.windowImpl.addEventListener).to.have.been.calledWith(
        'hashchange', element._onHashChange, false
      )

  it 'scrolls to target on page load if it exists', ->
    @props.windowImpl.location.hash = '#bar'
    Testing.renderComponent( TestComponent, props: @props ).then =>
      expect(@props.windowImpl.scroll).to.have.been.called

  it 'scrolls to an element', ->
    Testing.renderComponent( TestComponent, props: @props ).then ({dom, element}) =>
      element.scrollToElement(dom.querySelector('#foo'))
      expect(@props.windowImpl.scroll).to.have.been.called<commit_msg>add test for hash change<commit_after>{React, Testing, expect, _, sinon} = require './helpers/component-testing'

ScrollTo = require '../../src/components/scroll-to'

TestComponent = React.createClass
  mixins: [ScrollTo]

  render: ->
    React.createElement('div', {}, [
      React.createElement('div', {key: 'bar', id: 'bar', style: height: 1000},
        React.createElement('a', {href: '#foo'}, 'click me')
      )
      React.createElement('div', {key: 'foo', id: 'foo'}, 'a test of scrolling')
    ])
  getScrollTopOffset: 0
  getScrollDuration: 2 # speedy scroll for tests

describe 'ScrollTo Mixin', ->

  beforeEach ->
    # TODO clean up location and window stubs to include in `helpers/component-testing`
    windowListeners = {}

    _location =
      hash: ''
    locationStub = {}
    locationGetSet =
      get: ->
        _location.hash
      set: (value) ->
        _location.hash = value
        windowListeners.hashchange?()
    Object.defineProperty locationStub, 'hash', locationGetSet

    @props =
      windowImpl:
        scroll: sinon.spy()
        location: locationStub
        pageYOffset: 0
        requestAnimationFrame: sinon.spy()
        addEventListener: (name, callback) ->
          windowListeners[name] = callback
        removeEventListener: (name, callback) ->
          delete windowListeners[name] if windowListeners[name] is callback

  it 'scrolls to target on page load if it exists', ->
    @props.windowImpl.location.hash = '#bar'
    Testing.renderComponent( TestComponent, props: @props ).then =>
      expect(@props.windowImpl.scroll).to.have.been.called

  it 'scrolls to target on hash change', ->
    @props.windowImpl.location.hash = '#bar'
    Testing.renderComponent( TestComponent, props: @props ).then ({element, dom}) =>
      element.scrollToElement = sinon.spy()
      testHash = '#foo'
      fooDOM = dom.querySelector(testHash)

      @props.windowImpl.location.hash = testHash
      expect(element.scrollToElement).to.have.been.calledWith(fooDOM)

  it 'scrolls to an element', ->
    Testing.renderComponent( TestComponent, props: @props ).then ({dom, element}) =>
      element.scrollToElement(dom.querySelector('#foo'))
      expect(@props.windowImpl.scroll).to.have.been.called
{'fraction_non_alphanumeric': 0.14005748628168277, 'fraction_numerical': 0.0036582179252678338, 'mean_word_length': 3.2158590308370045, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4996061', 'n_tokens_mistral': 1132, 'n_tokens_neox': 1108, 'n_words': 271}