Best Python code snippet using fMBT_python
ReactUpdateQueue.js
Source:ReactUpdateQueue.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9// UpdateQueue is a linked list of prioritized updates.10//11// Like fibers, update queues come in pairs: a current queue, which represents12// the visible state of the screen, and a work-in-progress queue, which can be13// mutated and processed asynchronously before it is committed â a form of14// double buffering. If a work-in-progress render is discarded before finishing,15// we create a new work-in-progress by cloning the current queue.16//17// Both queues share a persistent, singly-linked list structure. To schedule an18// update, we append it to the end of both queues. Each queue maintains a19// pointer to first update in the persistent list that hasn't been processed.20// The work-in-progress pointer always has a position equal to or greater than21// the current queue, since we always work on that one. The current queue's22// pointer is only updated during the commit phase, when we swap in the23// work-in-progress.24//25// For example:26//27//   Current pointer:           A - B - C - D - E - F28//   Work-in-progress pointer:              D - E - F29//                                          ^30//                                          The work-in-progress queue has31//                                          processed more updates than current.32//33// The reason we append to both queues is because otherwise we might drop34// updates without ever processing them. For example, if we only add updates to35// the work-in-progress queue, some updates could be lost whenever a work-in36// -progress render restarts by cloning from current. Similarly, if we only add37// updates to the current queue, the updates will be lost whenever an already38// in-progress queue commits and swaps with the current queue. However, by39// adding to both queues, we guarantee that the update will be part of the next40// work-in-progress. (And because the work-in-progress queue becomes the41// current queue once it commits, there's no danger of applying the same42// update twice.)43//44// Prioritization45// --------------46//47// Updates are not sorted by priority, but by insertion; new updates are always48// appended to the end of the list.49//50// The priority is still important, though. When processing the update queue51// during the render phase, only the updates with sufficient priority are52// included in the result. If we skip an update because it has insufficient53// priority, it remains in the queue to be processed later, during a lower54// priority render. Crucially, all updates subsequent to a skipped update also55// remain in the queue *regardless of their priority*. That means high priority56// updates are sometimes processed twice, at two separate priorities. We also57// keep track of a base state, that represents the state before the first58// update in the queue is applied.59//60// For example:61//62//   Given a base state of '', and the following queue of updates63//64//     A1 - B2 - C1 - D265//66//   where the number indicates the priority, and the update is applied to the67//   previous state by appending a letter, React will process these updates as68//   two separate renders, one per distinct priority level:69//70//   First render, at priority 1:71//     Base state: ''72//     Updates: [A1, C1]73//     Result state: 'AC'74//75//   Second render, at priority 2:76//     Base state: 'A'            <-  The base state does not include C1,77//                                    because B2 was skipped.78//     Updates: [B2, C1, D2]      <-  C1 was rebased on top of B279//     Result state: 'ABCD'80//81// Because we process updates in insertion order, and rebase high priority82// updates when preceding updates are skipped, the final result is deterministic83// regardless of priority. Intermediate state may vary according to system84// resources, but the final state is always the same.85import type {Fiber} from './ReactFiber';86import type {ExpirationTime} from './ReactFiberExpirationTime';87import {NoWork} from './ReactFiberExpirationTime';88import {Callback, ShouldCapture, DidCapture} from 'shared/ReactSideEffectTags';89import {ClassComponent} from 'shared/ReactWorkTags';90import {91  debugRenderPhaseSideEffects,92  debugRenderPhaseSideEffectsForStrictMode,93} from 'shared/ReactFeatureFlags';94import {StrictMode} from './ReactTypeOfMode';95import invariant from 'shared/invariant';96import warningWithoutStack from 'shared/warningWithoutStack';97export type Update<State> = {98  expirationTime: ExpirationTime,99  tag: 0 | 1 | 2 | 3,100  payload: any,101  callback: (() => mixed) | null,102  next: Update<State> | null,103  nextEffect: Update<State> | null,104};105export type UpdateQueue<State> = {106  baseState: State,107  firstUpdate: Update<State> | null,108  lastUpdate: Update<State> | null,109  firstCapturedUpdate: Update<State> | null,110  lastCapturedUpdate: Update<State> | null,111  firstEffect: Update<State> | null,112  lastEffect: Update<State> | null,113  firstCapturedEffect: Update<State> | null,114  lastCapturedEffect: Update<State> | null,115};116export const UpdateState = 0;117export const ReplaceState = 1;118export const ForceUpdate = 2;119export const CaptureUpdate = 3;120// Global state that is reset at the beginning of calling `processUpdateQueue`.121// It should only be read right after calling `processUpdateQueue`, via122// `checkHasForceUpdateAfterProcessing`.123let hasForceUpdate = false;124let didWarnUpdateInsideUpdate;125let currentlyProcessingQueue;126export let resetCurrentlyProcessingQueue;127if (__DEV__) {128  didWarnUpdateInsideUpdate = false;129  currentlyProcessingQueue = null;130  resetCurrentlyProcessingQueue = () => {131    currentlyProcessingQueue = null;132  };133}134export function createUpdateQueue<State>(baseState: State): UpdateQueue<State> {135  const queue: UpdateQueue<State> = {136    baseState,137    firstUpdate: null,138    lastUpdate: null,139    firstCapturedUpdate: null,140    lastCapturedUpdate: null,141    firstEffect: null,142    lastEffect: null,143    firstCapturedEffect: null,144    lastCapturedEffect: null,145  };146  return queue;147}148function cloneUpdateQueue<State>(149  currentQueue: UpdateQueue<State>,150): UpdateQueue<State> {151  const queue: UpdateQueue<State> = {152    baseState: currentQueue.baseState,153    firstUpdate: currentQueue.firstUpdate,154    lastUpdate: currentQueue.lastUpdate,155    // TODO: With resuming, if we bail out and resuse the child tree, we should156    // keep these effects.157    firstCapturedUpdate: null,158    lastCapturedUpdate: null,159    firstEffect: null,160    lastEffect: null,161    firstCapturedEffect: null,162    lastCapturedEffect: null,163  };164  return queue;165}166export function createUpdate(expirationTime: ExpirationTime): Update<*> {167  return {168    expirationTime: expirationTime,169    tag: UpdateState,170    payload: null,171    callback: null,172    next: null,173    nextEffect: null,174  };175}176function appendUpdateToQueue<State>(177  queue: UpdateQueue<State>,178  update: Update<State>,179) {180  // Append the update to the end of the list.181  if (queue.lastUpdate === null) {182    // Queue is empty183    queue.firstUpdate = queue.lastUpdate = update;184  } else {185    queue.lastUpdate.next = update;186    queue.lastUpdate = update;187  }188}189export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {190  // Update queues are created lazily.191  const alternate = fiber.alternate;192  let queue1;193  let queue2;194  if (alternate === null) {195    // There's only one fiber.196    queue1 = fiber.updateQueue;197    queue2 = null;198    if (queue1 === null) {199      queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);200    }201  } else {202    // There are two owners.203    queue1 = fiber.updateQueue;204    queue2 = alternate.updateQueue;205    if (queue1 === null) {206      if (queue2 === null) {207        // Neither fiber has an update queue. Create new ones.208        queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);209        queue2 = alternate.updateQueue = createUpdateQueue(210          alternate.memoizedState,211        );212      } else {213        // Only one fiber has an update queue. Clone to create a new one.214        queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);215      }216    } else {217      if (queue2 === null) {218        // Only one fiber has an update queue. Clone to create a new one.219        queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);220      } else {221        // Both owners have an update queue.222      }223    }224  }225  if (queue2 === null || queue1 === queue2) {226    // There's only a single queue.227    appendUpdateToQueue(queue1, update);228  } else {229    // There are two queues. We need to append the update to both queues,230    // while accounting for the persistent structure of the list â we don't231    // want the same update to be added multiple times.232    if (queue1.lastUpdate === null || queue2.lastUpdate === null) {233      // One of the queues is not empty. We must add the update to both queues.234      appendUpdateToQueue(queue1, update);235      appendUpdateToQueue(queue2, update);236    } else {237      // Both queues are non-empty. The last update is the same in both lists,238      // because of structural sharing. So, only append to one of the lists.239      appendUpdateToQueue(queue1, update);240      // But we still need to update the `lastUpdate` pointer of queue2.241      queue2.lastUpdate = update;242    }243  }244  if (__DEV__) {245    if (246      fiber.tag === ClassComponent &&247      (currentlyProcessingQueue === queue1 ||248        (queue2 !== null && currentlyProcessingQueue === queue2)) &&249      !didWarnUpdateInsideUpdate250    ) {251      warningWithoutStack(252        false,253        'An update (setState, replaceState, or forceUpdate) was scheduled ' +254          'from inside an update function. Update functions should be pure, ' +255          'with zero side-effects. Consider using componentDidUpdate or a ' +256          'callback.',257      );258      didWarnUpdateInsideUpdate = true;259    }260  }261}262export function enqueueCapturedUpdate<State>(263  workInProgress: Fiber,264  update: Update<State>,265) {266  // Captured updates go into a separate list, and only on the work-in-267  // progress queue.268  let workInProgressQueue = workInProgress.updateQueue;269  if (workInProgressQueue === null) {270    workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(271      workInProgress.memoizedState,272    );273  } else {274    // TODO: I put this here rather than createWorkInProgress so that we don't275    // clone the queue unnecessarily. There's probably a better way to276    // structure this.277    workInProgressQueue = ensureWorkInProgressQueueIsAClone(278      workInProgress,279      workInProgressQueue,280    );281  }282  // Append the update to the end of the list.283  if (workInProgressQueue.lastCapturedUpdate === null) {284    // This is the first render phase update285    workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;286  } else {287    workInProgressQueue.lastCapturedUpdate.next = update;288    workInProgressQueue.lastCapturedUpdate = update;289  }290}291function ensureWorkInProgressQueueIsAClone<State>(292  workInProgress: Fiber,293  queue: UpdateQueue<State>,294): UpdateQueue<State> {295  const current = workInProgress.alternate;296  if (current !== null) {297    // If the work-in-progress queue is equal to the current queue,298    // we need to clone it first.299    if (queue === current.updateQueue) {300      queue = workInProgress.updateQueue = cloneUpdateQueue(queue);301    }302  }303  return queue;304}305function getStateFromUpdate<State>(306  workInProgress: Fiber,307  queue: UpdateQueue<State>,308  update: Update<State>,309  prevState: State,310  nextProps: any,311  instance: any,312): any {313  switch (update.tag) {314    case ReplaceState: {315      const payload = update.payload;316      if (typeof payload === 'function') {317        // Updater function318        if (__DEV__) {319          if (320            debugRenderPhaseSideEffects ||321            (debugRenderPhaseSideEffectsForStrictMode &&322              workInProgress.mode & StrictMode)323          ) {324            payload.call(instance, prevState, nextProps);325          }326        }327        return payload.call(instance, prevState, nextProps);328      }329      // State object330      return payload;331    }332    case CaptureUpdate: {333      workInProgress.effectTag =334        (workInProgress.effectTag & ~ShouldCapture) | DidCapture;335    }336    // Intentional fallthrough337    case UpdateState: {338      const payload = update.payload;339      let partialState;340      if (typeof payload === 'function') {341        // Updater function342        if (__DEV__) {343          if (344            debugRenderPhaseSideEffects ||345            (debugRenderPhaseSideEffectsForStrictMode &&346              workInProgress.mode & StrictMode)347          ) {348            payload.call(instance, prevState, nextProps);349          }350        }351        partialState = payload.call(instance, prevState, nextProps);352      } else {353        // Partial state object354        partialState = payload;355      }356      if (partialState === null || partialState === undefined) {357        // Null and undefined are treated as no-ops.358        return prevState;359      }360      // Merge the partial state and the previous state.361      return Object.assign({}, prevState, partialState);362    }363    case ForceUpdate: {364      hasForceUpdate = true;365      return prevState;366    }367  }368  return prevState;369}370export function processUpdateQueue<State>(371  workInProgress: Fiber,372  queue: UpdateQueue<State>,373  props: any,374  instance: any,375  renderExpirationTime: ExpirationTime,376): void {377  hasForceUpdate = false;378  queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);379  if (__DEV__) {380    currentlyProcessingQueue = queue;381  }382  // These values may change as we process the queue.383  let newBaseState = queue.baseState;384  let newFirstUpdate = null;385  let newExpirationTime = NoWork;386  // Iterate through the list of updates to compute the result.387  let update = queue.firstUpdate;388  let resultState = newBaseState;389  while (update !== null) {390    const updateExpirationTime = update.expirationTime;391    if (updateExpirationTime < renderExpirationTime) {392      // This update does not have sufficient priority. Skip it.393      if (newFirstUpdate === null) {394        // This is the first skipped update. It will be the first update in395        // the new list.396        newFirstUpdate = update;397        // Since this is the first update that was skipped, the current result398        // is the new base state.399        newBaseState = resultState;400      }401      // Since this update will remain in the list, update the remaining402      // expiration time.403      if (newExpirationTime < updateExpirationTime) {404        newExpirationTime = updateExpirationTime;405      }406    } else {407      // This update does have sufficient priority. Process it and compute408      // a new result.409      resultState = getStateFromUpdate(410        workInProgress,411        queue,412        update,413        resultState,414        props,415        instance,416      );417      const callback = update.callback;418      if (callback !== null) {419        workInProgress.effectTag |= Callback;420        // Set this to null, in case it was mutated during an aborted render.421        update.nextEffect = null;422        if (queue.lastEffect === null) {423          queue.firstEffect = queue.lastEffect = update;424        } else {425          queue.lastEffect.nextEffect = update;426          queue.lastEffect = update;427        }428      }429    }430    // Continue to the next update.431    update = update.next;432  }433  // Separately, iterate though the list of captured updates.434  let newFirstCapturedUpdate = null;435  update = queue.firstCapturedUpdate;436  while (update !== null) {437    const updateExpirationTime = update.expirationTime;438    if (updateExpirationTime < renderExpirationTime) {439      // This update does not have sufficient priority. Skip it.440      if (newFirstCapturedUpdate === null) {441        // This is the first skipped captured update. It will be the first442        // update in the new list.443        newFirstCapturedUpdate = update;444        // If this is the first update that was skipped, the current result is445        // the new base state.446        if (newFirstUpdate === null) {447          newBaseState = resultState;448        }449      }450      // Since this update will remain in the list, update the remaining451      // expiration time.452      if (newExpirationTime < updateExpirationTime) {453        newExpirationTime = updateExpirationTime;454      }455    } else {456      // This update does have sufficient priority. Process it and compute457      // a new result.458      resultState = getStateFromUpdate(459        workInProgress,460        queue,461        update,462        resultState,463        props,464        instance,465      );466      const callback = update.callback;467      if (callback !== null) {468        workInProgress.effectTag |= Callback;469        // Set this to null, in case it was mutated during an aborted render.470        update.nextEffect = null;471        if (queue.lastCapturedEffect === null) {472          queue.firstCapturedEffect = queue.lastCapturedEffect = update;473        } else {474          queue.lastCapturedEffect.nextEffect = update;475          queue.lastCapturedEffect = update;476        }477      }478    }479    update = update.next;480  }481  if (newFirstUpdate === null) {482    queue.lastUpdate = null;483  }484  if (newFirstCapturedUpdate === null) {485    queue.lastCapturedUpdate = null;486  } else {487    workInProgress.effectTag |= Callback;488  }489  if (newFirstUpdate === null && newFirstCapturedUpdate === null) {490    // We processed every update, without skipping. That means the new base491    // state is the same as the result state.492    newBaseState = resultState;493  }494  queue.baseState = newBaseState;495  queue.firstUpdate = newFirstUpdate;496  queue.firstCapturedUpdate = newFirstCapturedUpdate;497  // Set the remaining expiration time to be whatever is remaining in the queue.498  // This should be fine because the only two other things that contribute to499  // expiration time are props and context. We're already in the middle of the500  // begin phase by the time we start processing the queue, so we've already501  // dealt with the props. Context in components that specify502  // shouldComponentUpdate is tricky; but we'll have to account for503  // that regardless.504  workInProgress.expirationTime = newExpirationTime;505  workInProgress.memoizedState = resultState;506  if (__DEV__) {507    currentlyProcessingQueue = null;508  }509}510function callCallback(callback, context) {511  invariant(512    typeof callback === 'function',513    'Invalid argument passed as callback. Expected a function. Instead ' +514      'received: %s',515    callback,516  );517  callback.call(context);518}519export function resetHasForceUpdateBeforeProcessing() {520  hasForceUpdate = false;521}522export function checkHasForceUpdateAfterProcessing(): boolean {523  return hasForceUpdate;524}525export function commitUpdateQueue<State>(526  finishedWork: Fiber,527  finishedQueue: UpdateQueue<State>,528  instance: any,529  renderExpirationTime: ExpirationTime,530): void {531  // If the finished render included captured updates, and there are still532  // lower priority updates left over, we need to keep the captured updates533  // in the queue so that they are rebased and not dropped once we process the534  // queue again at the lower priority.535  if (finishedQueue.firstCapturedUpdate !== null) {536    // Join the captured update list to the end of the normal list.537    if (finishedQueue.lastUpdate !== null) {538      finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;539      finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;540    }541    // Clear the list of captured updates.542    finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;543  }544  // Commit the effects545  commitUpdateEffects(finishedQueue.firstEffect, instance);546  finishedQueue.firstEffect = finishedQueue.lastEffect = null;547  commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);548  finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;549}550function commitUpdateEffects<State>(551  effect: Update<State> | null,552  instance: any,553): void {554  while (effect !== null) {555    const callback = effect.callback;556    if (callback !== null) {557      effect.callback = null;558      callCallback(callback, instance);559    }560    effect = effect.nextEffect;561  }...wcs-upgrade.js
Source:wcs-upgrade.js  
1jQuery(document).ready(function($){2	var upgrade_start_time = null,3	    total_subscriptions = wcs_update_script_data.subscription_count;4	$('#update-messages').slideUp();5	$('#upgrade-step-3').slideUp();6	$('form#subscriptions-upgrade').on('submit',function(e){7		$('#update-welcome').slideUp(600);8		$('#update-messages').slideDown(600);9		if('true'==wcs_update_script_data.really_old_version){10			wcs_ajax_update_really_old_version();11		} else if('true'==wcs_update_script_data.upgrade_to_1_5){12			wcs_ajax_update_products();13			wcs_ajax_update_hooks();14		} else if('true'==wcs_update_script_data.upgrade_to_2_0){15			wcs_ajax_update_subscriptions();16		} else if('true'==wcs_update_script_data.repair_2_0){17			wcs_ajax_repair_subscriptions();18		} else {19			wcs_ajax_update_complete();20		}21		e.preventDefault();22	});23	function wcs_ajax_update_really_old_version(){24		$.ajax({25			url:  wcs_update_script_data.ajax_url,26			type: 'POST',27			data: {28				action:       'wcs_upgrade',29				upgrade_step: 'really_old_version',30				nonce:         wcs_update_script_data.upgrade_nonce31			},32			success: function(results) {33				$('#update-messages ol').append($('<li />').text(results.message));34				wcs_ajax_update_products();35				wcs_ajax_update_hooks();36			},37			error: function(results,status,errorThrown){38				wcs_ajax_update_error();39			}40		});41	}42	function wcs_ajax_update_products(){43		$.ajax({44			url:  wcs_update_script_data.ajax_url,45			type: 'POST',46			data: {47				action:       'wcs_upgrade',48				upgrade_step: 'products',49				nonce:         wcs_update_script_data.upgrade_nonce50			},51			success: function(results) {52				$('#update-messages ol').append($('<li />').text(results.message));53			},54			error: function(results,status,errorThrown){55				wcs_ajax_update_error();56			}57		});58	}59	function wcs_ajax_update_hooks() {60		var start_time = new Date();61		$.ajax({62			url:  wcs_update_script_data.ajax_url,63			type: 'POST',64			data: {65				action:       'wcs_upgrade',66				upgrade_step: 'hooks',67				nonce:         wcs_update_script_data.upgrade_nonce68			},69			success: function(results) {70				if(results.message){71					var end_time = new Date(),72						execution_time = Math.ceil( ( end_time.getTime() - start_time.getTime() ) / 1000 );73					$('#update-messages ol').append($('<li />').text(results.message.replace('{execution_time}',execution_time)));74				}75				if( undefined == typeof(results.upgraded_count) || parseInt(results.upgraded_count) <= ( wcs_update_script_data.hooks_per_request - 1 ) ){76					wcs_ajax_update_subscriptions();77				} else {78					wcs_ajax_update_hooks();79				}80			},81			error: function(results,status,errorThrown){82				wcs_ajax_update_error();83			}84		});85	}86	function wcs_ajax_update_subscriptions() {87		var start_time = new Date();88		if ( null === upgrade_start_time ) {89			upgrade_start_time = start_time;90		}91		$.ajax({92			url:  wcs_update_script_data.ajax_url,93			type: 'POST',94			data: {95				action:       'wcs_upgrade',96				upgrade_step: 'subscriptions',97				nonce:         wcs_update_script_data.upgrade_nonce98			},99			success: function(results) {100				if('success'==results.status){101					var end_time = new Date(),102						execution_time = Math.ceil( ( end_time.getTime() - start_time.getTime() ) / 1000 );103					$('#update-messages ol').append($('<li />').text(results.message.replace('{execution_time}',execution_time)));104					wcs_update_script_data.subscription_count -= results.upgraded_count;105					if( "undefined" === typeof(results.upgraded_count) || parseInt(wcs_update_script_data.subscription_count) <= 0 ) {106						wcs_ajax_update_complete();107					} else {108						wcs_ajax_update_estimated_time(results.time_message);109						wcs_ajax_update_subscriptions();110					}111				} else {112					wcs_ajax_update_error(results.message);113				}114			},115			error: function(results,status,errorThrown){116				$('<br/><span>Error: ' + results.status + ' ' + errorThrown + '</span>').appendTo('#update-error p');117				wcs_ajax_update_error( $('#update-error p').html() );118			}119		});120	}121	function wcs_ajax_repair_subscriptions() {122		var start_time = new Date();123		if ( null === upgrade_start_time ) {124			upgrade_start_time = start_time;125		}126		$.ajax({127			url:  wcs_update_script_data.ajax_url,128			type: 'POST',129			data: {130				action:       'wcs_upgrade',131				upgrade_step: 'subscription_dates_repair',132				nonce:         wcs_update_script_data.upgrade_nonce133			},134			success: function(results) {135				if('success'==results.status){136					var end_time = new Date(),137						execution_time = Math.ceil( ( end_time.getTime() - start_time.getTime() ) / 1000 );138					$('#update-messages ol').append($('<li />').text(results.message.replace('{execution_time}',execution_time)));139					wcs_update_script_data.subscription_count -= results.repaired_count;140					wcs_update_script_data.subscription_count -= results.unrepaired_count;141					if( parseInt(wcs_update_script_data.subscription_count) <= 0 ) {142						wcs_ajax_update_complete();143					} else {144						wcs_ajax_update_estimated_time(results.time_message);145						wcs_ajax_repair_subscriptions();146					}147				} else {148					wcs_ajax_update_error(results.message);149				}150			},151			error: function(results,status,errorThrown){152				$('<br/><span>Error: ' + results.status + ' ' + errorThrown + '</span>').appendTo('#update-error p');153				wcs_ajax_update_error( $('#update-error p').html() );154			}155		});156	}157	function wcs_ajax_update_complete() {158		$('#update-ajax-loader, #estimated_time').slideUp(function(){159			$('#update-complete').slideDown();160		});161	}162	function wcs_ajax_update_error(message) {163		message = message || '';164		if ( message.length > 0 ){165			$('#update-error p').html(message);166		}167		$('#update-ajax-loader, #estimated_time').slideUp(function(){168			$('#update-error').slideDown();169		});170	}171	function wcs_ajax_update_estimated_time(message) {172		var total_updated = total_subscriptions - wcs_update_script_data.subscription_count,173			now = new Date(),174			execution_time,175			time_per_update,176			time_left,177			time_left_minutes,178			time_left_seconds;179		execution_time = Math.ceil( ( now.getTime() - upgrade_start_time.getTime() ) / 1000 );180		time_per_update = execution_time / total_updated;181		time_left = Math.floor( wcs_update_script_data.subscription_count * time_per_update );182		time_left_minutes = Math.floor( time_left / 60 );183		time_left_seconds = time_left % 60;184		$('#estimated_time').html(message.replace( '{time_left}', time_left_minutes + ":" + zeropad(time_left_seconds) ));185	}186	function zeropad(number) {187		var pad_char = 0,188			pad = new Array(3).join(pad_char);189		return (pad + number).slice(-pad.length);190	}...FeatureGridUtils-test.js
Source:FeatureGridUtils-test.js  
1/*2 * Copyright 2018, GeoSolutions Sas.3 * All rights reserved.4 *5 * This source code is licensed under the BSD-style license found in the6 * LICENSE file in the root directory of this source tree.7*/8import expect from 'expect';9import {updatePages, gridUpdateToQueryUpdate} from '../FeatureGridUtils';10describe('FeatureGridUtils', () => {11    it('Test updatePages when needPages * size is less then features', () => {12        const oldFeatures = Array(350);13        const features = Array(60);14        const result = {15            features16        };17        const requestOptions = {18            endPage: 99,19            startPage: 9520        };21        const oldData = {22            pages: [23                2330,24                2340,25                2350,26                2360,27                2370,28                3190,29                3200,30                3210,31                3220,32                1020,33                1030,34                1040,35                1050,36                106037            ],38            features: oldFeatures39        };40        const paginationOptions = {41            size: 10,42            maxStoredPages: 10,43            startIndex: 96044        };45        const {pages, features: newFeatures } = updatePages(result, requestOptions, oldData, paginationOptions);46        expect(pages).toBeTruthy();47        expect(newFeatures).toBeTruthy();48        expect(newFeatures.length).toBe(120);49    });50    it('gridUpdateToQueryUpdate', () => {51        const gridUpdate1 = {52            type: "geometry",53            attribute: "ATTRIBUTE",54            operator: "OPERATOR",55            value: {attribute: "ATTRIBUTE", method: "METHOD_1"},56            rawValue: "RAWVAL"57        };58        const queryUpdateFilter = gridUpdateToQueryUpdate(gridUpdate1, {});59        expect(queryUpdateFilter.spatialField).toEqual(gridUpdate1.value);60        expect(queryUpdateFilter.filterFields).toBe(undefined);61        // value as array62        const gridUpdate2 = {63            ...gridUpdate1,64            value: [{attribute: "ATTRIBUTE", method: "METHOD_1"}, {attribute: "ATTRIBUTE", method: "METHOD_2"}]65        };66        const queryUpdateFilter2 = gridUpdateToQueryUpdate(gridUpdate2, {});67        expect(queryUpdateFilter2.spatialField).toEqual(gridUpdate2.value);68        expect(queryUpdateFilter2.filterFields).toBe(undefined);69        expect(queryUpdateFilter2.spatialFieldOperator).toBe("OR");70    });71    it('gridUpdateToQueryUpdate with multiple strings', () => {72        const gridUpdate1 = {73            type: "string",74            attribute: "ATTRIBUTE",75            operator: "ilike",76            value: "str1, str2",77            rawValue: "str1, str2"78        };79        const queryUpdateFilter = gridUpdateToQueryUpdate(gridUpdate1, {});80        expect(queryUpdateFilter.filterFields.length).toBe(2);81        expect(queryUpdateFilter.groupFields.length).toBe(1);82        expect(queryUpdateFilter.groupFields[0].logic).toBe("OR");83        expect(queryUpdateFilter.filterFields[0].value).toBe("str1");84        expect(queryUpdateFilter.filterFields[0].operator).toBe("ilike");85        expect(queryUpdateFilter.filterFields[1].value).toBe("str2");86        expect(queryUpdateFilter.filterFields[1].operator).toBe("ilike");87    });88    it('gridUpdateToQueryUpdate with multiple numbers', () => {89        const gridUpdate1 = {90            type: "number",91            attribute: "ATTRIBUTE",92            operator: null,93            value: "> 300, 69, < 10",94            rawValue: "> 300, 69, < 10"95        };96        const queryUpdateFilter = gridUpdateToQueryUpdate(gridUpdate1, {});97        expect(queryUpdateFilter.filterFields.length).toBe(3);98        expect(queryUpdateFilter.groupFields.length).toBe(1);99        expect(queryUpdateFilter.groupFields[0].logic).toBe("OR");100        expect(queryUpdateFilter.filterFields[0].value).toBe(300);101        expect(queryUpdateFilter.filterFields[0].operator).toBe(">");102        expect(queryUpdateFilter.filterFields[1].value).toBe(69);103        expect(queryUpdateFilter.filterFields[1].operator).toBe("=");104        expect(queryUpdateFilter.filterFields[2].value).toBe(10);105        expect(queryUpdateFilter.filterFields[2].operator).toBe("<");106    });107    it('gridUpdateToQueryUpdate with multiple numbers and multiple strings', () => {108        const gridUpdate1 = {109            type: "number",110            attribute: "ATTR_2_NUMERIC",111            operator: null,112            value: "> 300, 69, < 10",113            rawValue: "> 300, 69, < 10"114        };115        const oldFilterObject = {116            "groupFields": [{"id": "ATTR_1_STRING", "logic": "OR", "groupId": 1, "index": 0}],117            "filterFields": [118                {119                    "attribute": "ATTR_1_STRING",120                    "rowId": 1608204971082,121                    "type": "string",122                    "groupId": "ATTR_1_STRING",123                    "operator": "ilike",124                    "value": "cat"125                },126                {"attribute": "ATTR_1_STRING",127                    "rowId": 1608204971082,128                    "type": "string",129                    "groupId": "ATTR_1_STRING",130                    "operator": "ilike",131                    "value": "to"132                }133            ]};134        const queryUpdateFilter = gridUpdateToQueryUpdate(gridUpdate1, oldFilterObject);135        expect(queryUpdateFilter.filterFields.length).toBe(5);136        expect(queryUpdateFilter.groupFields.length).toBe(2);137        expect(queryUpdateFilter.groupFields[0].id).toBe("ATTR_1_STRING");138        expect(queryUpdateFilter.groupFields[0].logic).toBe("OR");139        expect(queryUpdateFilter.groupFields[0].id).toBe("ATTR_1_STRING");140        expect(queryUpdateFilter.groupFields[1].logic).toBe("OR");141        expect(queryUpdateFilter.filterFields[0].value).toBe("cat");142        expect(queryUpdateFilter.filterFields[0].operator).toBe("ilike");143        expect(queryUpdateFilter.filterFields[1].value).toBe("to");144        expect(queryUpdateFilter.filterFields[1].operator).toBe("ilike");145        expect(queryUpdateFilter.filterFields[2].value).toBe(300);146        expect(queryUpdateFilter.filterFields[2].operator).toBe(">");147        expect(queryUpdateFilter.filterFields[3].value).toBe(69);148        expect(queryUpdateFilter.filterFields[3].operator).toBe("=");149        expect(queryUpdateFilter.filterFields[4].value).toBe(10);150        expect(queryUpdateFilter.filterFields[4].operator).toBe("<");151    });...queryupdatelistener.js
Source:queryupdatelistener.js  
1import { Storage } from '../../../src/core';2import QueryTriggers from '../../../src/core/models/querytriggers';3import QueryUpdateListener from '../../../src/core/statelisteners/queryupdatelistener';4import SearchStates from '../../../src/core/storage/searchstates';5import StorageKeys from '../../../src/core/storage/storagekeys';6describe('registerMiddleware', () => {7  it('middleware is called before a search', async () => {8    const queryUpdateListener = initQueryUpdateListener();9    const middleware = jest.fn(() => new Promise(resolve => setTimeout(resolve, 5)));10    const middleware2 = jest.fn();11    queryUpdateListener.registerMiddleware(middleware);12    queryUpdateListener.registerMiddleware(middleware2);13    expect(middleware).toHaveBeenCalledTimes(0);14    expect(middleware2).toHaveBeenCalledTimes(0);15    await queryUpdateListener._debouncedSearch('a query');16    expect(middleware).toHaveBeenCalledTimes(1);17    expect(middleware2).toHaveBeenCalledTimes(1);18    expect(middleware).toHaveBeenCalledWith('a query');19    expect(middleware2).toHaveBeenCalledWith('a query');20  });21});22describe('_handleQueryUpdate', () => {23  it('is called when the query is updated', () => {24    const queryUpdateListener = initQueryUpdateListener();25    const _handleQueryUpdate = jest.fn();26    queryUpdateListener._handleQueryUpdate = _handleQueryUpdate;27    expect(_handleQueryUpdate).toHaveBeenCalledTimes(0);28    queryUpdateListener.core.storage.setWithPersist(StorageKeys.QUERY, 'a query');29    expect(_handleQueryUpdate).toHaveBeenCalledTimes(1);30    expect(_handleQueryUpdate).toHaveBeenCalledWith('a query');31  });32});33describe('_debouncedSearch', () => {34  it('debounces searches', async () => {35    const queryUpdateListener = initQueryUpdateListener();36    await Promise.all([37      queryUpdateListener._debouncedSearch('query1'),38      queryUpdateListener._debouncedSearch('query2'),39      queryUpdateListener._debouncedSearch('query3')40    ]);41    expect(queryUpdateListener.core.search).toHaveBeenCalledTimes(1);42  });43  it('makes a universal search when no verticalKey is set', async () => {44    const queryUpdateListener = initQueryUpdateListener();45    await queryUpdateListener._debouncedSearch('query1');46    expect(queryUpdateListener.core.search).toHaveBeenCalledTimes(1);47    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(0);48    expect(queryUpdateListener.core.search).toHaveBeenCalledWith('query1', {49      setQueryParams: true,50      resetPagination: true51    });52  });53  it('makes a vertical search when there is a verticalKey set', async () => {54    const queryUpdateListener = initQueryUpdateListener({55      verticalKey: 'aVerticalKey'56    });57    await queryUpdateListener._debouncedSearch('query1');58    expect(queryUpdateListener.core.search).toHaveBeenCalledTimes(0);59    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(1);60    const expectedSearchOptions = {61      setQueryParams: true,62      resetPagination: true63    };64    expect(queryUpdateListener.core.verticalSearch)65      .toHaveBeenCalledWith('aVerticalKey', expectedSearchOptions, { input: 'query1' });66  });67});68describe('sets the search loading state properly', () => {69  it('no search loading state is set on init', () => {70    const queryUpdateListener = initQueryUpdateListener();71    const storage = queryUpdateListener.core.storage;72    expect(storage.get(StorageKeys.VERTICAL_RESULTS)).toBeFalsy();73    expect(storage.get(StorageKeys.UNIVERSAL_RESULTS)).toBeFalsy();74  });75  it('for universal results', () => {76    const queryUpdateListener = initQueryUpdateListener();77    const storage = queryUpdateListener.core.storage;78    storage.set(StorageKeys.QUERY, 'test query');79    expect(storage.get(StorageKeys.UNIVERSAL_RESULTS).searchState).toEqual(SearchStates.SEARCH_LOADING);80    expect(storage.get(StorageKeys.VERTICAL_RESULTS)).toBeFalsy();81  });82  it('for vertical results', () => {83    const queryUpdateListener = initQueryUpdateListener({84      verticalKey: 'aVerticalKey'85    });86    const storage = queryUpdateListener.core.storage;87    storage.set(StorageKeys.QUERY, 'test query');88    expect(storage.get(StorageKeys.VERTICAL_RESULTS).searchState).toEqual(SearchStates.SEARCH_LOADING);89    expect(storage.get(StorageKeys.UNIVERSAL_RESULTS)).toBeFalsy();90  });91});92describe('empty searches', () => {93  it('can always be run if the QUERY_TRIGGER is FILTER_COMPONENT', async () => {94    const queryUpdateListener = initQueryUpdateListener({95      verticalKey: 'aVerticalKey',96      allowEmptySearch: false97    });98    queryUpdateListener.core.storage.set(StorageKeys.QUERY_TRIGGER, QueryTriggers.FILTER_COMPONENT);99    await queryUpdateListener._debouncedSearch('');100    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(1);101  });102  it('will not be run when no QUERY_TRIGGER is set, and allowEmptySearch is false', async () => {103    const queryUpdateListener = initQueryUpdateListener({104      verticalKey: 'aVerticalKey',105      allowEmptySearch: false106    });107    await queryUpdateListener._debouncedSearch('');108    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(0);109  });110  it('will be run when no QUERY_TRIGGER is set, and allowEmptySearch is true', async () => {111    const queryUpdateListener = initQueryUpdateListener({112      verticalKey: 'aVerticalKey',113      allowEmptySearch: true114    });115    await queryUpdateListener._debouncedSearch('');116    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(1);117  });118  it('will be run by default', async () => {119    const queryUpdateListener = initQueryUpdateListener({120      verticalKey: 'aVerticalKey'121    });122    await queryUpdateListener._debouncedSearch('');123    expect(queryUpdateListener.core.verticalSearch).toHaveBeenCalledTimes(1);124  });125});126function initQueryUpdateListener (config) {127  const mockCore = {128    verticalSearch: jest.fn(),129    search: jest.fn(),130    storage: new Storage().init()131  };132  return new QueryUpdateListener(mockCore, config);...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
