Ver Fonte

better rerender testing

Adam Shaw há 6 anos atrás
pai
commit
f65abdd3f1

+ 1 - 1
packages-premium

@@ -1 +1 @@
-Subproject commit c85fd5e977f5c941d580b8b60f11ddf5c7c2b920
+Subproject commit 1cd7d28cf175e8c8fa7b97abc7c9a6d6407489b6

+ 0 - 1
packages/__tests__/src/base.css

@@ -1,7 +1,6 @@
 
 body {
   margin-top: 40px;
-  text-align: center;
   font-size: 13px;
   font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
 }

+ 76 - 0
packages/__tests__/src/lib/ComponentSpy.js

@@ -0,0 +1,76 @@
+
+export default class ComponentSpy {
+
+  renderCount = 0
+  sizingCount = 0
+
+
+  constructor(ComponentClass, debugClassName) {
+    this.ComponentClass = ComponentClass
+    let origDidMount = this.origDidMount = ComponentClass.prototype.componentDidMount
+    let origDidUpdate = this.origDidUpdate = ComponentClass.prototype.componentDidUpdate
+    let origHandleSizing = null
+    let watcher = this
+
+    ComponentClass.prototype.componentDidMount = function() {
+      watcher.renderCount++
+
+      if (this.handleSizing) {
+        origHandleSizing = this.handleSizing
+        this.handleSizing = handleSizing
+      }
+
+      if (debugClassName) {
+        console.log(debugClassName + '::componentDidMount', watcher.renderCount)
+      }
+
+      if (origDidMount) {
+        origDidMount.apply(this, arguments)
+      }
+    }
+
+    ComponentClass.prototype.componentDidUpdate = function() {
+      watcher.renderCount++
+
+      if (debugClassName) {
+        console.log(debugClassName + '::componentDidUpdate', watcher.renderCount)
+      }
+
+      if (origDidUpdate) {
+        origDidUpdate.apply(this, arguments)
+      }
+    }
+
+    function handleSizing() {
+      watcher.sizingCount++
+
+      if (debugClassName) {
+        console.log(debugClassName + '::handleSizing', watcher.sizingCount)
+      }
+
+      origHandleSizing.apply(this, arguments)
+    }
+  }
+
+
+  resetCounts() {
+    this.renderCount = 0
+    this.sizingCount = 0
+  }
+
+
+  detach() {
+    let proto = this.ComponentClass.prototype
+
+    delete proto.componentDidMount
+    if (proto.componentDidMount !== this.origDidMount) {
+      proto.componentDidMount = this.origDidMount
+    }
+
+    delete proto.componentDidUpdate
+    if (proto.componentDidUpdate !== this.origDidUpdate) {
+      proto.componentDidUpdate = this.origDidUpdate
+    }
+  }
+
+}

+ 74 - 0
packages/__tests__/src/performance/daygrid-rerenders.js

