text: defineSuite([
          'Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel',
          'Core/defined',
          'Core/getTimestamp',
          'Scene/FrameRateMonitor',
          'Specs/createScene'
      ], function(
          PerformanceWatchdogViewModel,
          defined,
          getTimestamp,
          FrameRateMonitor,
          createScene) {
      'use strict';
  
      var scene;
      beforeAll(function() {
          scene = createScene();
      });
  
      afterAll(function() {
          scene.destroyForSpecs();
      });
  
      var viewModel;
      afterEach(function() {
          if (defined(viewModel)) {
              viewModel.destroy();
              viewModel = undefined;
          }
  
          FrameRateMonitor.fromScene(scene).destroy();
      });
  
      function spinWait(milliseconds) {
          /*eslint-disable no-empty*/
          var endTime = getTimestamp() + milliseconds;
          while (getTimestamp() < endTime) {
          }
          /*eslint-enable no-empty*/
      }
  
      it('throws when constructed without a scene', function() {
          expect(function() {
              viewModel = new PerformanceWatchdogViewModel();
          }).toThrowDeveloperError();
  
          expect(function() {
              viewModel = new PerformanceWatchdogViewModel({});
          }).toThrowDeveloperError();
      });
  
      it('can be constructed with just a scene', function() {
          viewModel = new PerformanceWatchdogViewModel({
              scene : scene
          });
  
          expect(viewModel.lowFrameRateMessage).toBeDefined();
          expect(viewModel.lowFrameRateMessageDismissed).toBe(false);
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
          expect(viewModel.scene).toBe(scene);
      });
  
      it('honors parameters to the constructor', function() {
          var options = {
              scene : scene,
              lowFrameRateMessage : 'why so slow?'
          };
  
          viewModel = new PerformanceWatchdogViewModel(options);
  
          expect(viewModel.lowFrameRateMessage).toBe('why so slow?');
          expect(viewModel.scene).toBe(scene);
      });
  
      it('shows a message on low frame rate', function() {
          var monitor = FrameRateMonitor.fromScene(scene);
          monitor.quietPeriod = 0.001;
          monitor.warmupPeriod = 0.001;
          monitor.samplingWindow = 0.001;
          monitor.minimumFrameRateDuringWarmup = 1000;
          monitor.minimumFrameRateAfterWarmup = 1000;
  
          viewModel = new PerformanceWatchdogViewModel({
              scene : scene
          });
  
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
  
          // Rendering once starts the quiet period
          scene.render();
  
          // Wait until we're well past the end of the quiet period.
          spinWait(2);
  
          // Rendering again records our first sample.
          scene.render();
  
          // Wait well over a millisecond, which is the maximum frame time allowed by this instance.
          spinWait(2);
  
          // Record our second sample.  The watchdog should notice that our frame rate is too low.
          scene.render();
          expect(viewModel.showingLowFrameRateMessage).toBe(true);
      });
  
      it('does not report a low frame rate during the queit period', function() {
          var monitor = FrameRateMonitor.fromScene(scene);
          monitor.quietPeriod = 1.0;
          monitor.warmupPeriod = 0.001;
          monitor.samplingWindow = 0.001;
          monitor.minimumFrameRateDuringWarmup = 1000;
          monitor.minimumFrameRateAfterWarmup = 1000;
  
          viewModel = new PerformanceWatchdogViewModel({
              scene : scene
          });
  
          // Rendering once starts the quiet period
          scene.render();
  
          // Wait well over a millisecond, which is the maximum frame time allowed by this instance.
          spinWait(2);
  
          // Render again.  Even though our frame rate is too low, the watchdog shouldn't bark because we're in the quiet period.
          scene.render();
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
      });
  
      it('the low frame rate message goes away after the warmup period if the frame rate returns to nominal', function() {
          var monitor = FrameRateMonitor.fromScene(scene);
          monitor.quietPeriod = 0.001;
          monitor.warmupPeriod = 0.001;
          monitor.samplingWindow = 0.001;
          monitor.minimumFrameRateDuringWarmup = 10;
          monitor.minimumFrameRateAfterWarmup = 10;
  
          viewModel = new PerformanceWatchdogViewModel({
              scene : scene
          });
  
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
  
          // Rendering once starts the quiet period
          scene.render();
  
          // Wait until we're well past the end of the quiet period.
          spinWait(2);
  
          // Rendering again records our first sample.
          scene.render();
  
          // Wait 120 millseconds, which is over the maximum frame time allowed by this instance.
          spinWait(120);
  
          // Record our second sample.  The watchdog should notice that our frame rate is too low.
          scene.render();
          expect(viewModel.showingLowFrameRateMessage).toBe(true);
  
          // Render as fast as possible for a samplingWindow, quietPeriod, and warmupPeriod.
          var endTime = getTimestamp() + 50;
          while (getTimestamp() < endTime) {
              scene.render();
          }
  
          // The low frame rate message should have gone away.
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
      });
  
      it('does not show the low frame rate message again once it is dismissed', function() {
          var monitor = FrameRateMonitor.fromScene(scene);
          monitor.quietPeriod = 0.001;
          monitor.warmupPeriod = 0.001;
          monitor.samplingWindow = 0.001;
          monitor.minimumFrameRateDuringWarmup = 1000;
          monitor.minimumFrameRateAfterWarmup = 1000;
  
          viewModel = new PerformanceWatchdogViewModel({
              scene : scene
          });
  
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
  
          // Rendering once starts the quiet period
          scene.render();
  
          // Wait until we're well past the end of the quiet period.
          spinWait(2);
  
          // Rendering again records our first sample.
          scene.render();
  
          // Wait well over a millisecond, which is the maximum frame time allowed by this instance.
          spinWait(2);
  
          // Record our second sample.  The watchdog should notice that our frame rate is too low.
          scene.render();
          expect(viewModel.showingLowFrameRateMessage).toBe(true);
  
          viewModel.dismissMessage();
  
          // Render several slow frames.  The message should not re-appear.
          scene.render();
          spinWait(2);
          scene.render();
          expect(viewModel.showingLowFrameRateMessage).toBe(false);
      });
  }, 'WebGL');
  