How to use raf method in Cypress

Best JavaScript code snippet using cypress

foundation.test.js

Source:foundation.test.js Github

copy

Full Screen

1/**2 * @license3 * Copyright 2017 Google Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a copy6 * of this software and associated documentation files (the "Software"), to deal7 * in the Software without restriction, including without limitation the rights8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell9 * copies of the Software, and to permit persons to whom the Software is10 * furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN21 * THE SOFTWARE.22 */23import {assert} from 'chai';24import td from 'testdouble';25import {getCorrectPropertyName} from '../../../packages/mdc-animation';26import {verifyDefaultAdapter} from '../helpers/foundation';27import {createMockRaf} from '../helpers/raf';28import {setupFoundationTest} from '../helpers/setup';29import {cssClasses} from '../../../packages/mdc-slider/constants';30import MDCSliderFoundation from '../../../packages/mdc-slider/foundation';31suite('MDCSliderFoundation');32const TRANSFORM_PROP = getCorrectPropertyName(window, 'transform');33test('exports cssClasses', () => {34 assert.property(MDCSliderFoundation, 'cssClasses');35});36test('exports strings', () => {37 assert.property(MDCSliderFoundation, 'strings');38});39test('exports numbers', () => {40 assert.property(MDCSliderFoundation, 'numbers');41});42test('default adapter returns a complete adapter implementation', () => {43 verifyDefaultAdapter(MDCSliderFoundation, [44 'hasClass', 'addClass', 'removeClass', 'getAttribute', 'setAttribute', 'removeAttribute',45 'computeBoundingRect', 'getTabIndex', 'registerInteractionHandler', 'deregisterInteractionHandler',46 'registerThumbContainerInteractionHandler', 'deregisterThumbContainerInteractionHandler',47 'registerBodyInteractionHandler', 'deregisterBodyInteractionHandler', 'registerResizeHandler',48 'deregisterResizeHandler', 'notifyInput', 'notifyChange', 'setThumbContainerStyleProperty',49 'setTrackStyleProperty', 'setMarkerValue', 'appendTrackMarkers', 'removeTrackMarkers',50 'setLastTrackMarkersStyleProperty', 'isRTL',51 ]);52});53const setupTest = () => setupFoundationTest(MDCSliderFoundation);54test('#constructor sets the default slider value to 0', () => {55 const {foundation} = setupTest();56 assert.equal(foundation.getValue(), 0);57});58test('#constructor sets the default slider max to 100', () => {59 const {foundation} = setupTest();60 assert.equal(foundation.getMax(), 100);61});62test('#constructor sets the default slider min to 0', () => {63 const {foundation} = setupTest();64 assert.equal(foundation.getMin(), 0);65});66test('#constructor sets the default slider step to 0 (no step)', () => {67 const {foundation} = setupTest();68 assert.equal(foundation.getStep(), 0);69});70test('#constructor sets the default disabled state to enabled', () => {71 const {foundation} = setupTest();72 assert.isFalse(foundation.isDisabled());73});74test('#init registers all necessary event handlers for the component', () => {75 const {foundation, mockAdapter} = setupTest();76 const {isA} = td.matchers;77 const raf = createMockRaf();78 td.when(mockAdapter.computeBoundingRect()).thenReturn({width: 0, left: 0});79 foundation.init();80 td.verify(mockAdapter.registerInteractionHandler('mousedown', isA(Function)));81 td.verify(mockAdapter.registerInteractionHandler('pointerdown', isA(Function)));82 td.verify(mockAdapter.registerInteractionHandler('touchstart', isA(Function)));83 td.verify(mockAdapter.registerInteractionHandler('keydown', isA(Function)));84 td.verify(mockAdapter.registerInteractionHandler('focus', isA(Function)));85 td.verify(mockAdapter.registerInteractionHandler('blur', isA(Function)));86 td.verify(mockAdapter.registerThumbContainerInteractionHandler('mousedown', isA(Function)));87 td.verify(mockAdapter.registerThumbContainerInteractionHandler('pointerdown', isA(Function)));88 td.verify(mockAdapter.registerThumbContainerInteractionHandler('touchstart', isA(Function)));89 td.verify(mockAdapter.registerResizeHandler(isA(Function)));90 raf.restore();91});92test('#init checks if slider is discrete and if display track markers', () => {93 const {foundation, mockAdapter} = setupTest();94 const raf = createMockRaf();95 td.when(mockAdapter.computeBoundingRect()).thenReturn({width: 100, left: 200});96 foundation.init();97 raf.flush();98 td.verify(mockAdapter.hasClass(cssClasses.IS_DISCRETE));99 td.verify(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER));100 raf.restore();101});102test('#init sets step to one if slider is discrete but step is zero', () => {103 const {foundation, mockAdapter} = setupTest();104 const raf = createMockRaf();105 td.when(mockAdapter.computeBoundingRect()).thenReturn({width: 100, left: 200});106 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);107 foundation.init();108 raf.flush();109 assert.equal(foundation.getStep(), 1);110 raf.restore();111});112test('#init performs an initial layout of the component', () => {113 const {foundation, mockAdapter} = setupTest();114 const raf = createMockRaf();115 const {anything} = td.matchers;116 td.when(mockAdapter.computeBoundingRect()).thenReturn({width: 100, left: 200});117 foundation.init();118 raf.flush();119 td.verify(mockAdapter.setThumbContainerStyleProperty(anything(), anything()));120 td.verify(mockAdapter.setTrackStyleProperty(anything(), anything()));121 raf.restore();122});123test('#destroy deregisters all component event handlers registered during init()', () => {124 const {foundation, mockAdapter} = setupTest();125 const {isA} = td.matchers;126 foundation.destroy();127 td.verify(mockAdapter.deregisterInteractionHandler('mousedown', isA(Function)));128 td.verify(mockAdapter.deregisterInteractionHandler('pointerdown', isA(Function)));129 td.verify(mockAdapter.deregisterInteractionHandler('touchstart', isA(Function)));130 td.verify(mockAdapter.deregisterInteractionHandler('keydown', isA(Function)));131 td.verify(mockAdapter.deregisterInteractionHandler('focus', isA(Function)));132 td.verify(mockAdapter.deregisterInteractionHandler('blur', isA(Function)));133 td.verify(mockAdapter.deregisterThumbContainerInteractionHandler('mousedown', isA(Function)));134 td.verify(mockAdapter.deregisterThumbContainerInteractionHandler('pointerdown', isA(Function)));135 td.verify(mockAdapter.deregisterThumbContainerInteractionHandler('touchstart', isA(Function)));136 td.verify(mockAdapter.deregisterResizeHandler(isA(Function)));137});138test('#setupTrackMarker appends correct number of markers to discrete slider with markers', () => {139 const {foundation, mockAdapter} = setupTest();140 const raf = createMockRaf();141 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});142 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);143 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);144 foundation.init();145 raf.flush();146 const numMarkers = 10;147 foundation.setMax(100);148 foundation.setMin(0);149 foundation.setStep(10);150 foundation.setupTrackMarker();151 td.verify(mockAdapter.removeTrackMarkers());152 td.verify(mockAdapter.appendTrackMarkers(numMarkers));153 raf.restore();154});155test('#setupTrackMarker append one excessive marker if distance is indivisible to step', () => {156 const {foundation, mockAdapter} = setupTest();157 const raf = createMockRaf();158 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});159 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);160 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);161 foundation.init();162 raf.flush();163 const numMarkers = 12;164 foundation.setMax(100);165 foundation.setMin(0);166 foundation.setStep(9);167 foundation.setupTrackMarker();168 td.verify(mockAdapter.removeTrackMarkers());169 td.verify(mockAdapter.appendTrackMarkers(numMarkers));170 raf.restore();171});172test('#setupTrackMarker does execute if it is continuous slider', () => {173 const {foundation, mockAdapter} = setupTest();174 const {isA} = td.matchers;175 const raf = createMockRaf();176 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});177 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(false);178 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);179 foundation.init();180 raf.flush();181 foundation.setMax(100);182 foundation.setMin(0);183 foundation.setStep(10);184 foundation.setupTrackMarker();185 td.verify(mockAdapter.removeTrackMarkers(), {times: 0});186 td.verify(mockAdapter.appendTrackMarkers(isA(Number)), {times: 0});187 raf.restore();188});189test('#setupTrackMarker does execute if discrete slider does not display markers', () => {190 const {foundation, mockAdapter} = setupTest();191 const {isA} = td.matchers;192 const raf = createMockRaf();193 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});194 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);195 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(false);196 foundation.init();197 raf.flush();198 foundation.setMax(100);199 foundation.setMin(0);200 foundation.setStep(10);201 foundation.setupTrackMarker();202 td.verify(mockAdapter.removeTrackMarkers(), {times: 0});203 td.verify(mockAdapter.appendTrackMarkers(isA(Number)), {times: 0});204 raf.restore();205});206test('#layout re-computes the bounding rect for the component on each call', () => {207 const {foundation, mockAdapter} = setupTest();208 const raf = createMockRaf();209 let numComputations = 0;210 // NOTE: Using a counter for numComputations here since we do indeed need to stub211 // getComputedBoundingRect(), but verifying a stub gives a warning from testdouble212 // (rightfully so).213 td.when(mockAdapter.computeBoundingRect()).thenDo(() => {214 numComputations++;215 return /* dummy value */ {};216 });217 foundation.layout();218 foundation.layout();219 assert.equal(numComputations, 2);220 raf.restore();221});222test('#layout re-updates the UI for the current value', () => {223 const {foundation, mockAdapter} = setupTest();224 const raf = createMockRaf();225 td.when(mockAdapter.computeBoundingRect()).thenReturn(226 {left: 0, width: 50}, {left: 0, width: 100});227 foundation.init();228 raf.flush();229 const halfMaxValue = 50;230 foundation.setValue(halfMaxValue);231 raf.flush();232 // Sanity check233 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(25px) translateX(-50%)'));234 foundation.layout();235 raf.flush();236 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(50px) translateX(-50%)'));237 raf.restore();238});239test('#getValue/#setValue retrieves / sets the max value, respectively', () => {240 const {foundation, mockAdapter} = setupTest();241 const raf = createMockRaf();242 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});243 foundation.init();244 raf.flush();245 foundation.setValue(10);246 assert.equal(foundation.getValue(), 10);247 raf.restore();248});249test('#getValue returns the current value of the slider (0 by default)', () => {250 const {foundation} = setupTest();251 assert.equal(foundation.getValue(), 0);252});253test('#setValue does nothing if the value being set is the same as the current value', () => {254 const {foundation, mockAdapter} = setupTest();255 const raf = createMockRaf();256 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});257 foundation.init();258 raf.flush();259 foundation.setValue(50);260 raf.flush();261 foundation.setValue(50);262 raf.flush();263 td.verify(264 mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(50px) translateX(-50%)'),265 {times: 1});266 raf.restore();267});268test('#setValue quantizes the given value to the nearest step value when a step is set', () => {269 const {foundation, mockAdapter} = setupTest();270 const raf = createMockRaf();271 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});272 foundation.init();273 raf.flush();274 foundation.setStep(1);275 foundation.setValue(2.4);276 assert.equal(foundation.getValue(), 2);277 foundation.setValue(2.6);278 assert.equal(foundation.getValue(), 3);279 raf.restore();280});281test('#setValue does not quantize the given value if the value is set to the minimum value', () => {282 const {foundation, mockAdapter} = setupTest();283 const raf = createMockRaf();284 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});285 foundation.init();286 raf.flush();287 foundation.setMin(5);288 foundation.setStep(10);289 foundation.setValue(5);290 assert.equal(foundation.getValue(), 5);291 raf.restore();292});293test('#setValue does not quantize the given value if the value is set to the maximum value', () => {294 const {foundation, mockAdapter} = setupTest();295 const raf = createMockRaf();296 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});297 foundation.init();298 raf.flush();299 foundation.setMax(102);300 foundation.setStep(20);301 foundation.setValue(102);302 assert.equal(foundation.getValue(), 102);303 raf.restore();304});305test('#setValue clamps the value to the minimum value if given value is less than the minimum', () => {306 const {foundation, mockAdapter} = setupTest();307 const raf = createMockRaf();308 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});309 foundation.init();310 raf.flush();311 foundation.setValue(foundation.getMin() - 1);312 assert.equal(foundation.getValue(), foundation.getMin());313 raf.restore();314});315test('#setValue clamps the value to the maximum value if given value is less than the maximum', () => {316 const {foundation, mockAdapter} = setupTest();317 const raf = createMockRaf();318 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});319 foundation.init();320 raf.flush();321 foundation.setValue(foundation.getMax() + 1);322 assert.equal(foundation.getValue(), foundation.getMax());323 raf.restore();324});325test('#setValue updates "aria-valuenow" with the current value', () => {326 const {foundation, mockAdapter} = setupTest();327 const raf = createMockRaf();328 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});329 foundation.init();330 raf.flush();331 foundation.setValue(10);332 td.verify(mockAdapter.setAttribute('aria-valuenow', '10'));333 raf.restore();334});335test('#setValue updates the slider thumb to represent the current value of the slider', () => {336 const {foundation, mockAdapter} = setupTest();337 const raf = createMockRaf();338 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});339 foundation.init();340 raf.flush();341 foundation.setValue(75);342 raf.flush();343 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(75px) translateX(-50%)'));344 raf.restore();345});346test('#setValue updates the slider track to represent the current value of the slider', () => {347 const {foundation, mockAdapter} = setupTest();348 const raf = createMockRaf();349 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});350 foundation.init();351 raf.flush();352 foundation.setValue(75);353 raf.flush();354 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.75)'));355 raf.restore();356});357test('#setValue respects the width of the slider when setting the thumb container transform', () => {358 const {foundation, mockAdapter} = setupTest();359 const raf = createMockRaf();360 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 200});361 foundation.init();362 raf.flush();363 foundation.setValue(75);364 raf.flush();365 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(150px) translateX(-50%)'));366 raf.restore();367});368test('#setValue flips the slider thumb position across the X-axis when in an RTL context', () => {369 const {foundation, mockAdapter} = setupTest();370 const raf = createMockRaf();371 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});372 td.when(mockAdapter.isRTL()).thenReturn(true);373 foundation.init();374 raf.flush();375 foundation.setValue(75);376 raf.flush();377 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(25px) translateX(-50%)'));378 raf.restore();379});380test('#setValue does not cause any events to be fired', () => {381 const {foundation, mockAdapter} = setupTest();382 const raf = createMockRaf();383 td.when(mockAdapter.computeBoundingRect()).thenReturn({width: 0, left: 0});384 foundation.init();385 raf.flush();386 foundation.setValue(20);387 td.verify(mockAdapter.notifyInput(), {times: 0});388 td.verify(mockAdapter.notifyChange(), {times: 0});389 raf.restore();390});391test('#getMax/#setMax retrieves / sets the maximum value, respectively', () => {392 const {foundation, mockAdapter} = setupTest();393 const raf = createMockRaf();394 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});395 foundation.init();396 raf.flush();397 foundation.setMax(50);398 assert.equal(foundation.getMax(), 50);399 raf.restore();400});401test('#setMax throws if the maximum value given is less than the minimum value', () => {402 const {foundation, mockAdapter} = setupTest();403 const raf = createMockRaf();404 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});405 foundation.init();406 raf.flush();407 foundation.setMin(50);408 assert.throws(() => foundation.setMax(49));409 raf.restore();410});411test('#setMax clamps the value to the new maximum if above the new maximum', () => {412 const {foundation, mockAdapter} = setupTest();413 const raf = createMockRaf();414 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});415 foundation.init();416 raf.flush();417 foundation.setValue(100);418 foundation.setMax(50);419 assert.equal(foundation.getValue(), 50);420 td.verify(mockAdapter.setAttribute('aria-valuenow', '50'));421 raf.restore();422});423test('#setMax updates the slider\'s UI when clamping the value to a new maximum', () => {424 const {foundation, mockAdapter} = setupTest();425 const raf = createMockRaf();426 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});427 foundation.init();428 raf.flush();429 foundation.setValue(50);430 raf.flush();431 // Sanity check432 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.5)'));433 foundation.setMax(50);434 raf.flush();435 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(100px) translateX(-50%)'));436 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(1)'));437 raf.restore();438});439test('#setMax updates "aria-valuemax" to the new maximum', () => {440 const {foundation, mockAdapter} = setupTest();441 const raf = createMockRaf();442 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});443 foundation.init();444 raf.flush();445 foundation.setMax(50);446 td.verify(mockAdapter.setAttribute('aria-valuemax', '50'));447 raf.restore();448});449test('#setMax re-renders track markers if slider is discrete and displays markers', () => {450 const {foundation, mockAdapter} = setupTest();451 const raf = createMockRaf();452 const {isA} = td.matchers;453 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});454 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);455 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);456 foundation.init();457 raf.flush();458 foundation.setMax(50);459 td.verify(mockAdapter.removeTrackMarkers());460 td.verify(mockAdapter.appendTrackMarkers(isA(Number)));461 raf.restore();462});463test('#getMin/#setMin retrieves / sets the minimum value, respectively', () => {464 const {foundation, mockAdapter} = setupTest();465 const raf = createMockRaf();466 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});467 foundation.init();468 raf.flush();469 foundation.setMin(10);470 assert.equal(foundation.getMin(), 10);471 raf.restore();472});473test('#setMin throws if the minimum value given is greater than the maximum value', () => {474 const {foundation, mockAdapter} = setupTest();475 const raf = createMockRaf();476 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});477 foundation.init();478 raf.flush();479 foundation.setMax(10);480 assert.throws(() => foundation.setMin(11));481 raf.restore();482});483test('#setMin clamps the value to the new minimum if above the new minimum', () => {484 const {foundation, mockAdapter} = setupTest();485 const raf = createMockRaf();486 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});487 foundation.init();488 raf.flush();489 foundation.setValue(5);490 foundation.setMin(10);491 assert.equal(foundation.getValue(), 10);492 td.verify(mockAdapter.setAttribute('aria-valuenow', '10'));493 raf.restore();494});495test('#setMin updates the slider\'s UI when clamping the value to a new minimum', () => {496 const {foundation, mockAdapter} = setupTest();497 const raf = createMockRaf();498 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});499 foundation.init();500 raf.flush();501 foundation.setValue(10);502 raf.flush();503 // Sanity check504 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.1)'));505 foundation.setMin(10);506 raf.flush();507 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(0px) translateX(-50%)'));508 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0)'));509 raf.restore();510});511test('#setMin updates "aria-valuemin" to the new minimum', () => {512 const {foundation, mockAdapter} = setupTest();513 const raf = createMockRaf();514 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});515 foundation.init();516 raf.flush();517 foundation.setMin(10);518 td.verify(mockAdapter.setAttribute('aria-valuemin', '10'));519 raf.restore();520});521test('#setMin re-renders track markers if slider is discrete and displays markers', () => {522 const {foundation, mockAdapter} = setupTest();523 const raf = createMockRaf();524 const {isA} = td.matchers;525 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});526 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);527 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);528 foundation.init();529 raf.flush();530 foundation.setMin(10);531 td.verify(mockAdapter.removeTrackMarkers());532 td.verify(mockAdapter.appendTrackMarkers(isA(Number)));533 raf.restore();534});535test('#getStep/#setStep retrieves / sets the step value, respectively', () => {536 const {foundation, mockAdapter} = setupTest();537 const raf = createMockRaf();538 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});539 foundation.init();540 raf.flush();541 foundation.setStep(2);542 assert.equal(foundation.getStep(), 2);543 raf.restore();544});545test('#setStep allows floating-point values to be used as step values', () => {546 const {foundation, mockAdapter} = setupTest();547 const raf = createMockRaf();548 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});549 foundation.init();550 raf.flush();551 foundation.setStep(0.2);552 foundation.setValue(0.46);553 assert.equal(foundation.getValue(), 0.4);554 foundation.setValue(1.52);555 assert.equal(foundation.getValue(), 1.6);556 raf.restore();557});558test('#setStep throws if the step value given is less than 0', () => {559 const {foundation, mockAdapter} = setupTest();560 const raf = createMockRaf();561 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});562 foundation.init();563 raf.flush();564 assert.throws(() => foundation.setStep(-1));565 raf.restore();566});567test('#setStep set discrete slider step to 1 if the provided step is invalid', () => {568 const {foundation, mockAdapter} = setupTest();569 const raf = createMockRaf();570 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 0});571 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);572 foundation.init();573 raf.flush();574 foundation.setStep(0.5);575 assert.equal(foundation.getStep(), 1);576 raf.restore();577});578test('#setStep updates the slider\'s UI when altering the step value', () => {579 const {foundation, mockAdapter} = setupTest();580 const raf = createMockRaf();581 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});582 foundation.init();583 raf.flush();584 foundation.setValue(9.8);585 raf.flush();586 // Sanity check587 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.098)'));588 foundation.setStep(1);589 raf.flush();590 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(10px) translateX(-50%)'));591 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.1)'));592 raf.restore();593});594test('#setStep re-renders track markers if slider is discrete and displays markers', () => {595 const {foundation, mockAdapter} = setupTest();596 const raf = createMockRaf();597 const {isA} = td.matchers;598 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});599 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);600 td.when(mockAdapter.hasClass(cssClasses.HAS_TRACK_MARKER)).thenReturn(true);601 foundation.init();602 raf.flush();603 foundation.setStep(10);604 td.verify(mockAdapter.removeTrackMarkers());605 td.verify(mockAdapter.appendTrackMarkers(isA(Number)));606 raf.restore();607});608test('#isDisabled/#setDisabled retrieves / sets the disabled state, respectively', () => {609 const {foundation} = setupTest();610 foundation.setDisabled(true);611 assert.isTrue(foundation.isDisabled());612});613test('#setDisabled adds the mdc-slider--disabled class when given true', () => {614 const {foundation, mockAdapter} = setupTest();615 foundation.setDisabled(true);616 td.verify(mockAdapter.addClass(cssClasses.DISABLED));617});618test('#setDisabled adds "aria-disabled=true" when given true', () => {619 const {foundation, mockAdapter} = setupTest();620 foundation.setDisabled(true);621 td.verify(mockAdapter.setAttribute('aria-disabled', 'true'));622});623test('#setDisabled removes the tabindex attribute when given true', () => {624 const {foundation, mockAdapter} = setupTest();625 foundation.setDisabled(true);626 td.verify(mockAdapter.removeAttribute('tabindex'));627});628test('#setDisabled removes the mdc-slider--disabled class when given false', () => {629 const {foundation, mockAdapter} = setupTest();630 foundation.setDisabled(false);631 td.verify(mockAdapter.removeClass(cssClasses.DISABLED));632});633test('#setDisabled removes the "aria-disabled" attribute when given false', () => {634 const {foundation, mockAdapter} = setupTest();635 foundation.setDisabled(false);636 td.verify(mockAdapter.removeAttribute('aria-disabled'));637});638test('#setDisabled restores any previously set tabindices when given false', () => {639 const {foundation, mockAdapter} = setupTest();640 td.when(mockAdapter.getTabIndex()).thenReturn(0);641 // Save the mock tab index set above642 foundation.setDisabled(true);643 foundation.setDisabled(false);644 td.verify(mockAdapter.setAttribute('tabindex', '0'));645});646test('#setDisabled does not touch the tabindex property if no previous tabindex saved when given false', () => {647 const {foundation, mockAdapter} = setupTest();648 foundation.setDisabled(false);649 td.verify(mockAdapter.setAttribute('tabindex', td.matchers.anything()), {times: 0});...

Full Screen

Full Screen

foundation-keyboard-events.test.js

Source:foundation-keyboard-events.test.js Github

copy

Full Screen

1/**2 * @license3 * Copyright 2017 Google Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a copy6 * of this software and associated documentation files (the "Software"), to deal7 * in the Software without restriction, including without limitation the rights8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell9 * copies of the Software, and to permit persons to whom the Software is10 * furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN21 * THE SOFTWARE.22 */23import {assert} from 'chai';24import td from 'testdouble';25import {TRANSFORM_PROP, setupEventTest as setupTest} from './helpers';26suite('MDCSliderFoundation - keyboard events');27function createFakeEvent(info = {}) {28 return Object.assign({29 preventDefault: td.func('evt.preventDefault'),30 }, info);31}32test('on arrow left keydown prevents the default behavior', () => {33 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();34 const evt = createFakeEvent({key: 'ArrowLeft'});35 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});36 foundation.init();37 raf.flush();38 rootHandlers.keydown(evt);39 raf.flush();40 td.verify(evt.preventDefault());41 raf.restore();42});43test('on arrow left keydown decreases the slider value by 1 when no step given', () => {44 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();45 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});46 foundation.init();47 raf.flush();48 foundation.setValue(50);49 raf.flush();50 rootHandlers.keydown(createFakeEvent({key: 'ArrowLeft'}));51 raf.flush();52 assert.equal(foundation.getValue(), 49);53 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));54 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));55 raf.restore();56});57test('on arrow left keydown decreases the slider value by the step amount when a step value is given', () => {58 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();59 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});60 foundation.init();61 raf.flush();62 foundation.setStep(10);63 foundation.setValue(50);64 raf.flush();65 rootHandlers.keydown(createFakeEvent({key: 'ArrowLeft'}));66 raf.flush();67 assert.equal(foundation.getValue(), 40);68 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(40px) translateX(-50%)'));69 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.4)'));70 raf.restore();71});72test('on arrow left increases the slider value when in an RTL context', () => {73 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();74 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});75 td.when(mockAdapter.isRTL()).thenReturn(true);76 foundation.init();77 raf.flush();78 foundation.setValue(50);79 raf.flush();80 rootHandlers.keydown(createFakeEvent({key: 'ArrowLeft'}));81 raf.flush();82 assert.equal(foundation.getValue(), 51);83 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));84 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));85 raf.restore();86});87test('on arrow left keydown works with keyCode', () => {88 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();89 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});90 foundation.init();91 raf.flush();92 foundation.setValue(50);93 raf.flush();94 rootHandlers.keydown(createFakeEvent({keyCode: 37}));95 raf.flush();96 assert.equal(foundation.getValue(), 49);97 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));98 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));99 raf.restore();100});101test('on arrow left keydown works with non-standard IE key propery backed with proper keyCode', () => {102 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();103 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});104 foundation.init();105 raf.flush();106 foundation.setValue(50);107 raf.flush();108 rootHandlers.keydown(createFakeEvent({key: 'Left', keyCode: 37}));109 raf.flush();110 assert.equal(foundation.getValue(), 49);111 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));112 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));113 raf.restore();114});115test('on arrow up keydown prevents the default behavior', () => {116 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();117 const evt = createFakeEvent({key: 'ArrowUp'});118 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});119 foundation.init();120 raf.flush();121 rootHandlers.keydown(evt);122 raf.flush();123 td.verify(evt.preventDefault());124 raf.restore();125});126test('on arrow up keydown increases the slider value by 1 when no step given', () => {127 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();128 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});129 foundation.init();130 raf.flush();131 foundation.setValue(50);132 raf.flush();133 rootHandlers.keydown(createFakeEvent({key: 'ArrowUp'}));134 raf.flush();135 assert.equal(foundation.getValue(), 51);136 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));137 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));138 raf.restore();139});140test('on arrow up keydown increases the slider value by the step amount when a step value is given', () => {141 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();142 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});143 foundation.init();144 raf.flush();145 foundation.setStep(10);146 foundation.setValue(50);147 raf.flush();148 rootHandlers.keydown(createFakeEvent({key: 'ArrowUp'}));149 raf.flush();150 assert.equal(foundation.getValue(), 60);151 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(60px) translateX(-50%)'));152 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.6)'));153 raf.restore();154});155test('on arrow up keydown works with keyCode', () => {156 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();157 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});158 foundation.init();159 raf.flush();160 foundation.setValue(50);161 raf.flush();162 rootHandlers.keydown(createFakeEvent({keyCode: 38}));163 raf.flush();164 assert.equal(foundation.getValue(), 51);165 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));166 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));167 raf.restore();168});169test('on arrow up keydown works with non-standard IE key propery backed with proper keyCode', () => {170 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();171 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});172 foundation.init();173 raf.flush();174 foundation.setValue(50);175 raf.flush();176 rootHandlers.keydown(createFakeEvent({key: 'Up', keyCode: 38}));177 raf.flush();178 assert.equal(foundation.getValue(), 51);179 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));180 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));181 raf.restore();182});183test('on arrow right keydown prevents the default behavior', () => {184 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();185 const evt = createFakeEvent({key: 'ArrowRight'});186 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});187 foundation.init();188 raf.flush();189 rootHandlers.keydown(evt);190 raf.flush();191 td.verify(evt.preventDefault());192 raf.restore();193});194test('on arrow right keydown increases the slider value by 1 when no step given', () => {195 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();196 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});197 foundation.init();198 raf.flush();199 foundation.setValue(50);200 raf.flush();201 rootHandlers.keydown(createFakeEvent({key: 'ArrowRight'}));202 raf.flush();203 assert.equal(foundation.getValue(), 51);204 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));205 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));206 raf.restore();207});208test('on arrow right keydown increases the slider value by the step amount when a step value is given', () => {209 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();210 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});211 foundation.init();212 raf.flush();213 foundation.setStep(10);214 foundation.setValue(50);215 raf.flush();216 rootHandlers.keydown(createFakeEvent({key: 'ArrowRight'}));217 raf.flush();218 assert.equal(foundation.getValue(), 60);219 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(60px) translateX(-50%)'));220 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.6)'));221 raf.restore();222});223test('on arrow right decreases the slider value when in an RTL context', () => {224 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();225 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});226 td.when(mockAdapter.isRTL()).thenReturn(true);227 foundation.init();228 raf.flush();229 foundation.setValue(50);230 raf.flush();231 rootHandlers.keydown(createFakeEvent({key: 'ArrowRight'}));232 raf.flush();233 assert.equal(foundation.getValue(), 49);234 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));235 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));236 raf.restore();237});238test('on arrow right keydown works with keyCode', () => {239 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();240 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});241 foundation.init();242 raf.flush();243 foundation.setValue(50);244 raf.flush();245 rootHandlers.keydown(createFakeEvent({keyCode: 39}));246 raf.flush();247 assert.equal(foundation.getValue(), 51);248 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));249 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));250 raf.restore();251});252test('on arrow right keydown works with non-standard IE key propery backed with proper keyCode', () => {253 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();254 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});255 foundation.init();256 raf.flush();257 foundation.setValue(50);258 raf.flush();259 rootHandlers.keydown(createFakeEvent({key: 'Right', keyCode: 39}));260 raf.flush();261 assert.equal(foundation.getValue(), 51);262 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(51px) translateX(-50%)'));263 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.51)'));264 raf.restore();265});266test('on arrow down keydown prevents the default behavior', () => {267 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();268 const evt = createFakeEvent({key: 'ArrowDown'});269 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});270 foundation.init();271 raf.flush();272 rootHandlers.keydown(evt);273 raf.flush();274 td.verify(evt.preventDefault());275 raf.restore();276});277test('on arrow down keydown decreases the slider value by 1 when no step given', () => {278 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();279 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});280 foundation.init();281 raf.flush();282 foundation.setValue(50);283 raf.flush();284 rootHandlers.keydown(createFakeEvent({key: 'ArrowDown'}));285 raf.flush();286 assert.equal(foundation.getValue(), 49);287 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));288 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));289 raf.restore();290});291test('on arrow down keydown decreases the slider value by the step amount when a step value is given', () => {292 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();293 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});294 foundation.init();295 raf.flush();296 foundation.setStep(10);297 foundation.setValue(50);298 raf.flush();299 rootHandlers.keydown(createFakeEvent({key: 'ArrowDown'}));300 raf.flush();301 assert.equal(foundation.getValue(), 40);302 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(40px) translateX(-50%)'));303 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.4)'));304 raf.restore();305});306test('on arrow down keydown works with keyCode', () => {307 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();308 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});309 foundation.init();310 raf.flush();311 foundation.setValue(50);312 raf.flush();313 rootHandlers.keydown(createFakeEvent({keyCode: 40}));314 raf.flush();315 assert.equal(foundation.getValue(), 49);316 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));317 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));318 raf.restore();319});320test('on arrow down keydown works with non-standard IE key propery backed with proper keyCode', () => {321 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();322 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});323 foundation.init();324 raf.flush();325 foundation.setValue(50);326 raf.flush();327 rootHandlers.keydown(createFakeEvent({key: 'Down', keyCode: 40}));328 raf.flush();329 assert.equal(foundation.getValue(), 49);330 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(49px) translateX(-50%)'));331 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.49)'));332 raf.restore();333});334test('on home keydown prevents default', () => {335 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();336 const evt = createFakeEvent({key: 'Home'});337 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});338 foundation.init();339 raf.flush();340 rootHandlers.keydown(evt);341 raf.flush();342 td.verify(evt.preventDefault());343 raf.restore();344});345test('on home keydown sets the slider to the minimum value', () => {346 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();347 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});348 foundation.init();349 raf.flush();350 foundation.setValue(50);351 raf.flush();352 rootHandlers.keydown(createFakeEvent({key: 'Home'}));353 raf.flush();354 assert.equal(foundation.getValue(), 0);355 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(0px) translateX(-50%)'));356 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0)'));357 raf.restore();358});359test('on home keydown works with keyCode', () => {360 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();361 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});362 foundation.init();363 raf.flush();364 foundation.setValue(50);365 raf.flush();366 rootHandlers.keydown(createFakeEvent({keyCode: 36}));367 raf.flush();368 assert.equal(foundation.getValue(), 0);369 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(0px) translateX(-50%)'));370 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0)'));371 raf.restore();372});373test('on end keydown prevents default', () => {374 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();375 const evt = createFakeEvent({key: 'End'});376 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});377 foundation.init();378 raf.flush();379 rootHandlers.keydown(evt);380 raf.flush();381 td.verify(evt.preventDefault());382 raf.restore();383});384test('on end keydown sets the slider to the maximum value', () => {385 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();386 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});387 foundation.init();388 raf.flush();389 foundation.setValue(50);390 raf.flush();391 rootHandlers.keydown(createFakeEvent({key: 'End'}));392 raf.flush();393 assert.equal(foundation.getValue(), 100);394 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(100px) translateX(-50%)'));395 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(1)'));396 raf.restore();397});398test('on end keydown works with keyCode', () => {399 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();400 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});401 foundation.init();402 raf.flush();403 foundation.setValue(50);404 raf.flush();405 rootHandlers.keydown(createFakeEvent({keyCode: 35}));406 raf.flush();407 assert.equal(foundation.getValue(), 100);408 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(100px) translateX(-50%)'));409 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(1)'));410 raf.restore();411});412test('on page up keydown prevents default', () => {413 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();414 const evt = createFakeEvent({key: 'PageUp'});415 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});416 foundation.init();417 raf.flush();418 rootHandlers.keydown(evt);419 raf.flush();420 td.verify(evt.preventDefault());421 raf.restore();422});423test('on page up keydown increases the slider by 4 when no step given', () => {424 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();425 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});426 foundation.init();427 raf.flush();428 foundation.setValue(50);429 raf.flush();430 rootHandlers.keydown(createFakeEvent({key: 'PageUp'}));431 raf.flush();432 assert.equal(foundation.getValue(), 54);433 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(54px) translateX(-50%)'));434 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.54)'));435 raf.restore();436});437test('on page up keydown increases the slider by 4 * the step value when a step is given', () => {438 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();439 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});440 foundation.init();441 raf.flush();442 foundation.setValue(50);443 foundation.setStep(5);444 raf.flush();445 rootHandlers.keydown(createFakeEvent({key: 'PageUp'}));446 raf.flush();447 assert.equal(foundation.getValue(), 70);448 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(70px) translateX(-50%)'));449 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.7)'));450 raf.restore();451});452test('on page up keydown works with keyCode', () => {453 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();454 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});455 foundation.init();456 raf.flush();457 foundation.setValue(50);458 raf.flush();459 rootHandlers.keydown(createFakeEvent({keyCode: 33}));460 raf.flush();461 assert.equal(foundation.getValue(), 54);462 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(54px) translateX(-50%)'));463 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.54)'));464 raf.restore();465});466test('on page down keydown prevents default', () => {467 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();468 const evt = createFakeEvent({key: 'PageDown'});469 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});470 foundation.init();471 raf.flush();472 rootHandlers.keydown(evt);473 raf.flush();474 td.verify(evt.preventDefault());475 raf.restore();476});477test('on page down keydown increases the slider by 4 when no step given', () => {478 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();479 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});480 foundation.init();481 raf.flush();482 foundation.setValue(50);483 raf.flush();484 rootHandlers.keydown(createFakeEvent({key: 'PageDown'}));485 raf.flush();486 assert.equal(foundation.getValue(), 46);487 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(46px) translateX(-50%)'));488 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.46)'));489 raf.restore();490});491test('on page down keydown increases the slider by 4 * the step value when a step is given', () => {492 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();493 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});494 foundation.init();495 raf.flush();496 foundation.setValue(50);497 foundation.setStep(5);498 raf.flush();499 rootHandlers.keydown(createFakeEvent({key: 'PageDown'}));500 raf.flush();501 assert.equal(foundation.getValue(), 30);502 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(30px) translateX(-50%)'));503 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.3)'));504 raf.restore();505});506test('on page down keydown works with keyCode', () => {507 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();508 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});509 foundation.init();510 raf.flush();511 foundation.setValue(50);512 raf.flush();513 rootHandlers.keydown(createFakeEvent({keyCode: 34}));514 raf.flush();515 assert.equal(foundation.getValue(), 46);516 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(46px) translateX(-50%)'));517 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.46)'));518 raf.restore();519});520test('on any other keydown does nothing', () => {521 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();522 const evt = createFakeEvent({key: 'Enter'});523 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});524 foundation.init();525 raf.flush();526 foundation.setValue(50);527 raf.flush();528 rootHandlers.keydown(evt);529 td.verify(evt.preventDefault(), {times: 0});530 assert.equal(foundation.getValue(), 50);...