@@ -0,0 +1,74 @@
+import { DayHeader } from '@fullcalendar/core'
+import { Table } from '@fullcalendar/daygrid'
+import ComponentSpy from '../lib/ComponentSpy'
+
+
+it('daygrid view rerenders well', function(done) {
+  let headerSpy = new ComponentSpy(DayHeader)
+  let gridSpy = new ComponentSpy(Table)
+  let eventRenderCnt = 0
+
+  initCalendar({
+    defaultView: 'dayGridMonth',
+    defaultDate: '2017-10-04',
+    windowResizeDelay: 0,
+    eventRender() {
+      eventRenderCnt++
+    },
+    events: [
+      { title: 'event 0', start: '2017-10-04' }
+    ]
+  })
+
+  function resetCounts() {
+    headerSpy.resetCounts()
+    gridSpy.resetCounts()
+    eventRenderCnt = 0
+  }
+
+  function expectSomeViewRendering() {
+    expect(headerSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(gridSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(gridSpy.sizingCount).toBeLessThanOrEqual(2)
+  }
+
+  function expectNoViewRendering() {
+    expect(headerSpy.renderCount).toBe(0)
+    expect(gridSpy.renderCount).toBe(0)
+    expect(gridSpy.sizingCount).toBe(0)
+  }
+
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(1)
+
+  resetCounts()
+  currentCalendar.next()
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event will be out of view
+
+  resetCounts()
+  currentCalendar.changeView('listWeek') // switch away
+  expectNoViewRendering()
+  expect(eventRenderCnt).toBe(0)
+
+  resetCounts()
+  currentCalendar.changeView('dayGridMonth') // return to view
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event still out of view
+
+  resetCounts()
+  $(window).simulate('resize')
+  setTimeout(function() {
+
+    // allow some rerendering as a result of handleSizing, but that's it
+    expect(headerSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(gridSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(gridSpy.sizingCount).toBeLessThanOrEqual(2)
+    expect(eventRenderCnt).toBe(0)
+
+    headerSpy.detach()
+    gridSpy.detach()
+
+    done()
+  }, 1) // more than windowResizeDelay
+})

+ 67 - 0
packages/__tests__/src/performance/list-rerenders.js

@@ -0,0 +1,67 @@
+import { ListView } from '@fullcalendar/list'
+import ComponentSpy from '../lib/ComponentSpy'
+
+
+it('list view rerenders well', function(done) {
+  let listSpy = new ComponentSpy(ListView)
+  let eventRenderCnt = 0
+
+  initCalendar({
+    defaultView: 'listWeek',
+    defaultDate: '2017-10-04',
+    windowResizeDelay: 0,
+    eventRender() {
+      eventRenderCnt++
+    },
+    events: [
+      { title: 'event 0', start: '2017-10-04' }
+    ]
+  })
+
+  function resetCounts() {
+    listSpy.resetCounts()
+    eventRenderCnt = 0
+  }
+
+  function expectSomeViewRendering() {
+    expect(listSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(listSpy.sizingCount).toBeLessThanOrEqual(2)
+  }
+
+  function expectNoViewRendering() {
+    expect(listSpy.renderCount).toBe(0)
+    expect(listSpy.sizingCount).toBe(0)
+  }
+
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(1)
+
+  resetCounts()
+  currentCalendar.next()
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event will be out of view
+
+  resetCounts()
+  currentCalendar.changeView('dayGridWeek') // switch away
+  expectNoViewRendering()
+  expect(eventRenderCnt).toBe(0)
+
+  resetCounts()
+  currentCalendar.changeView('timeGridWeek') // return to view
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event still out of view
+
+  resetCounts()
+  $(window).simulate('resize')
+  setTimeout(function() {
+
+    // allow some rerendering as a result of handleSizing, but that's it
+    expect(listSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(listSpy.sizingCount).toBeLessThanOrEqual(2)
+    expect(eventRenderCnt).toBe(0)
+
+    listSpy.detach()
+
+    done()
+  }, 1) // more than windowResizeDelay
+})

+ 0 - 98
packages/__tests__/src/performance/rerenders.js

@@ -1,98 +0,0 @@
-import { DayTable } from '@fullcalendar/daygrid'
-import { DayTimeCols } from '@fullcalendar/timegrid'
-import { ListView } from '@fullcalendar/list'
-
-/*
-these tests will only work as long as each component has an updateSize method
-*/
-describe('rerender performance', function() {
-
-  pushOptions({
-    defaultDate: '2017-10-04',
-    events: [
-      { title: 'event 0', start: '2017-10-04' }
-    ],
-    windowResizeDelay: 0
-  })
-
-  ;[
-    {
-      defaultView: 'dayGridMonth',
-      classes: { DayTable },
-      changeToView: 'list' // does not have DayTable!
-    },
-    {
-      defaultView: 'timeGridWeek',
-      classes: { DayTable, DayTimeCols },
-      changeToView: 'list' // does not have DayTable!
-    },
-    {
-      defaultView: 'listWeek',
-      classes: { ListView },
-      changeToView: 'dayGridMonth'
-    }
-  ].forEach(function(settings) {
-
-    $.each(settings.classes, function(className, Class) {
-
-      describe('for ' + className + ' in ' + settings.defaultView + ' view', function() {
-
-        it('calls methods a limited number of times', function(done) {
-          var calSettings = {
-            defaultView: settings.defaultView,
-            viewSkeletonRender: function() {},
-            datesRender: function() {},
-            eventRender: function() {}
-          }
-
-          var updateSize = spyOnMethod(Class, 'updateSize') // for the specific initial view
-          spyOn(calSettings, 'viewSkeletonRender') // for all views...
-          spyOn(calSettings, 'eventRender')
-          spyOn(calSettings, 'datesRender')
-
-          initCalendar(calSettings)
-
-          expect(calSettings.viewSkeletonRender.calls.count()).toBe(1)
-          expect(calSettings.datesRender.calls.count()).toBe(1)
-          expect(calSettings.eventRender.calls.count()).toBe(1)
-          expect(updateSize.calls.count()).toBe(1)
-
-          currentCalendar.changeView(settings.changeToView)
-
-          expect(calSettings.viewSkeletonRender.calls.count()).toBe(2) // +1 (switch to new view)
-          expect(calSettings.datesRender.calls.count()).toBe(2) // +1 (switch to new view)
-          expect(calSettings.eventRender.calls.count()).toBe(2) // +1 (switch to new view)
-          expect(updateSize.calls.count()).toBe(1)
-
-          currentCalendar.changeView(settings.defaultView)
-
-          expect(calSettings.viewSkeletonRender.calls.count()).toBe(3) // +1 (switch to new view)
-          expect(calSettings.datesRender.calls.count()).toBe(3) // +1 (switch to new view)
-          expect(calSettings.eventRender.calls.count()).toBe(3) // +1 (switch to new view)
-          expect(updateSize.calls.count()).toBe(2) // +1
-
-          currentCalendar.rerenderEvents()
-
-          expect(calSettings.viewSkeletonRender.calls.count()).toBe(3)
-          expect(calSettings.datesRender.calls.count()).toBe(3)
-          expect(calSettings.eventRender.calls.count()).toBe(4) // +1
-          expect(updateSize.calls.count()).toBe(3) // +1
-
-          $(window).simulate('resize')
-
-          setTimeout(function() {
-
-            expect(calSettings.viewSkeletonRender.calls.count()).toBe(3)
-            expect(calSettings.datesRender.calls.count()).toBe(3)
-            expect(calSettings.eventRender.calls.count()).toBe(4)
-            expect(updateSize.calls.count()).toBe(4) // +1
-
-            updateSize.restore()
-
-            done()
-          }, 1) // more than windowResizeDelay
-        })
-      })
-    })
-  })
-})

+ 84 - 0
packages/__tests__/src/performance/timegrid-rerenders.js

@@ -0,0 +1,84 @@
+import { DayHeader } from '@fullcalendar/core'
+import { Table } from '@fullcalendar/daygrid'
+import { TimeCols } from '@fullcalendar/timegrid'
+import ComponentSpy from '../lib/ComponentSpy'
+
+
+it('timegrid view rerenders well', function(done) {
+  let headerSpy = new ComponentSpy(DayHeader)
+  let dayGridSpy = new ComponentSpy(Table)
+  let timeGridSpy = new ComponentSpy(TimeCols)
+  let eventRenderCnt = 0
+
+  initCalendar({
+    defaultView: 'timeGridWeek',
+    defaultDate: '2017-10-04',
+    windowResizeDelay: 0,
+    eventRender() {
+      eventRenderCnt++
+    },
+    events: [
+      { title: 'event 0', start: '2017-10-04T00:00:00' }
+    ]
+  })
+
+  function resetCounts() {
+    headerSpy.resetCounts()
+    dayGridSpy.resetCounts()
+    timeGridSpy.resetCounts()
+    eventRenderCnt = 0
+  }
+
+  function expectSomeViewRendering() {
+    expect(headerSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(dayGridSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(dayGridSpy.sizingCount).toBeLessThanOrEqual(2)
+    expect(timeGridSpy.renderCount).toBeLessThanOrEqual(2)
+    expect(timeGridSpy.sizingCount).toBeLessThanOrEqual(2)
+  }
+
+  function expectNoViewRendering() {
+    expect(headerSpy.renderCount).toBe(0)
+    expect(dayGridSpy.renderCount).toBe(0)
+    expect(dayGridSpy.sizingCount).toBe(0)
+    expect(timeGridSpy.renderCount).toBe(0)
+    expect(timeGridSpy.sizingCount).toBe(0)
+  }
+
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(1)
+
+  resetCounts()
+  currentCalendar.next()
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event will be out of view
+
+  resetCounts()
+  currentCalendar.changeView('listWeek') // switch away
+  expectNoViewRendering()
+  expect(eventRenderCnt).toBe(0)
+
+  resetCounts()
+  currentCalendar.changeView('timeGridWeek') // return to view
+  expectSomeViewRendering()
+  expect(eventRenderCnt).toBe(0) // event still out of view
+
+  resetCounts()
+  $(window).simulate('resize')
+  setTimeout(function() {
+
+    // allow some rerendering as a result of handleSizing, but that's it
+    expect(headerSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(dayGridSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(dayGridSpy.sizingCount).toBeLessThanOrEqual(2)
+    expect(timeGridSpy.renderCount).toBeLessThanOrEqual(1)
+    expect(timeGridSpy.sizingCount).toBeLessThanOrEqual(2)
+    expect(eventRenderCnt).toBe(0)
+
+    headerSpy.detach()
+    dayGridSpy.detach()
+    timeGridSpy.detach()
+
+    done()
+  }, 1) // more than windowResizeDelay
+})