 7d4f2f3183
			
		
	
	7d4f2f3183
	
	
	
		
			
			The WCT tests used deprecated version on sinon. This change adds the newest version of sinon to polygerrit and update tests. Change-Id: Ic746c4afc97779974da643362e17c9c1bb1cbf48
		
			
				
	
	
		
			344 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright (C) 2017 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  * http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| import '../../../test/common-test-setup-karma.js';
 | |
| import './gr-textarea.js';
 | |
| import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 | |
| 
 | |
| const basicFixture = fixtureFromElement('gr-textarea');
 | |
| 
 | |
| const monospaceFixture = fixtureFromTemplate(html`
 | |
| <gr-textarea monospace="true"></gr-textarea>
 | |
| `);
 | |
| 
 | |
| const hideBorderFixture = fixtureFromTemplate(html`
 | |
| <gr-textarea hide-border="true"></gr-textarea>
 | |
| `);
 | |
| 
 | |
| suite('gr-textarea tests', () => {
 | |
|   let element;
 | |
| 
 | |
|   setup(() => {
 | |
|     element = basicFixture.instantiate();
 | |
|     sinon.stub(element.reporting, 'reportInteraction');
 | |
|   });
 | |
| 
 | |
|   test('monospace is set properly', () => {
 | |
|     assert.isFalse(element.classList.contains('monospace'));
 | |
|   });
 | |
| 
 | |
|   test('hideBorder is set properly', () => {
 | |
|     assert.isFalse(element.$.textarea.classList.contains('noBorder'));
 | |
|   });
 | |
| 
 | |
|   test('emoji selector is not open with the textarea lacks focus', () => {
 | |
|     element.$.textarea.selectionStart = 1;
 | |
|     element.$.textarea.selectionEnd = 1;
 | |
|     element.text = ':';
 | |
|     assert.isFalse(!element.$.emojiSuggestions.isHidden);
 | |
|   });
 | |
| 
 | |
|   test('emoji selector is not open when a general text is entered', () => {
 | |
|     MockInteractions.focus(element.$.textarea);
 | |
|     element.$.textarea.selectionStart = 9;
 | |
|     element.$.textarea.selectionEnd = 9;
 | |
|     element.text = 'some text';
 | |
|     assert.isFalse(!element.$.emojiSuggestions.isHidden);
 | |
|   });
 | |
| 
 | |
|   test('emoji selector opens when a colon is typed & the textarea has focus',
 | |
|       () => {
 | |
|         MockInteractions.focus(element.$.textarea);
 | |
|         // Needed for Safari tests. selectionStart is not updated when text is
 | |
|         // updated.
 | |
|         element.$.textarea.selectionStart = 1;
 | |
|         element.$.textarea.selectionEnd = 1;
 | |
|         element.text = ':';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(element.$.emojiSuggestions.isHidden);
 | |
|         assert.equal(element._colonIndex, 0);
 | |
|         assert.isFalse(element._hideAutocomplete);
 | |
|         assert.equal(element._currentSearchString, '');
 | |
|       });
 | |
| 
 | |
|   test('emoji selector opens when a colon is typed after space',
 | |
|       () => {
 | |
|         MockInteractions.focus(element.$.textarea);
 | |
|         // Needed for Safari tests. selectionStart is not updated when text is
 | |
|         // updated.
 | |
|         element.$.textarea.selectionStart = 2;
 | |
|         element.$.textarea.selectionEnd = 2;
 | |
|         element.text = ' :';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(element.$.emojiSuggestions.isHidden);
 | |
|         assert.equal(element._colonIndex, 1);
 | |
|         assert.isFalse(element._hideAutocomplete);
 | |
|         assert.equal(element._currentSearchString, '');
 | |
|       });
 | |
| 
 | |
|   test('emoji selector doesn\`t open when a colon is typed after character',
 | |
|       () => {
 | |
|         MockInteractions.focus(element.$.textarea);
 | |
|         // Needed for Safari tests. selectionStart is not updated when text is
 | |
|         // updated.
 | |
|         element.$.textarea.selectionStart = 5;
 | |
|         element.$.textarea.selectionEnd = 5;
 | |
|         element.text = 'test:';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isTrue(element.$.emojiSuggestions.isHidden);
 | |
|         assert.isTrue(element._hideAutocomplete);
 | |
|       });
 | |
| 
 | |
|   test('emoji selector opens when a colon is typed and some substring',
 | |
|       () => {
 | |
|         MockInteractions.focus(element.$.textarea);
 | |
|         // Needed for Safari tests. selectionStart is not updated when text is
 | |
|         // updated.
 | |
|         element.$.textarea.selectionStart = 1;
 | |
|         element.$.textarea.selectionEnd = 1;
 | |
|         element.text = ':';
 | |
|         element.$.textarea.selectionStart = 2;
 | |
|         element.$.textarea.selectionEnd = 2;
 | |
|         element.text = ':t';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(element.$.emojiSuggestions.isHidden);
 | |
|         assert.equal(element._colonIndex, 0);
 | |
|         assert.isFalse(element._hideAutocomplete);
 | |
|         assert.equal(element._currentSearchString, 't');
 | |
|       });
 | |
| 
 | |
|   test('emoji selector opens when a colon is typed in middle of text',
 | |
|       () => {
 | |
|         MockInteractions.focus(element.$.textarea);
 | |
|         // Needed for Safari tests. selectionStart is not updated when text is
 | |
|         // updated.
 | |
|         element.$.textarea.selectionStart = 1;
 | |
|         element.$.textarea.selectionEnd = 1;
 | |
|         // Since selectionStart is on Chrome set always on end of text, we
 | |
|         // stub it to 1
 | |
|         const text = ': hello';
 | |
|         sinon.stub(element.$, 'textarea').value( {
 | |
|           selectionStart: 1,
 | |
|           value: text,
 | |
|           textarea: {
 | |
|             focus: () => {},
 | |
|           },
 | |
|         });
 | |
|         element.text = text;
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(element.$.emojiSuggestions.isHidden);
 | |
|         assert.equal(element._colonIndex, 0);
 | |
|         assert.isFalse(element._hideAutocomplete);
 | |
|         assert.equal(element._currentSearchString, '');
 | |
|       });
 | |
|   test('emoji selector closes when text changes before the colon', () => {
 | |
|     const resetStub = sinon.stub(element, '_resetEmojiDropdown');
 | |
|     MockInteractions.focus(element.$.textarea);
 | |
|     flushAsynchronousOperations();
 | |
|     element.$.textarea.selectionStart = 10;
 | |
|     element.$.textarea.selectionEnd = 10;
 | |
|     element.text = 'test test ';
 | |
|     element.$.textarea.selectionStart = 12;
 | |
|     element.$.textarea.selectionEnd = 12;
 | |
|     element.text = 'test test :';
 | |
|     element.$.textarea.selectionStart = 15;
 | |
|     element.$.textarea.selectionEnd = 15;
 | |
|     element.text = 'test test :smi';
 | |
| 
 | |
|     assert.equal(element._currentSearchString, 'smi');
 | |
|     assert.isFalse(resetStub.called);
 | |
|     element.text = 'test test test :smi';
 | |
|     assert.isTrue(resetStub.called);
 | |
|   });
 | |
| 
 | |
|   test('_resetEmojiDropdown', () => {
 | |
|     const closeSpy = sinon.spy(element, 'closeDropdown');
 | |
|     element._resetEmojiDropdown();
 | |
|     assert.equal(element._currentSearchString, '');
 | |
|     assert.isTrue(element._hideAutocomplete);
 | |
|     assert.equal(element._colonIndex, null);
 | |
| 
 | |
|     element.$.emojiSuggestions.open();
 | |
|     flushAsynchronousOperations();
 | |
|     element._resetEmojiDropdown();
 | |
|     assert.isTrue(closeSpy.called);
 | |
|   });
 | |
| 
 | |
|   test('_determineSuggestions', () => {
 | |
|     const emojiText = 'tear';
 | |
|     const formatSpy = sinon.spy(element, '_formatSuggestions');
 | |
|     element._determineSuggestions(emojiText);
 | |
|     assert.isTrue(formatSpy.called);
 | |
|     assert.isTrue(formatSpy.lastCall.calledWithExactly(
 | |
|         [{dataValue: '😂', value: '😂', match: 'tears :\')',
 | |
|           text: '😂 tears :\')'},
 | |
|         {dataValue: '😢', value: '😢', match: 'tear', text: '😢 tear'},
 | |
|         ]));
 | |
|   });
 | |
| 
 | |
|   test('_formatSuggestions', () => {
 | |
|     const matchedSuggestions = [{value: '😢', match: 'tear'},
 | |
|       {value: '😂', match: 'tears'}];
 | |
|     element._formatSuggestions(matchedSuggestions);
 | |
|     assert.deepEqual(
 | |
|         [{value: '😢', dataValue: '😢', match: 'tear', text: '😢 tear'},
 | |
|           {value: '😂', dataValue: '😂', match: 'tears', text: '😂 tears'}],
 | |
|         element._suggestions);
 | |
|   });
 | |
| 
 | |
|   test('_handleEmojiSelect', () => {
 | |
|     element.$.textarea.selectionStart = 16;
 | |
|     element.$.textarea.selectionEnd = 16;
 | |
|     element.text = 'test test :tears';
 | |
|     element._colonIndex = 10;
 | |
|     const selectedItem = {dataset: {value: '😂'}};
 | |
|     const event = {detail: {selected: selectedItem}};
 | |
|     element._handleEmojiSelect(event);
 | |
|     assert.equal(element.text, 'test test 😂');
 | |
|   });
 | |
| 
 | |
|   test('_updateCaratPosition', () => {
 | |
|     element.$.textarea.selectionStart = 4;
 | |
|     element.$.textarea.selectionEnd = 4;
 | |
|     element.text = 'test';
 | |
|     element._updateCaratPosition();
 | |
|     assert.deepEqual(element.$.hiddenText.innerHTML, element.text +
 | |
|         element.$.caratSpan.outerHTML);
 | |
|   });
 | |
| 
 | |
|   test('emoji dropdown is closed when iron-overlay-closed is fired', () => {
 | |
|     const resetSpy = sinon.spy(element, '_resetEmojiDropdown');
 | |
|     element.$.emojiSuggestions.dispatchEvent(
 | |
|         new CustomEvent('dropdown-closed', {
 | |
|           composed: true, bubbles: true,
 | |
|         }));
 | |
|     assert.isTrue(resetSpy.called);
 | |
|   });
 | |
| 
 | |
|   test('_onValueChanged fires bind-value-changed', () => {
 | |
|     const listenerStub = sinon.stub();
 | |
|     const eventObject = {currentTarget: {focused: false}};
 | |
|     element.addEventListener('bind-value-changed', listenerStub);
 | |
|     element._onValueChanged(eventObject);
 | |
|     assert.isTrue(listenerStub.called);
 | |
|   });
 | |
| 
 | |
|   suite('keyboard shortcuts', () => {
 | |
|     function setupDropdown(callback) {
 | |
|       MockInteractions.focus(element.$.textarea);
 | |
|       element.$.textarea.selectionStart = 1;
 | |
|       element.$.textarea.selectionEnd = 1;
 | |
|       element.text = ':';
 | |
|       element.$.textarea.selectionStart = 1;
 | |
|       element.$.textarea.selectionEnd = 2;
 | |
|       element.text = ':1';
 | |
|       flushAsynchronousOperations();
 | |
|     }
 | |
| 
 | |
|     test('escape key', () => {
 | |
|       const resetSpy = sinon.spy(element, '_resetEmojiDropdown');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 27);
 | |
|       assert.isFalse(resetSpy.called);
 | |
|       setupDropdown();
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 27);
 | |
|       assert.isTrue(resetSpy.called);
 | |
|       assert.isFalse(!element.$.emojiSuggestions.isHidden);
 | |
|     });
 | |
| 
 | |
|     test('up key', () => {
 | |
|       const upSpy = sinon.spy(element.$.emojiSuggestions, 'cursorUp');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 38);
 | |
|       assert.isFalse(upSpy.called);
 | |
|       setupDropdown();
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 38);
 | |
|       assert.isTrue(upSpy.called);
 | |
|     });
 | |