Full Screen

Full Screen

test-vsync.js

Source:test-vsync.js Github

copy

Full Screen

1/**2 * Copyright 2015 The AMP HTML Authors. All Rights Reserved.3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 * http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS-IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16import {AmpDocShadow, installDocService} from '../../src/service/ampdoc-impl';17import {Services} from '../../src/services';18import {Vsync} from '../../src/service/vsync-impl';19import {installTimerService} from '../../src/service/timer-impl';20describe('vsync', () => {21 let sandbox;22 let clock;23 let win;24 let viewer;25 let viewerVisibilityChangedHandler;26 let docState;27 let docVisibilityHandler;28 let contextNode;29 beforeEach(() => {30 sandbox = sinon.sandbox;31 clock = sandbox.useFakeTimers();32 win = {33 document: {34 nodeType: /* DOCUMENT */ 9,35 body: {},36 },37 navigator: {38 },39 services: {},40 setTimeout: (fn, t) => {41 return window.setTimeout(fn, t);42 },43 clearTimeout: index => {44 window.clearTimeout(index);45 },46 requestAnimationFrame: window.requestAnimationFrame.bind(window),47 };48 win.document.defaultView = win;49 win.Promise = window.Promise;50 installTimerService(win);51 viewerVisibilityChangedHandler = undefined;52 viewer = {53 isVisible: () => true,54 onVisibilityChanged: handler => viewerVisibilityChangedHandler = handler,55 };56 docVisibilityHandler = undefined;57 docState = {58 isHidden: () => false,59 onVisibilityChanged: handler => docVisibilityHandler = handler,60 };61 win.services['documentState'] = {obj: docState};62 contextNode = document.createElement('div');63 document.body.appendChild(contextNode);64 });65 afterEach(() => {66 sandbox.restore();67 document.body.removeChild(contextNode);68 });69 describe('single-doc', () => {70 let ampdoc;71 let vsync;72 beforeEach(() => {73 installDocService(win, /* isSingleDoc */ true);74 ampdoc = Services.ampdocServiceFor(win).getAmpDoc();75 win.services['viewer'] = {obj: viewer};76 vsync = new Vsync(win);77 return Services.viewerPromiseForDoc(ampdoc);78 });79 afterEach(() => {80 });81 it('should init correctly', () => {82 expect(vsync.canAnimate(contextNode)).to.be.true;83 expect(viewerVisibilityChangedHandler).to.exist;84 expect(docVisibilityHandler).to.not.exist;85 });86 it('should fail canAnimate without node', () => {87 allowConsoleError(() => { expect(() => {88 vsync.canAnimate();89 }).to.throw(/Assertion failed/); });90 });91 // TODO(choumx, #12476): Make this test work with sinon 4.0.92 it.skip('should generate a frame and run callbacks', () => {93 let result = '';94 return new Promise(resolve => {95 vsync.run({96 measure: () => {97 result += 'me1';98 },99 mutate: () => {100 result += 'mu1';101 },102 });103 vsync.run({104 measure: () => {105 result += 'me2';106 },107 mutate: () => {108 result += 'mu2';109 },110 });111 vsync.run({112 measure: () => {113 result += 'me3';114 },115 });116 vsync.run({117 mutate: () => {118 result += 'mu3';119 },120 });121 vsync.mutate(() => {122 result += 'mu4';123 resolve();124 });125 vsync.measure(() => {126 result += 'me4';127 resolve();128 });129 }).then(() => {130 expect(result).to.equal('me1me2me3me4mu1mu2mu3mu4');131 });132 });133 // TODO(choumx, #12476): Make this test work with sinon 4.0.134 it.skip('should tolerate errors in measures and mutates', () => {135 let result = '';136 return new Promise(resolve => {137 vsync.run({138 measure: () => {139 result += 'me1';140 },141 mutate: () => {142 result += 'mu1';143 },144 });145 // Measure fails.146 vsync.run({147 measure: () => {148 throw new Error('intentional');149 },150 mutate: () => {151 result += 'mu2';152 },153 });154 // Mutate fails.155 vsync.run({156 measure: () => {157 result += 'me3';158 },159 mutate: () => {160 throw new Error('intentional');161 },162 });163 // Both fail.164 vsync.run({165 measure: () => {166 throw new Error('intentional');167 },168 mutate: () => {169 throw new Error('intentional');170 },171 });172 // Both succeed.173 vsync.run({174 measure: () => {175 result += 'me5';176 },177 mutate: () => {178 result += 'mu5';179 },180 });181 // Resolve.182 vsync.mutate(resolve);183 }).then(() => {184 // Notice that `mu2` is skipped becuase `me2` failed.185 expect(result).to.equal('me1me3me5mu1mu5');186 });187 });188 // TODO(choumx, #12476): Make this test work with sinon 4.0.189 it.skip('should schedule nested vsyncs', () => {190 let result = '';191 return new Promise(resolve => {192 vsync.run({193 measure: () => {194 result += 'me1';195 vsync.run({196 measure: () => {197 result += 'me2';198 },199 mutate: () => {200 result += 'mu2';201 vsync.run({202 measure: () => {203 result += 'me3';204 },205 });206 vsync.run({207 mutate: () => {208 result += 'mu3';209 resolve();210 },211 });212 },213 });214 },215 mutate: () => {216 result += 'mu1';217 },218 });219 }).then(() => {220 expect(result).to.equal('me1mu1me2mu2me3mu3');221 });222 });223 // TODO(choumx, #12476): Make this test work with sinon 4.0.224 it.skip('should return a promise from runPromise that ' +225 'executes "run"', () => {226 const measureSpy = sandbox.spy();227 const mutateSpy = sandbox.spy();228 return vsync.runPromise({measure: measureSpy, mutate: mutateSpy})229 .then(() => {230 expect(mutateSpy).to.be.calledOnce;231 expect(measureSpy).to.be.calledOnce;232 });233 });234 // TODO(choumx, #12476): Make this test work with sinon 4.0.235 it.skip('should return a promise from measurePromise ' +236 'that runs measurer', () => {237 let measured = false;238 return vsync.measurePromise(() => {239 measured = true;240 }).then(() => {241 expect(measured).to.be.true;242 });243 });244 // TODO(choumx, #12476): Make this test work with sinon 4.0.245 it.skip('should return a promise from mutatePromise' +246 'that runs mutator', () => {247 const mutator = sandbox.spy();248 return vsync.mutatePromise(mutator).then(() => {249 expect(mutator).to.be.calledOnce;250 });251 });252 it('should schedule via animation frames when doc is visible', () => {253 let rafHandler;254 vsync.raf_ = handler => rafHandler = handler;255 viewer.isVisible = () => true;256 let result = '';257 vsync.run({258 mutate: () => {259 result += 'mu1';260 },261 });262 expect(vsync.tasks_).to.have.length(1);263 expect(vsync.scheduled_).to.be.true;264 expect(rafHandler).to.exist;265 expect(vsync.invisiblePass_.isPending()).to.be.false;266 expect(vsync.backupPass_.isPending()).to.be.true;267 rafHandler();268 expect(result).to.equal('mu1');269 expect(vsync.tasks_).to.have.length(0);270 expect(vsync.scheduled_).to.be.false;271 expect(vsync.invisiblePass_.isPending()).to.be.false;272 expect(vsync.backupPass_.isPending()).to.be.false;273 });274 it('should schedule via timer frames when doc is not visible', () => {275 let rafHandler;276 vsync.raf_ = handler => rafHandler = handler;277 viewer.isVisible = () => false;278 let result = '';279 vsync.run({280 mutate: () => {281 result += 'mu1';282 },283 });284 expect(vsync.tasks_).to.have.length(1);285 expect(vsync.scheduled_).to.be.true;286 expect(rafHandler).to.be.undefined;287 expect(vsync.invisiblePass_.isPending()).to.be.true;288 clock.tick(17);289 expect(result).to.equal('mu1');290 expect(vsync.tasks_).to.have.length(0);291 expect(vsync.scheduled_).to.be.false;292 expect(vsync.invisiblePass_.isPending()).to.be.false;293 });294 it('should run via backup timer if rAF somehow doesnt fire', () => {295 let rafHandler;296 vsync.raf_ = function() {297 // intentionally empty298 };299 viewer.isVisible = () => true;300 let result = '';301 vsync.run({302 mutate: () => {303 result += 'mu1';304 },305 });306 expect(vsync.tasks_).to.have.length(1);307 expect(vsync.scheduled_).to.be.true;308 expect(rafHandler).to.be.undefined;309 expect(vsync.invisiblePass_.isPending()).to.be.false;310 expect(vsync.backupPass_.isPending()).to.be.true;311 clock.tick(17);312 expect(result).to.equal('');313 expect(vsync.tasks_).to.have.length(1);314 expect(vsync.scheduled_).to.be.true;315 expect(vsync.invisiblePass_.isPending()).to.be.false;316 expect(vsync.backupPass_.isPending()).to.be.true;317 clock.tick(240);318 expect(result).to.equal('mu1');319 expect(vsync.tasks_).to.have.length(0);320 expect(vsync.scheduled_).to.be.false;321 expect(vsync.invisiblePass_.isPending()).to.be.false;322 expect(vsync.backupPass_.isPending()).to.be.false;323 });324 it('should re-schedule when doc goes invisible', () => {325 let rafHandler;326 vsync.raf_ = handler => rafHandler = handler;327 viewer.isVisible = () => true;328 let result = '';329 vsync.run({330 mutate: () => {331 result += 'mu1';332 },333 });334 expect(vsync.tasks_).to.have.length(1);335 expect(vsync.scheduled_).to.be.true;336 expect(rafHandler).to.exist;337 expect(vsync.invisiblePass_.isPending()).to.be.false;338 viewer.isVisible = () => false;339 viewerVisibilityChangedHandler();340 expect(vsync.tasks_).to.have.length(1);341 expect(vsync.scheduled_).to.be.true;342 expect(vsync.invisiblePass_.isPending()).to.be.true;343 clock.tick(17);344 expect(result).to.equal('mu1');345 expect(vsync.tasks_).to.have.length(0);346 expect(vsync.scheduled_).to.be.false;347 expect(vsync.invisiblePass_.isPending()).to.be.false;348 });349 it('should re-schedule when doc goes visible', () => {350 let rafHandler;351 vsync.raf_ = handler => rafHandler = handler;352 viewer.isVisible = () => false;353 let result = '';354 vsync.run({355 mutate: () => {356 result += 'mu1';357 },358 });359 expect(vsync.tasks_).to.have.length(1);360 expect(vsync.scheduled_).to.be.true;361 expect(rafHandler).to.be.undefined;362 expect(vsync.invisiblePass_.isPending()).to.be.true;363 viewer.isVisible = () => true;364 viewerVisibilityChangedHandler();365 expect(vsync.tasks_).to.have.length(1);366 expect(vsync.scheduled_).to.be.true;367 expect(rafHandler).to.exist;368 rafHandler();369 expect(result).to.equal('mu1');370 expect(vsync.tasks_).to.have.length(0);371 expect(vsync.scheduled_).to.be.false;372 });373 it('should NOT re-schedule when no tasks pending', () => {374 let rafHandler;375 vsync.raf_ = handler => rafHandler = handler;376 viewer.isVisible = () => true;377 expect(vsync.tasks_).to.have.length(0);378 expect(vsync.scheduled_).to.be.false;379 expect(rafHandler).to.be.undefined;380 expect(vsync.invisiblePass_.isPending()).to.be.false;381 viewer.isVisible = () => false;382 viewerVisibilityChangedHandler();383 expect(vsync.tasks_).to.have.length(0);384 expect(vsync.scheduled_).to.be.false;385 expect(rafHandler).to.be.undefined;386 expect(vsync.invisiblePass_.isPending()).to.be.false;387 });388 it('should run anim task when visible', () => {389 let rafHandler;390 vsync.raf_ = handler => rafHandler = handler;391 viewer.isVisible = () => true;392 let result = '';393 const res = vsync.runAnim(contextNode, {394 mutate: () => {395 result += 'mu1';396 },397 });398 expect(res).to.be.true;399 expect(rafHandler).to.exist;400 expect(vsync.scheduled_).to.be.true;401 rafHandler();402 expect(result).to.equal('mu1');403 });404 it('should create and run anim task when visible', () => {405 let rafHandler;406 vsync.raf_ = handler => rafHandler = handler;407 viewer.isVisible = () => true;408 let result = '';409 const task = vsync.createAnimTask(contextNode, {410 mutate: () => {411 result += 'mu1';412 },413 });414 const res = task();415 expect(res).to.be.true;416 expect(rafHandler).to.exist;417 expect(vsync.scheduled_).to.be.true;418 rafHandler();419 expect(result).to.equal('mu1');420 });421 it('should NOT run anim task when invisible', () => {422 let rafHandler;423 vsync.raf_ = handler => rafHandler = handler;424 viewer.isVisible = () => false;425 let result = ''; // eslint-disable-line no-unused-vars426 const res = vsync.runAnim(contextNode, {427 mutate: () => {428 result += 'mu1';429 },430 });431 expect(res).to.be.false;432 expect(rafHandler).to.be.undefined;433 expect(vsync.scheduled_).to.be.false;434 });435 it('should create but NOT run anim task when invisible', () => {436 let rafHandler;437 vsync.raf_ = handler => rafHandler = handler;438 viewer.isVisible = () => false;439 let result = ''; // eslint-disable-line no-unused-vars440 const task = vsync.createAnimTask(contextNode, {441 mutate: () => {442 result += 'mu1';443 },444 });445 const res = task();446 expect(res).to.be.false;447 expect(rafHandler).to.be.undefined;448 expect(vsync.scheduled_).to.be.false;449 });450 it('should reject mutate series when invisible', () => {451 viewer.isVisible = () => false;452 const mutatorSpy = sandbox.spy();453 const promise = vsync.runAnimMutateSeries(contextNode, mutatorSpy);454 return promise.then(() => {455 return 'SUCCESS';456 }, error => {457 return 'ERROR: ' + error;458 }).then(response => {459 expect(response).to.match(/^ERROR/);460 expect(mutatorSpy).to.have.not.been.called;461 });462 });463 describe('RAF polyfill', () => {464 let vsync;465 beforeEach(() => {466 delete win.requestAnimationFrame;467 vsync = new Vsync(win);468 });469 it('should schedule frames using the polyfill', () => {470 let calls = 0;471 vsync.mutate(() => {472 calls++;473 });474 clock.tick(15);475 vsync.mutate(() => {476 calls++;477 });478 expect(calls).to.equal(0);479 clock.tick(1);480 expect(calls).to.equal(2);481 clock.tick(10);482 vsync.mutate(() => {483 calls++;484 });485 expect(calls).to.equal(2);486 clock.tick(6);487 expect(calls).to.equal(3);488 });489 });490 });491 describe('multi-doc', () => {492 let root;493 let ampdoc;494 let vsync;495 beforeEach(() => {496 installDocService(win, /* isSingleDoc */ false);497 root = document.createElement('i-amphtml-shadow-root');498 document.body.appendChild(root);499 ampdoc = new AmpDocShadow(win, 'https://acme.org/', root);500 ampdoc.services = {};501 ampdoc.services['viewer'] = {obj: viewer};502 contextNode.ampdoc_ = ampdoc;503 vsync = new Vsync(win);504 });505 afterEach(() => {506 document.body.removeChild(root);507 });508 it('should init correctly', () => {509 expect(vsync.canAnimate(contextNode)).to.be.true;510 expect(docVisibilityHandler).to.exist;511 expect(viewerVisibilityChangedHandler).to.not.exist;512 });513 it('should schedule via animation frames when doc is visible', () => {514 let rafHandler;515 vsync.raf_ = handler => rafHandler = handler;516 viewer.isVisible = () => true;517 let result = '';518 vsync.run({519 mutate: () => {520 result += 'mu1';521 },522 });523 expect(vsync.tasks_).to.have.length(1);524 expect(vsync.scheduled_).to.be.true;525 expect(rafHandler).to.exist;526 expect(vsync.invisiblePass_.isPending()).to.be.false;527 rafHandler();528 expect(result).to.equal('mu1');529 expect(vsync.tasks_).to.have.length(0);530 expect(vsync.scheduled_).to.be.false;531 });532 it('should schedule via timer frames when doc is not visible', () => {533 let rafHandler;534 vsync.raf_ = handler => rafHandler = handler;535 docState.isHidden = () => true;536 let result = '';537 vsync.run({538 mutate: () => {539 result += 'mu1';540 },541 });542 expect(vsync.tasks_).to.have.length(1);543 expect(vsync.scheduled_).to.be.true;544 expect(rafHandler).to.be.undefined;545 expect(vsync.invisiblePass_.isPending()).to.be.true;546 clock.tick(17);547 expect(result).to.equal('mu1');548 expect(vsync.tasks_).to.have.length(0);549 expect(vsync.scheduled_).to.be.false;550 expect(vsync.invisiblePass_.isPending()).to.be.false;551 });552 it('should re-schedule when doc goes invisible', () => {553 let rafHandler;554 vsync.raf_ = handler => rafHandler = handler;555 docState.isHidden = () => false;556 let result = '';557 vsync.run({558 mutate: () => {559 result += 'mu1';560 },561 });562 expect(vsync.tasks_).to.have.length(1);563 expect(vsync.scheduled_).to.be.true;564 expect(rafHandler).to.exist;565 expect(vsync.invisiblePass_.isPending()).to.be.false;566 docState.isHidden = () => true;567 docVisibilityHandler();568 expect(vsync.tasks_).to.have.length(1);569 expect(vsync.scheduled_).to.be.true;570 expect(vsync.invisiblePass_.isPending()).to.be.true;571 clock.tick(17);572 expect(result).to.equal('mu1');573 expect(vsync.tasks_).to.have.length(0);574 expect(vsync.scheduled_).to.be.false;575 expect(vsync.invisiblePass_.isPending()).to.be.false;576 });577 it('should re-schedule when doc goes visible', () => {578 let rafHandler;579 vsync.raf_ = handler => rafHandler = handler;580 docState.isHidden = () => true;581 let result = '';582 vsync.run({583 mutate: () => {584 result += 'mu1';585 },586 });587 expect(vsync.tasks_).to.have.length(1);588 expect(vsync.scheduled_).to.be.true;589 expect(rafHandler).to.be.undefined;590 expect(vsync.invisiblePass_.isPending()).to.be.true;591 docState.isHidden = () => false;592 docVisibilityHandler();593 expect(vsync.tasks_).to.have.length(1);594 expect(vsync.scheduled_).to.be.true;595 expect(rafHandler).to.exist;596 rafHandler();597 expect(result).to.equal('mu1');598 expect(vsync.tasks_).to.have.length(0);599 expect(vsync.scheduled_).to.be.false;600 });601 it('should NOT re-schedule when no tasks pending', () => {602 let rafHandler;603 vsync.raf_ = handler => rafHandler = handler;604 docState.isHidden = () => false;605 expect(vsync.tasks_).to.have.length(0);606 expect(vsync.scheduled_).to.be.false;607 expect(rafHandler).to.be.undefined;608 expect(vsync.invisiblePass_.isPending()).to.be.false;609 docState.isHidden = () => true;610 docVisibilityHandler();611 expect(vsync.tasks_).to.have.length(0);612 expect(vsync.scheduled_).to.be.false;613 expect(rafHandler).to.be.undefined;614 expect(vsync.invisiblePass_.isPending()).to.be.false;615 });616 it('should run anim task when visible', () => {617 let rafHandler;618 vsync.raf_ = handler => rafHandler = handler;619 docState.isHidden = () => false;620 let result = '';621 const res = vsync.runAnim(contextNode, {622 mutate: () => {623 result += 'mu1';624 },625 });626 expect(res).to.be.true;627 expect(rafHandler).to.exist;628 expect(vsync.scheduled_).to.be.true;629 rafHandler();630 expect(result).to.equal('mu1');631 });632 it('should create and run anim task when visible', () => {633 let rafHandler;634 vsync.raf_ = handler => rafHandler = handler;635 docState.isHidden = () => false;636 let result = '';637 const task = vsync.createAnimTask(contextNode, {638 mutate: () => {639 result += 'mu1';640 },641 });642 const res = task();643 expect(res).to.be.true;644 expect(rafHandler).to.exist;645 expect(vsync.scheduled_).to.be.true;646 rafHandler();647 expect(result).to.equal('mu1');648 });649 it('should NOT run anim task when invisible', () => {650 let rafHandler;651 vsync.raf_ = handler => rafHandler = handler;652 docState.isHidden = () => true;653 let result = ''; // eslint-disable-line no-unused-vars654 const res = vsync.runAnim(contextNode, {655 mutate: () => {656 result += 'mu1';657 },658 });659 expect(res).to.be.false;660 expect(rafHandler).to.be.undefined;661 expect(vsync.scheduled_).to.be.false;662 });663 it('should create but NOT run anim task when invisible', () => {664 let rafHandler;665 vsync.raf_ = handler => rafHandler = handler;666 docState.isHidden = () => true;667 let result = ''; // eslint-disable-line no-unused-vars668 const task = vsync.createAnimTask(contextNode, {669 mutate: () => {670 result += 'mu1';671 },672 });673 const res = task();674 expect(res).to.be.false;675 expect(rafHandler).to.be.undefined;676 expect(vsync.scheduled_).to.be.false;677 });678 it('should reject mutate series when invisible', () => {679 docState.isHidden = () => true;680 const mutatorSpy = sandbox.spy();681 const promise = vsync.runAnimMutateSeries(contextNode, mutatorSpy);682 return promise.then(() => {683 return 'SUCCESS';684 }, error => {685 return 'ERROR: ' + error;686 }).then(response => {687 expect(response).to.match(/^ERROR/);688 expect(mutatorSpy).to.have.not.been.called;689 });690 });691 });...

Full Screen

Full Screen

foundation-pointer-events.test.js

Source:foundation-pointer-events.test.js Github

copy

Full Screen

1/**2 * @license3 * Copyright 2017 Google Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a copy6 * of this software and associated documentation files (the "Software"), to deal7 * in the Software without restriction, including without limitation the rights8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell9 * copies of the Software, and to permit persons to whom the Software is10 * furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN21 * THE SOFTWARE.22 */23import {assert} from 'chai';24import td from 'testdouble';25import {getCorrectEventName} from '../../../packages/mdc-animation';26import {cssClasses} from '../../../packages/mdc-slider/constants';27import {TRANSFORM_PROP, setupEventTest as setupTest} from './helpers';28suite('MDCSliderFoundation - pointer events');29const TRANSITION_END_EVT = getCorrectEventName(window, 'transitionend');30createTestSuiteForPointerEvents('mousedown', 'mousemove', 'mouseup');31createTestSuiteForPointerEvents('pointerdown', 'pointermove', 'pointerup');32createTestSuiteForPointerEvents('touchstart', 'touchmove', 'touchend', (pageX) => ({targetTouches: [{pageX}]}));33function createTestSuiteForPointerEvents(downEvt, moveEvt, upEvt, pageXObj = (pageX) => ({pageX})) {34 test(`on ${downEvt} sets the value of the slider using the X coordinate of the event`, () => {35 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();36 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});37 foundation.init();38 raf.flush();39 rootHandlers[downEvt](pageXObj(50));40 raf.flush();41 assert.equal(foundation.getValue(), 50);42 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(50px) translateX(-50%)'));43 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.5)'));44 raf.restore();45 });46 test(`on ${downEvt} offsets the value by the X position of the slider element`, () => {47 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();48 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 10, width: 100});49 foundation.init();50 raf.flush();51 rootHandlers[downEvt](pageXObj(50));52 raf.flush();53 assert.equal(foundation.getValue(), 40);54 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(40px) translateX(-50%)'));55 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.4)'));56 raf.restore();57 });58 test(`on ${downEvt} takes RTL into account when computing the slider\'s value using the X ` +59 'coordinate of the event', () => {60 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();61 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});62 td.when(mockAdapter.isRTL()).thenReturn(true);63 foundation.init();64 raf.flush();65 rootHandlers[downEvt](pageXObj(25));66 raf.flush();67 assert.equal(foundation.getValue(), 75);68 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(25px) translateX(-50%)'));69 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.75)'));70 raf.restore();71 });72 test(`on ${downEvt} adds the mdc-slider--active class to the root element`, () => {73 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();74 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});75 foundation.init();76 raf.flush();77 rootHandlers[downEvt](pageXObj(50));78 raf.flush();79 td.verify(mockAdapter.addClass(cssClasses.ACTIVE));80 raf.restore();81 });82 test(`on ${downEvt} adds mdc-slider--in-transit class to the root element if the thumb container ` +83 'isn\'t the target', () => {84 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();85 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});86 foundation.init();87 raf.flush();88 rootHandlers[downEvt](pageXObj(50));89 raf.flush();90 td.verify(mockAdapter.addClass(cssClasses.IN_TRANSIT));91 raf.restore();92 });93 test(`on ${downEvt} does not add mdc-slider--in-transit class to the root element if the thumb container ` +94 'is the target', () => {95 const {foundation, mockAdapter, raf, thumbContainerHandlers} = setupTest();96 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});97 foundation.init();98 raf.flush();99 thumbContainerHandlers[downEvt](pageXObj(2));100 raf.flush();101 td.verify(mockAdapter.addClass(cssClasses.IN_TRANSIT), {times: 0});102 raf.restore();103 });104 test(`on ${downEvt} removes the mdc-slider--in-transit class when the thumb container finishes transitioning`, () => {105 const {foundation, mockAdapter, raf, rootHandlers, thumbContainerHandlers} = setupTest();106 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});107 foundation.init();108 raf.flush();109 rootHandlers[downEvt](pageXObj(2));110 raf.flush();111 // Sanity check112 td.verify(mockAdapter.addClass(cssClasses.IN_TRANSIT));113 thumbContainerHandlers[TRANSITION_END_EVT]();114 td.verify(mockAdapter.removeClass(cssClasses.IN_TRANSIT));115 raf.restore();116 });117 test(`on ${downEvt} notifies the client of an input event`, () => {118 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();119 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});120 foundation.init();121 raf.flush();122 rootHandlers[downEvt](pageXObj(50));123 raf.flush();124 td.verify(mockAdapter.notifyInput());125 raf.restore();126 });127 test(`on ${downEvt} notifies discrete slider pin value marker to change value`, () => {128 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();129 const {isA} = td.matchers;130 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});131 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);132 foundation.init();133 raf.flush();134 rootHandlers[downEvt](pageXObj(50));135 raf.flush();136 td.verify(mockAdapter.setMarkerValue(isA(Number)));137 raf.restore();138 });139 test(`on ${downEvt} attaches event handlers for ${moveEvt} and all *up/end events to the document body`, () => {140 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();141 const {isA} = td.matchers;142 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});143 foundation.init();144 raf.flush();145 rootHandlers[downEvt](pageXObj(50));146 raf.flush();147 td.verify(mockAdapter.registerBodyInteractionHandler(moveEvt, isA(Function)));148 td.verify(mockAdapter.registerBodyInteractionHandler('mouseup', isA(Function)));149 td.verify(mockAdapter.registerBodyInteractionHandler('pointerup', isA(Function)));150 td.verify(mockAdapter.registerBodyInteractionHandler('touchend', isA(Function)));151 raf.restore();152 });153 test('on ${downEvt} does nothing if the component is disabled', () => {154 const {foundation, mockAdapter, raf, rootHandlers} = setupTest();155 const {anything} = td.matchers;156 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});157 foundation.init();158 raf.flush();159 const valueBeforeEvent = foundation.getValue();160 foundation.setDisabled(true);161 rootHandlers[downEvt](pageXObj(50));162 raf.flush();163 assert.equal(foundation.getValue(), valueBeforeEvent);164 td.verify(mockAdapter.addClass(cssClasses.ACTIVE), {times: 0});165 // These should only happen once during initialization166 td.verify(mockAdapter.setThumbContainerStyleProperty(anything(), anything()), {times: 1});167 td.verify(mockAdapter.setTrackStyleProperty(anything(), anything()), {times: 1});168 raf.restore();169 });170 test(`on body ${moveEvt} prevents default behavior`, () => {171 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();172 const preventDefault = td.func('evt.preventDefault');173 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});174 foundation.init();175 raf.flush();176 rootHandlers[downEvt](pageXObj(49));177 bodyHandlers[moveEvt](178 Object.assign({preventDefault}, pageXObj(50))179 );180 raf.flush();181 td.verify(preventDefault());182 raf.restore();183 });184 test(`on body ${moveEvt} updates the slider\'s value based on the X coordinate of the event`, () => {185 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();186 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});187 foundation.init();188 raf.flush();189 rootHandlers[downEvt](pageXObj(49));190 bodyHandlers[moveEvt](Object.assign({191 preventDefault: () => {},192 }, pageXObj(50)));193 raf.flush();194 assert.equal(foundation.getValue(), 50);195 td.verify(mockAdapter.setThumbContainerStyleProperty(TRANSFORM_PROP, 'translateX(50px) translateX(-50%)'));196 td.verify(mockAdapter.setTrackStyleProperty(TRANSFORM_PROP, 'scaleX(0.5)'));197 raf.restore();198 });199 test(`on body ${moveEvt} notifies the client of an input event`, () => {200 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();201 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});202 foundation.init();203 raf.flush();204 rootHandlers[downEvt](pageXObj(49));205 bodyHandlers[moveEvt](Object.assign({206 preventDefault: () => {},207 }, pageXObj(50)));208 raf.flush();209 // Once on mousedown, once on mousemove210 td.verify(mockAdapter.notifyInput(), {times: 2});211 raf.restore();212 });213 test(`on body ${moveEvt} notifies discrete slider pin value marker to change value`, () => {214 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();215 const {isA} = td.matchers;216 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});217 td.when(mockAdapter.hasClass(cssClasses.IS_DISCRETE)).thenReturn(true);218 foundation.init();219 raf.flush();220 rootHandlers[downEvt](pageXObj(49));221 bodyHandlers[moveEvt](Object.assign({222 preventDefault: () => {},223 }, pageXObj(50)));224 raf.flush();225 // Once on mousedown, once on mousemove226 td.verify(mockAdapter.setMarkerValue(isA(Number)), {times: 2});227 raf.restore();228 });229 test(`on body ${upEvt} removes the mdc-slider--active class from the component`, () => {230 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();231 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});232 foundation.init();233 raf.flush();234 rootHandlers[downEvt](pageXObj(50));235 raf.flush();236 bodyHandlers[upEvt]();237 td.verify(mockAdapter.removeClass(cssClasses.ACTIVE));238 raf.restore();239 });240 test(`on body ${upEvt} removes the ${moveEvt} and all *up/end event handlers from the document body`, () => {241 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();242 const {isA} = td.matchers;243 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});244 foundation.init();245 raf.flush();246 rootHandlers[downEvt](pageXObj(50));247 raf.flush();248 bodyHandlers[upEvt]();249 td.verify(mockAdapter.deregisterBodyInteractionHandler(moveEvt, isA(Function)));250 td.verify(mockAdapter.deregisterBodyInteractionHandler('mouseup', isA(Function)));251 td.verify(mockAdapter.deregisterBodyInteractionHandler('pointerup', isA(Function)));252 td.verify(mockAdapter.deregisterBodyInteractionHandler('touchend', isA(Function)));253 raf.restore();254 });255 test(`on body ${upEvt} notifies the client of a change event`, () => {256 const {foundation, mockAdapter, raf, rootHandlers, bodyHandlers} = setupTest();257 td.when(mockAdapter.computeBoundingRect()).thenReturn({left: 0, width: 100});258 foundation.init();259 raf.flush();260 rootHandlers[downEvt](pageXObj(50));261 raf.flush();262 bodyHandlers[upEvt]();263 td.verify(mockAdapter.notifyChange());264 raf.restore();265 });...

