Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend_integration/test_helpers/utils')
-rw-r--r--spec/frontend_integration/test_helpers/utils/obj.js36
-rw-r--r--spec/frontend_integration/test_helpers/utils/obj_spec.js23
-rw-r--r--spec/frontend_integration/test_helpers/utils/overclock_timers.js65
3 files changed, 124 insertions, 0 deletions
diff --git a/spec/frontend_integration/test_helpers/utils/obj.js b/spec/frontend_integration/test_helpers/utils/obj.js
new file mode 100644
index 00000000000..6c301798489
--- /dev/null
+++ b/spec/frontend_integration/test_helpers/utils/obj.js
@@ -0,0 +1,36 @@
+import { has, mapKeys, pick } from 'lodash';
+
+/**
+ * This method is used to type-safely set values on the given object
+ *
+ * @template T
+ * @returns {T} A shallow copy of `obj`, with the values from `values`
+ * @throws {Error} If `values` contains a key that isn't already on `obj`
+ * @param {T} source
+ * @param {Object} values
+ */
+export const withValues = (source, values) =>
+ Object.entries(values).reduce(
+ (acc, [key, value]) => {
+ if (!has(acc, key)) {
+ throw new Error(
+ `[mock_server] Cannot write property that does not exist on object '${key}'`,
+ );
+ }
+
+ return {
+ ...acc,
+ [key]: value,
+ };
+ },
+ { ...source },
+ );
+
+/**
+ * This method returns a subset of the given object and maps the key names based on the
+ * given `keys`.
+ *
+ * @param {Object} obj The source object.
+ * @param {Object} map The object which contains the keys to use and mapped key names.
+ */
+export const withKeys = (obj, map) => mapKeys(pick(obj, Object.keys(map)), (val, key) => map[key]);
diff --git a/spec/frontend_integration/test_helpers/utils/obj_spec.js b/spec/frontend_integration/test_helpers/utils/obj_spec.js
new file mode 100644
index 00000000000..0ad7b4a1a4c
--- /dev/null
+++ b/spec/frontend_integration/test_helpers/utils/obj_spec.js
@@ -0,0 +1,23 @@
+import { withKeys, withValues } from './obj';
+
+describe('frontend_integration/test_helpers/utils/obj', () => {
+ describe('withKeys', () => {
+ it('picks and maps keys', () => {
+ expect(withKeys({ a: '123', b: 456, c: 'd' }, { b: 'lorem', c: 'ipsum', z: 'zed ' })).toEqual(
+ { lorem: 456, ipsum: 'd' },
+ );
+ });
+ });
+
+ describe('withValues', () => {
+ it('sets values', () => {
+ expect(withValues({ a: '123', b: 456 }, { b: 789 })).toEqual({ a: '123', b: 789 });
+ });
+
+ it('throws if values has non-existent key', () => {
+ expect(() => withValues({ a: '123', b: 456 }, { b: 789, bogus: 'throws' })).toThrow(
+ `[mock_server] Cannot write property that does not exist on object 'bogus'`,
+ );
+ });
+ });
+});
diff --git a/spec/frontend_integration/test_helpers/utils/overclock_timers.js b/spec/frontend_integration/test_helpers/utils/overclock_timers.js
new file mode 100644
index 00000000000..046c7f8e527
--- /dev/null
+++ b/spec/frontend_integration/test_helpers/utils/overclock_timers.js
@@ -0,0 +1,65 @@
+/**
+ * This function replaces the existing `setTimeout` and `setInterval` with wrappers that
+ * discount the `ms` passed in by `boost`.
+ *
+ * For example, if a module has:
+ *
+ * ```
+ * setTimeout(cb, 100);
+ * ```
+ *
+ * But a test has:
+ *
+ * ```
+ * useOverclockTimers(25);
+ * ```
+ *
+ * Then the module's call to `setTimeout` effectively becomes:
+ *
+ * ```
+ * setTimeout(cb, 4);
+ * ```
+ *
+ * It's important to note that the timing for `setTimeout` and order of execution is non-deterministic
+ * and discounting the `ms` passed could make this very obvious and expose some underlying issues
+ * with flaky failures.
+ *
+ * WARNING: If flaky spec failures show up in a spec that is using this helper, please consider either:
+ *
+ * - Refactoring the production code so that it's reactive to state changes, not dependent on timers.
+ * - Removing the call to this helper from the spec.
+ *
+ * @param {Number} boost
+ */
+// eslint-disable-next-line import/prefer-default-export
+export const useOverclockTimers = (boost = 50) => {
+ if (boost <= 0) {
+ throw new Error(`[overclock_timers] boost (${boost}) cannot be <= 0`);
+ }
+
+ let origSetTimeout;
+ let origSetInterval;
+ const newSetTimeout = (fn, msParam = 0) => {
+ const ms = msParam > 0 ? Math.floor(msParam / boost) : msParam;
+
+ return origSetTimeout(fn, ms);
+ };
+ const newSetInterval = (fn, msParam = 0) => {
+ const ms = msParam > 0 ? Math.floor(msParam / boost) : msParam;
+
+ return origSetInterval(fn, ms);
+ };
+
+ beforeEach(() => {
+ origSetTimeout = global.setTimeout;
+ origSetInterval = global.setInterval;
+
+ global.setTimeout = newSetTimeout;
+ global.setInterval = newSetInterval;
+ });
+
+ afterEach(() => {
+ global.setTimeout = origSetTimeout;
+ global.setInterval = origSetInterval;
+ });
+};