| 
 | |
|     test('down key', () => {
 | |
|       const downSpy = sinon.spy(element.$.emojiSuggestions, 'cursorDown');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 40);
 | |
|       assert.isFalse(downSpy.called);
 | |
|       setupDropdown();
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 40);
 | |
|       assert.isTrue(downSpy.called);
 | |
|     });
 | |
| 
 | |
|     test('enter key', () => {
 | |
|       const enterSpy = sinon.spy(element.$.emojiSuggestions,
 | |
|           'getCursorTarget');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 13);
 | |
|       assert.isFalse(enterSpy.called);
 | |
|       setupDropdown();
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 13);
 | |
|       assert.isTrue(enterSpy.called);
 | |
|       flushAsynchronousOperations();
 | |
|       assert.equal(element.text, '💯');
 | |
|     });
 | |
| 
 | |
|     test('enter key - ignored on just colon without more information', () => {
 | |
|       const enterSpy = sinon.spy(element.$.emojiSuggestions,
 | |
|           'getCursorTarget');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 13);
 | |
|       assert.isFalse(enterSpy.called);
 | |
|       MockInteractions.focus(element.$.textarea);
 | |
|       element.$.textarea.selectionStart = 1;
 | |
|       element.$.textarea.selectionEnd = 1;
 | |
|       element.text = ':';
 | |
|       flushAsynchronousOperations();
 | |
|       MockInteractions.pressAndReleaseKeyOn(element.$.textarea, 13);
 | |
|       assert.isFalse(enterSpy.called);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   suite('gr-textarea monospace', () => {
 | |
|   // gr-textarea set monospace class in the ready() method.
 | |
|   // In Polymer2, ready() is called from the fixture(...) method,
 | |
|   // If ready() is called again later, some nested elements doesn't
 | |
|   // handle it correctly. A separate test-fixture is used to set
 | |
|   // properties before ready() is called.
 | |
| 
 | |
|     let element;
 | |
| 
 | |
|     setup(() => {
 | |
|       element = monospaceFixture.instantiate();
 | |
|     });
 | |
| 
 | |
|     test('monospace is set properly', () => {
 | |
|       assert.isTrue(element.classList.contains('monospace'));
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   suite('gr-textarea hideBorder', () => {
 | |
|   // gr-textarea set noBorder class in the ready() method.
 | |
|   // In Polymer2, ready() is called from the fixture(...) method,
 | |
|   // If ready() is called again later, some nested elements doesn't
 | |
|   // handle it correctly. A separate test-fixture is used to set
 | |
|   // properties before ready() is called.
 | |
| 
 | |
|     let element;
 | |
| 
 | |
|     setup(() => {
 | |
|       element = hideBorderFixture.instantiate();
 | |
|     });
 | |
| 
 | |
|     test('hideBorder is set properly', () => {
 | |
|       assert.isTrue(element.$.textarea.classList.contains('noBorder'));
 | |
|     });
 | |
|   });
 | |
| });
 | |
| 
 |