Back to Repositories

Testing EventTarget Queue Mechanisms in Video.js

This test suite validates the EventTarget implementation in Video.js, focusing on event queuing and trigger mechanisms. It ensures proper event handling, timing, and single execution of queued events using QUnit and Sinon for time manipulation.

Test Coverage Overview

The test suite covers critical event handling functionality in the EventTarget module.

Key areas tested include:
  • Event queuing behavior with queueTrigger
  • Delayed event execution timing
  • Multiple queue request deduplication
  • Event handler attachment and removal

Implementation Analysis

The testing approach uses QUnit’s module and test structure with Sinon’s fake timers for precise time control. The implementation validates asynchronous event handling through queued triggers, ensuring events fire exactly once regardless of multiple queue requests.

Technical patterns include:
  • Sinon clock manipulation for time-based testing
  • Event handler tracking with counters
  • Setup/teardown with beforeEach/afterEach hooks

Technical Details

Testing tools and configuration:
  • QUnit as the primary testing framework
  • Sinon.js for time manipulation and fake timers
  • ES modules for importing EventTarget
  • Clock restoration in afterEach to prevent timer leaks

Best Practices Demonstrated

The test suite exemplifies strong testing practices through isolated test cases and proper cleanup.

Notable practices include:
  • Clear test case isolation
  • Proper event handler cleanup
  • Controlled time manipulation
  • Explicit assertions for both positive and negative cases
  • Consistent setup and teardown patterns

videojs/videoJs

test/unit/event-target.test.js

            
/* eslint-env qunit */
import EventTarget from '../../src/js/event-target.js';
import sinon from 'sinon';

const { test } = QUnit;

QUnit.module('EventTarget', {
  beforeEach() {
    this.clock = sinon.useFakeTimers();
  },
  afterEach() {
    this.clock.restore();
  }
});

test('EventTarget queueTrigger queues the event', function(t) {
  const et = new EventTarget();
  let changes = 0;
  const changeHandler = function() {
    changes++;
  };

  et.on('change', changeHandler);

  et.queueTrigger('change');
  t.equal(changes, 0, 'EventTarget did not trigger a change event yet');

  this.clock.tick(1);
  t.equal(changes, 1, 'EventTarget triggered a change event once the clock ticked');
  et.off('change', changeHandler);
});

test('EventTarget will only trigger event once with queueTrigger', function(t) {
  const et = new EventTarget();
  let changes = 0;
  const changeHandler = function() {
    changes++;
  };

  et.on('change', changeHandler);

  et.queueTrigger('change');
  t.equal(changes, 0, 'EventTarget did not trigger a change event yet');
  et.queueTrigger('change');
  t.equal(changes, 0, 'EventTarget did not trigger a change event yet');
  et.queueTrigger('change');
  t.equal(changes, 0, 'EventTarget did not trigger a change event yet');
  et.queueTrigger('change');

  this.clock.tick(100);
  t.equal(changes, 1, 'EventTarget *only* triggered a change event once');

  et.off('change', changeHandler);
});