Debounce $scope updates when typing in chat. (#8485)

Fixes #6462, by saving a bunch of time per frame. See the issue for evidence of
the win.
This commit is contained in:
Matt Handley
2017-02-27 12:19:42 -06:00
committed by Keith Holliday
parent 6d0df78441
commit 705a78e835
5 changed files with 80 additions and 11 deletions

View File

@@ -1,14 +1,14 @@
'use strict';
describe("Chat Controller", function() {
var scope, ctrl, user, $rootScope, $controller;
var scope, ctrl, user, $rootScope, $controller, $httpBackend, html;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function(_$rootScope_, _$controller_){
inject(function(_$rootScope_, _$controller_, _$compile_, _$httpBackend_){
user = specHelper.newUser();
user._id = "unique-user-id";
$rootScope = _$rootScope_;
@@ -16,13 +16,20 @@ describe("Chat Controller", function() {
scope = _$rootScope_.$new();
$controller = _$controller_;
$httpBackend = _$httpBackend_;
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = $controller('ChatCtrl', {$scope: scope});
html = _$compile_('<div><form ng-submit="postChat(group, message.content)"><textarea submit-on-meta-enter ng-model="message.content" ng-model-options="{debounce: 250}"></textarea></form></div>')(scope);
document.body.appendChild(html[0]);
ctrl = $controller('ChatCtrl', {$scope: scope, $element: html});
});
});
afterEach(function() {
html.remove();
});
describe('copyToDo', function() {
it('when copying a user message it opens modal with information from message', function() {
@@ -68,5 +75,47 @@ describe("Chat Controller", function() {
}));
});
});
it('updates model on enter key press', function() {
// Set initial state of the page with some dummy data.
scope.group = { name: 'group' };
// The main controller is going to try to fetch the template right off.
// No big deal, just return an empty string.
$httpBackend.when('GET', 'partials/main.html').respond('');
// Let the page settle, and the controllers set their initial state.
$rootScope.$digest();
// Watch for calls to postChat & make sure it doesn't do anything.
let postChatSpy = sandbox.stub(scope, 'postChat');
// Pretend we typed 'aaa' into the textarea.
var textarea = html.find('textarea');
textarea[0].value = 'aaa';
let inputEvent = new Event('input');
textarea[0].dispatchEvent(inputEvent);
// Give a change for the ng-model watchers to notice that the value in the
// textarea has changed.
$rootScope.$digest();
// Since no time has elapsed and we debounce the model change, we should
// see no model update just yet.
expect(scope.message.content).to.equal('');
// Now, press the enter key in the textarea. We use jquery here to paper
// over browser differences with initializing the keyboard event.
var keyboardEvent = jQuery.Event('keydown', {keyCode: 13, key: 'Enter', metaKey: true});
jQuery(textarea).trigger(keyboardEvent);
// Now, allow the model to update given the changes to the page still
// without letting any time elapse...
$rootScope.$digest();
// ... and nevertheless seeing the desired call to postChat with the right
// data. Yay!
postChatSpy.should.have.been.calledWith(scope.group, 'aaa');
});
});