Full Screen

Full Screen

Level2Record.js

Source:Level2Record.js Github

copy

Full Screen

1const { Level2Parser } = require('./Level2Parser')2const { MESSAGE_HEADER_SIZE, FILE_HEADER_SIZE, RADAR_DATA_SIZE, CTM_HEADER_SIZE } = require('../constants')3/**4 * Returns a record from the loaded radar data5 */6class Level2Record {7 constructor(raf, record, message31_offset) {8 this._record_offset = record * RADAR_DATA_SIZE + FILE_HEADER_SIZE + message31_offset9 // passed the buffer, finished reading the file10 if(this._record_offset >= raf.getLength()) return { finished: true }11 // return the current record data12 return this._getRecord(raf)13 }14 /**15 * Creates a new parser and grabs the data16 * from the data blocks. Then save that data17 * to the record.volume Object18 * See page 114; Section "Data Block #1" https://www.roc.noaa.gov/wsr88d/PublicDocs/ICDs/RDA_RPG_2620002P.pdf19 */20 _parseVolumeData(raf, record, data_block_pointer) {21 let parser = new Level2Parser(raf, data_block_pointer, this._record_offset)22 let data = {23 block_type: parser.getDataBlockString(0, 1),24 name: parser.getDataBlockString(1, 3),25 size: parser.getDataBlockShort(4),26 version_major: parser.getDataBlockByte(6),27 version_miner: parser.getDataBlockByte(7),28 latitude: parser.getDataBlockFloat(8),29 longitude: parser.getDataBlockFloat(12),30 elevation: parser.getDataBlockShort(16),31 feedhorn_height: parser.getDataBlockByte(18),32 calibration: parser.getDataBlockFloat(20),33 tx_horizontal: parser.getDataBlockFloat(24),34 tx_vertical: parser.getDataBlockFloat(28),35 differential_reflectivity: parser.getDataBlockFloat(32),36 volume_coverage_pattern: parser.getDataBlockByte(40)37 }38 record.volume = data39 }40 /**41 * Creates a new parser and grabs the data42 * from the data blocks. Then save that data43 * to the record.elevation Object44 * See page 114; Section "Data Block #2" https://www.roc.noaa.gov/wsr88d/PublicDocs/ICDs/RDA_RPG_2620002P.pdf45 */46 _parseElevationData(raf, record, data_block_pointer) {47 let parser = new Level2Parser(raf, data_block_pointer, this._record_offset)48 let data = {49 block_type: parser.getDataBlockString(0, 1),50 name: parser.getDataBlockString(1, 3),51 size: parser.getDataBlockShort(4),52 atmos: parser.getDataBlockShort(6),53 calibration: parser.getDataBlockFloat(8)54 }55 record.elevation = data56 }57 /**58 * Creates a new parser and grabs the data59 * from the data blocks. Then save that data60 * to the record.radial Object61 * See page 115; Section "Data Block #3" https://www.roc.noaa.gov/wsr88d/PublicDocs/ICDs/RDA_RPG_2620002P.pdf62 */63 _parseRadialData(raf, record, data_block_pointer) {64 let parser = new Level2Parser(raf, data_block_pointer, this._record_offset)65 let data = {66 block_type: parser.getDataBlockString(0, 1),67 name: parser.getDataBlockString(1, 3),68 size: parser.getDataBlockShort(4),69 unambiguous_range: parser.getDataBlockShort(6),70 horizontal_noise_level: parser.getDataBlockFloat(8),71 vertical_noise_level: parser.getDataBlockFloat(12),72 nyquist_velocity: parser.getDataBlockShort(16)73 }74 record.radial = data75 }76 /**77 * Creates a new parser and grabs the data78 * from the data blocks. Then save that data79 * to the record.(reflect|velocity|spectrum|zdr|phi|rho)80 * Object base on what type being parsed81 * See page 115-117; Section "Data Block #4-9" https://www.roc.noaa.gov/wsr88d/PublicDocs/ICDs/RDA_RPG_2620002P.pdf82 */83 _parseMomentData(raf, record, data_block_pointer, type) {84 if(data_block_pointer > 0) {85 let parser = new Level2Parser(raf, data_block_pointer, this._record_offset)86 let data = {87 gate_count: parser.getDataBlockShort(8),88 first_gate: parser.getDataBlockShort(10) / 1000, // scale int to float 0.001 precision89 gate_size: parser.getDataBlockShort(12) / 1000, // scale int to float 0.001 precision90 rf_threshold: parser.getDataBlockShort(14) / 10, // scale int to float 0.1 precision91 snr_threshold: parser.getDataBlockShort(16) / 1000, // scale int to float 0.001 precision92 data_size: parser.getDataBlockByte(19),93 scale: parser.getDataBlockFloat(20),94 offset: parser.getDataBlockFloat(24),95 data_offset: data_block_pointer + 28,96 moment_data: []97 }98 99 switch(type) {100 case 'REF':101 for(let i = 28; i <= 1867; i++) {102 data.moment_data.push((parser.getDataBlockByte(i) - data.offset) / data.scale)103 }104 record.reflect = data105 break106 case 'VEL':107 for(let i = 28; i <= 1227; i++) {108 data.moment_data.push((parser.getDataBlockByte(i) - data.offset) / data.scale)109 }110 record.velocity = data111 break112 case 'SW':113 for(let i = 28; i <= 1227; i++) {114 data.moment_data.push((parser.getDataBlockByte(i) - data.offset) / data.scale)115 }116 record.spectrum = data117 break118 case 'ZDR':119 for(let i = 28; i <= 1227; i++) {120 data.moment_data.push((parser.getDataBlockByte(i) - data.offset) / data.scale)121 }122 record.zdr = data123 break124 /* case 'PHI': 125 for(let i = 28; i <= 1227; i += 2) {126 data.moment_data.push((parser.getDataBlockShort(i) - data.offset) / data.scale)127 }128 record.phi = data129 break */130 case 'RHO':131 // RHO - getting indexing errors - !!FIX!!132 for(let i = 28; i <= 1227; i++) {133 data.moment_data.push((parser.getDataBlockByte(i) - data.offset) / data.scale)134 }135 record.rho = data136 break137 }138 }139 }140 /**141 * o--------------o-----------------------------o142 * | Message type | Data |143 * |--------------|-----------------------------|144 * | 2 | RDA Status |145 * | 3 | RDA Performance/Maintenance |146 * | 5 | RDA Volume Coverage |147 * | 13 | Clutter Filter Bypass Map |148 * | 15 | Clutter Map |149 * | 18 | RDA Adaptable Parameters |150 * | 29 | Model Data Message |151 * | 31 | Digital Radar Generic Format|152 * o--------------o-----------------------------o153 */154 _getRecord(raf) {155 raf.seek(this._record_offset)156 raf.skip(CTM_HEADER_SIZE)157 let message = {158 message_size: raf.readShort(),159 channel: raf.readByte(), 160 message_type: raf.readByte(),161 id_sequence: raf.readShort(),162 message_julian_date: raf.readShort(),163 message_mseconds: raf.readInt(),164 segment_count: raf.readShort(),165 segment_number: raf.readShort()166 }167 if(message.message_type == 31) {168 message.record = {169 id: raf.readString(4),170 mseconds: raf.readInt(),171 julian_date: raf.readShort(),172 radial_number: raf.readShort(),173 azimuth: raf.readFloat(),174 compress_idx: raf.readByte(),175 sp: raf.readByte(),176 radial_length: raf.readShort(),177 ars: raf.readByte(),178 rs: raf.readByte(),179 elevation_number: raf.readByte(),180 cut: raf.readByte(),181 elevation: raf.readFloat(),182 rsbs: raf.readByte(),183 aim: raf.readByte(),184 dcount: raf.readShort()185 }186 /**187 * Read and save the data pointers from the file188 * so we know where to start reading within the file189 * to grab the data from the data blocks190 * See page 114 of https://www.roc.noaa.gov/wsr88d/PublicDocs/ICDs/RDA_RPG_2620002P.pdf191 */192 let dbp1 = raf.readInt()193 let dbp2 = raf.readInt()194 let dbp3 = raf.readInt()195 let dbp4 = raf.readInt()196 let dbp5 = raf.readInt()197 let dbp6 = raf.readInt()198 let dbp7 = raf.readInt()199 let dbp8 = raf.readInt()200 let dbp9 = raf.readInt()201 /**202 * Parse all of our data inside the datablocks203 * and save it to the message.record Object204 */205 this._parseVolumeData(raf, message.record, dbp1)206 this._parseElevationData(raf, message.record, dbp2)207 this._parseRadialData(raf, message.record, dbp3)208 this._parseMomentData(raf, message.record, dbp4, 'REF')209 this._parseMomentData(raf, message.record, dbp5, 'VEL')210 this._parseMomentData(raf, message.record, dbp6, 'SW')211 this._parseMomentData(raf, message.record, dbp7, 'ZDR')212 this._parseMomentData(raf, message.record, dbp8, 'PHI')213 this._parseMomentData(raf, message.record, dbp9, 'RHO')214 }215 if(message.message_type == 1) {216 message.record = {217 mseconds: raf.readInt(),218 julian_date: raf.readShort(),219 range: raf.readShort(),220 azmith_angle: raf.readShort(),221 radial_number: raf.readShort(),222 radial_status: raf.readShort(),223 elevation_angle: raf.readShort(),224 elevation_number: raf.readShort(),225 reflect_first_gate: raf.readShort(),226 doppler_first_gate: raf.readShort(),227 reflect_gate_size: raf.readShort(),228 doppler_gate_size: raf.readShort(),229 reflect_gate_count: raf.readShort(),230 doppler_gate_count: raf.readShort(),231 cut: raf.readShort(),232 calibration: raf.readFloat(),233 reflect_offset: raf.readShort(),234 velocity_offset: raf.readShort(),235 width_offset: raf.readShort(),236 resolution: raf.readShort(),237 vcp: raf.readShort()238 }239 raf.skip(14)240 message.record.nyquist_vel = raf.readShort()241 message.record.attenuation = raf.readShort()242 message.record.threshold = raf.readShort()243 message.record.has_reflection_data = message.record.reflect_gate_count > 0244 message.record.has_doppler_data = message.record.doppler_gate_count > 0245 }246 return message247 }248}...

Full Screen

Full Screen

swipable-list-item.js

Source:swipable-list-item.js Github

copy

Full Screen

1import Ember from 'ember';2const {3 Mixin,4 run,5 testing,6 observer7} = Ember;8const OPTION_WIDTH = 64;9export default Mixin.create({10 classNames: ['js-list-item'],11 classNameBindings: ['isOpen'],12 isOpen: false,13 isSwipable: true,14 isPanOpen: false,15 optionsWidth: OPTION_WIDTH * 4,16 rafPanId: null,17 rafSlideId: null,18 init() {19 this._super(...arguments);20 // Check that registerItem function exists on parentView21 if (this.get('parentView').registerItem) {22 this.get('parentView').registerItem(this);23 }24 },25 didInsertElement() {26 this._super(...arguments);27 this.$item = this.$();28 },29 willDestroyElement() {30 this._super(...arguments);31 this.$item = null;32 this.$front = null;33 if (this.rafPanId) {34 window.cancelAnimationFrame(this.rafPanId);35 this.rafPanId = null;36 }37 if (this.rafSlideId) {38 window.cancelAnimationFrame(this.rafSlideId);39 this.rafSlideId = null;40 }41 },42 closeItem() {43 let style = '';44 style += 'transform: translateX(0); transition: transform 250ms;';45 this.$front.style.cssText = style;46 },47 doPanStart() {48 this.$front = this.$item.find('.js-swipeable-block')[0];49 // this.get('ui').own(this.get('elementId'), this.close.bind(this));50 let style = window.getComputedStyle(this.$front);51 // TODO: What is this? Use window.getComputedStyle(el).getPropertyValue("translate")52 let matrix = new WebKitCSSMatrix(style.webkitTransform);53 this.startX = matrix.m41;54 if (!testing) {55 this.lastX = this.startX;56 }57 if (this.rafSlideId) {58 window.cancelAnimationFrame(this.rafSlideId);59 this.rafSlideId = null;60 }61 // keep track that we're panning62 // this.set('isPanning', true);63 },64 doPanMove(event) {65 let newX = Math.round(this.startX + event.originalEvent.gesture.deltaX);66 let width = this.get('optionsWidth');67 newX = Math.min(Math.max(newX, -1 * width), 0);68 if (this.lastX === newX) {69 return;70 }71 this.lastX = newX;72 if (!this.rafPanId) {73 this.rafPanId = window.requestAnimationFrame(this.animatePan.bind(this));74 }75 },76 doPanEnd() {77 this.startX = null;78 let width = this.get('optionsWidth');79 let clip = Math.round((width / 2), 0);80 this.setProperties({81 isPanning: false,82 isPanOpen: (Math.abs(this.lastX) >= clip)83 });84 // if (!this.get('isPanOpen')) {85 // this.get('ui').disown(this.get('elementId'));86 // }87 if (this.rafPanId) {88 window.cancelAnimationFrame(this.rafPanId);89 this.rafPanId = null;90 }91 if (!this.rafSlideId) {92 this.rafSlideId = window.requestAnimationFrame(this.animateSlide.bind(this));93 }94 },95 // Note: Called every pixel the element is dragged96 animatePan() {97 this.rafPanId = null;98 let newX = this.lastX;99 this.$front.style.cssText = `transform: translateX(${ newX }px)`;100 },101 // Note: Called at the end of a drag. Used to autoclose or open when dragging is stopped midway102 animateSlide() {103 if (!this.$front) {104 return;105 }106 this.rafSlideId = null;107 let newX,108 relativeDuration;109 let width = this.get('optionsWidth');110 // Checks whether to snap open or close111 newX = (this.get('isPanOpen')) ? -1 * width : 0;112 // calculate the remaining duration (time) needed to complete the action113 // relativeDuration = Math.abs(newX - this.lastX) / (this.get('clip') / this.get('duration'));114 relativeDuration = 120;115 this.$front.style.cssText = `transition: transform ${ relativeDuration }ms; transform: translateX(${ newX }px); `;116 if (newX === 0) {117 this.slideTimer = run.later(this, function() {118 if (this.get('isDestroying') || this.get('isDestroyed')) {119 return;120 }121 this.$front.style.cssText = '';122 }, relativeDuration);123 }124 },125 _enqueSlide: observer('isPanOpen', function() {126 if (this.get('isDestroying') || this.get('isDestroyed')) {127 return;128 }129 if (this.rafPanId) {130 window.cancelAnimationFrame(this.rafPanId);131 this.rafPanId = null;132 }133 if (!this.rafSlideId) {134 this.rafSlideId = window.requestAnimationFrame(this.animateSlide.bind(this));135 }136 this.set('parentView.isItemOpen', this.get('isPanOpen'));137 })...

Full Screen

Full Screen

rafSpec.js

Source:rafSpec.js Github

copy

Full Screen

1'use strict';2describe('$$rAF', function() {3 it('should queue and block animation frames', inject(function($$rAF) {4 if (!$$rAF.supported) return;5 var message;6 $$rAF(function() {7 message = 'yes';8 });9 expect(message).toBeUndefined();10 $$rAF.flush();11 expect(message).toBe('yes');12 }));13 it('should provide a cancellation method', inject(function($$rAF) {14 if (!$$rAF.supported) return;15 var present = true;16 var cancel = $$rAF(function() {17 present = false;18 });19 expect(present).toBe(true);20 cancel();21 try {22 $$rAF.flush();23 } catch (e) {}24 expect(present).toBe(true);25 }));26 it('should only consume only one RAF if multiple async functions are registered before the first frame kicks in', inject(function($$rAF) {27 if (!$$rAF.supported) return;28 //we need to create our own injector to work around the ngMock overrides29 var rafLog = [];30 var injector = createInjector(['ng', function($provide) {31 $provide.value('$window', {32 location: window.location,33 history: window.history,34 webkitRequestAnimationFrame: function(fn) {35 rafLog.push(fn);36 }37 });38 }]);39 $$rAF = injector.get('$$rAF');40 var log = [];41 function logFn() {42 log.push(log.length);43 }44 $$rAF(logFn);45 $$rAF(logFn);46 $$rAF(logFn);47 expect(log).toEqual([]);48 expect(rafLog.length).toBe(1);49 rafLog[0]();50 expect(log).toEqual([0,1,2]);51 expect(rafLog.length).toBe(1);52 $$rAF(logFn);53 expect(log).toEqual([0,1,2]);54 expect(rafLog.length).toBe(2);55 }));56 describe('$timeout fallback', function() {57 it("it should use a $timeout incase native rAF isn't suppored", function() {58 var timeoutSpy = jasmine.createSpy('callback');59 //we need to create our own injector to work around the ngMock overrides60 var injector = createInjector(['ng', function($provide) {61 $provide.value('$timeout', timeoutSpy);62 $provide.value('$window', {63 location: window.location64 });65 }]);66 var $$rAF = injector.get('$$rAF');67 expect($$rAF.supported).toBe(false);68 var message;69 $$rAF(function() {70 message = 'on';71 });72 expect(message).toBeUndefined();73 expect(timeoutSpy).toHaveBeenCalled();74 timeoutSpy.mostRecentCall.args[0]();75 expect(message).toBe('on');76 });77 });78 describe('mocks', function() {79 it('should throw an error if no frames are present', inject(function($$rAF) {80 if ($$rAF.supported) {81 var failed = false;82 try {83 $$rAF.flush();84 } catch (e) {85 failed = true;86 }87 expect(failed).toBe(true);88 }89 }));90 });91 describe('mobile', function() {92 it('should provide a cancellation method for an older version of Android', function() {93 //we need to create our own injector to work around the ngMock overrides94 var injector = createInjector(['ng', function($provide) {95 $provide.value('$window', {96 location: window.location,97 history: window.history,98 webkitRequestAnimationFrame: jasmine.createSpy('$window.webkitRequestAnimationFrame'),99 webkitCancelRequestAnimationFrame: jasmine.createSpy('$window.webkitCancelRequestAnimationFrame')100 });101 }]);102 var $$rAF = injector.get('$$rAF');103 var $window = injector.get('$window');104 var cancel = $$rAF(function() {});105 expect($$rAF.supported).toBe(true);106 try {107 cancel();108 } catch (e) {}109 expect($window.webkitCancelRequestAnimationFrame).toHaveBeenCalled();110 });111 });...

Full Screen

Full Screen

raf.js

Source:raf.js Github

copy

Full Screen

...41 this.trigger(this.props);42 if (!this.isTicking) {43 return;44 }45 this.id = this.raf(() => this.loop());46 }47 /**48 * Stop the requestAnimationFrame loop.49 *50 * @returns {void}51 */52 kill() {53 this.cancelRaf(this.id);54 this.isTicking = false;55 }56 /**57 * Get raf props.58 *59 * @todo Return elapsed time / index?...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.pause()4 cy.contains('type').click()5 cy.url().should('include', '/commands/actions')6 cy.get('.action-email')7 .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', () => {2 it('Does not do much!', () => {3 cy.pause()4 cy.contains('type').click()5 cy.url().should('include', '/commands/actions')6 cy.get('.action-email')7 .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('waitForReact', () => {2 cy.window().then(win => {3 return new Cypress.Promise((resolve, reject) => {4 const start = Date.now();5 const check = () => {6 if (win.React && win.ReactDOM && win.ReactDOM.render && win.ReactDOM.findDOMNode) {7 resolve();8 } else if (Date.now() - start > 10000) {9 reject(new Error('waitForReact timed out'));10 } else {11 setTimeout(check, 20);12 }13 };14 check();15 });16 });17 });18 Cypress.Commands.add('waitForRedux', () => {19 cy.window().then(win => {20 return new Cypress.Promise((resolve, reject) => {21 const start = Date.now();22 const check = () => {23 if (win.store) {24 resolve();25 } else if (Date.now() - start > 10000) {26 reject(new Error('waitForRedux timed out'));27 } else {28 setTimeout(check, 20);29 }30 };31 check();32 });33 });34 });35 Cypress.Commands.add('waitForRouter', () => {36 cy.window().then(win => {37 return new Cypress.Promise((resolve, reject) => {38 const start = Date.now();39 const check = () => {40 if (win.reactRouter) {41 resolve();42 } else if (Date.now() - start > 10000) {43 reject(new Error('waitForRouter timed out'));44 } else {45 setTimeout(check, 20);46 }47 };48 check();49 });50 });51 });52 Cypress.Commands.add('waitForComponent', () => {53 cy.window().then(win => {54 return new Cypress.Promise((resolve, reject) => {55 const start = Date.now();56 const check = () => {57 if (win.Component) {58 resolve();59 } else if (Date.now() - start > 10000) {60 reject(new Error('waitForComponent timed out'));61 } else {62 setTimeout(check, 20);63 }64 };65 check();66 });67 });68 });

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('waitUntil', (subject, condition, options = {}) => {2 const { timeout = 3000, interval = 100, errorMsg = '' } = options;3 const start = new Date().getTime();4 return new Cypress.Promise((resolve, reject) => {5 const checkCondition = () => {6 const result = condition(subject);7 if (result) {8 return resolve(result);9 }10 if (new Date().getTime() - start > timeout) {11 return reject(new Error(errorMsg));12 }13 setTimeout(checkCondition, interval);14 };15 checkCondition();16 });17});18Cypress.Commands.add('waitUntilElementExists', (selector, options = {}) => {19 const { timeout = 3000, interval = 100 } = options;20 const start = new Date().getTime();21 return new Cypress.Promise((resolve, reject) => {22 const checkCondition = () => {23 if (Cypress.$(selector).length) {24 return resolve();25 }26 if (new Date().getTime() - start > timeout) {27 return reject(new Error(`Element ${selector} was not found`));28 }29 setTimeout(checkCondition, interval);30 };31 checkCondition();32 });33});34Cypress.Commands.add('waitUntilElementDoesNotExist', (selector, options = {}) => {35 const { timeout = 3000, interval = 100 } = options;36 const start = new Date().getTime();37 return new Cypress.Promise((resolve, reject) => {38 const checkCondition = () => {39 if (!Cypress.$(selector).length) {40 return resolve();41 }42 if (new Date().getTime() - start > timeout) {43 return reject(new Error(`Element ${selector} was found`));44 }45 setTimeout(checkCondition, interval);46 };47 checkCondition();48 });49});50Cypress.Commands.add('waitUntilElementIsVisible', (selector, options = {}) => {51 const { timeout = 3000, interval = 100 } = options;52 const start = new Date().getTime();53 return new Cypress.Promise((resolve, reject) => {54 const checkCondition = () => {55 if (Cypress.$(selector).is(':visible')) {56 return resolve();

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Test', () => {2 it('should work', () => {3 cy.server()4 cy.route('GET', '**/comments/*').as('getComment')5 cy.get('.network-btn').click()6 cy.wait('@getComment').its('responseBody').should('have.property', 'name', 'Using GET in cy.route()')7 })8})

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful