<!DOCTYPE html>
<html>

  <head>
    <link data-require="jasmine@*" data-semver="2.4.1" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.css" />
    <script data-require="jasmine@*" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
    <script data-require="jasmine@*" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
    <script data-require="jasmine@*" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>
    <script data-require="rxjs@4.1.0" data-semver="4.1.0" src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    
  </body>

</html>
// Testing throttling example
var throttleWindowDuration = 2 * 1000; /* 2 seconds */

function throttleTest() {
  var unthrottledStream = new Rx.Subject();
  var source = unthrottledStream.throttle(throttleWindowDuration);
  var result = {
    emitCounter: 0,
    unthrottledStream
  };

  var subscription = source.subscribe(
    function() {
      result.emitCounter++;
    });

  return result;
}

describe('run with test scheduler', function() {
  var testScheduler;
  var throttleSpy;

  beforeAll(function() {
    testScheduler = new Rx.TestScheduler();
    var originalThrottle = Rx.Observable.prototype.throttle;
    throttleSpy = spyOn(Rx.Observable.prototype, 'throttle')
      .and.callFake(function(dueTime) {
        return originalThrottle.call(this, dueTime, testScheduler);
      });
  });

  afterAll(function() {
    throttleSpy.and.callThrough();
  });

  it('advancing testScheduler allows to test throttling synchronously', function() {
    var throttleTestResult = throttleTest();

    //throttled stream will not emit if scheduler clock is at zero
    testScheduler.advanceBy(1);
    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    
    testScheduler.advanceBy(throttleWindowDuration);
    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    
    testScheduler.advanceBy(throttleWindowDuration);
    throttleTestResult.unthrottledStream.onNext();
    
    testScheduler.advanceBy(throttleWindowDuration);
    throttleTestResult.unthrottledStream.onNext();

    expect(throttleTestResult.emitCounter).toBe(4);
  });
});

describe('run without test scheduler', function() {
  it('without test scheduler the emit counter will stay at 1 ' 
    + 'as throttle duration is not elapsed', function() {
    var throttleTestResult = throttleTest();

    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    throttleTestResult.unthrottledStream.onNext();
    expect(throttleTestResult.emitCounter).toBe(1);
  });
});