diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 10:34:06 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 10:34:06 +0000 |
commit | 859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch) | |
tree | d7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /spec/frontend/__helpers__ | |
parent | 446d496a6d000c73a304be52587cd9bbc7493136 (diff) | |
download | gitlab-ce-859a6fb938bb9ee2a317c46dfa4fcc1af49608f0.tar.gz |
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'spec/frontend/__helpers__')
-rw-r--r-- | spec/frontend/__helpers__/emoji.js | 36 | ||||
-rw-r--r-- | spec/frontend/__helpers__/fake_date/fake_date.js (renamed from spec/frontend/__helpers__/fake_date.js) | 21 | ||||
-rw-r--r-- | spec/frontend/__helpers__/fake_date/fake_date_spec.js (renamed from spec/frontend/__helpers__/fake_date_spec.js) | 8 | ||||
-rw-r--r-- | spec/frontend/__helpers__/fake_date/index.js | 2 | ||||
-rw-r--r-- | spec/frontend/__helpers__/fake_date/jest.js | 41 | ||||
-rw-r--r-- | spec/frontend/__helpers__/graphql_helpers.js | 14 | ||||
-rw-r--r-- | spec/frontend/__helpers__/graphql_helpers_spec.js | 23 | ||||
-rw-r--r-- | spec/frontend/__helpers__/init_vue_mr_page_helper.js | 4 | ||||
-rw-r--r-- | spec/frontend/__helpers__/jest_execution_watcher.js | 12 | ||||
-rw-r--r-- | spec/frontend/__helpers__/stub_component.js | 25 |
10 files changed, 145 insertions, 41 deletions
diff --git a/spec/frontend/__helpers__/emoji.js b/spec/frontend/__helpers__/emoji.js index ea6613b53c9..9f9134f6f63 100644 --- a/spec/frontend/__helpers__/emoji.js +++ b/spec/frontend/__helpers__/emoji.js @@ -1,6 +1,6 @@ import MockAdapter from 'axios-mock-adapter'; -import axios from '~/lib/utils/axios_utils'; import { initEmojiMap, EMOJI_VERSION } from '~/emoji'; +import axios from '~/lib/utils/axios_utils'; export const emojiFixtureMap = { atom: { @@ -29,10 +29,6 @@ export const emojiFixtureMap = { unicodeVersion: '6.0', description: 'white question mark ornament', }, - - // used for regression tests - // black_heart MUST come before heart - // custard MUST come before star black_heart: { moji: '🖤', unicodeVersion: '1.1', @@ -55,34 +51,18 @@ export const emojiFixtureMap = { }, }; -Object.keys(emojiFixtureMap).forEach((k) => { - emojiFixtureMap[k].name = k; - if (!emojiFixtureMap[k].aliases) { - emojiFixtureMap[k].aliases = []; - } -}); +export const mockEmojiData = Object.keys(emojiFixtureMap).reduce((acc, k) => { + const { moji: e, unicodeVersion: u, category: c, description: d } = emojiFixtureMap[k]; + acc[k] = { name: k, e, u, c, d }; -export async function initEmojiMock() { - const emojiData = Object.fromEntries( - Object.values(emojiFixtureMap).map((m) => { - const { name: n, moji: e, unicodeVersion: u, category: c, description: d } = m; - return [n, { c, e, d, u }]; - }), - ); + return acc; +}, {}); +export async function initEmojiMock(mockData = mockEmojiData) { const mock = new MockAdapter(axios); - mock.onGet(`/-/emojis/${EMOJI_VERSION}/emojis.json`).reply(200, JSON.stringify(emojiData)); + mock.onGet(`/-/emojis/${EMOJI_VERSION}/emojis.json`).reply(200, JSON.stringify(mockData)); await initEmojiMap(); return mock; } - -export function describeEmojiFields(label, tests) { - describe.each` - field | accessor - ${'name'} | ${(e) => e.name} - ${'alias'} | ${(e) => e.aliases[0]} - ${'description'} | ${(e) => e.description} - `(label, tests); -} diff --git a/spec/frontend/__helpers__/fake_date.js b/spec/frontend/__helpers__/fake_date/fake_date.js index 5391ae04797..bc088ad96b6 100644 --- a/spec/frontend/__helpers__/fake_date.js +++ b/spec/frontend/__helpers__/fake_date/fake_date.js @@ -1,11 +1,13 @@ // Frida Kahlo's birthday (6 = July) -export const DEFAULT_ARGS = [2020, 6, 6]; +const DEFAULT_ARGS = [2020, 6, 6]; const RealDate = Date; const isMocked = (val) => Boolean(val.mock); -export const createFakeDateClass = (ctorDefault) => { +const createFakeDateClass = (ctorDefaultParam = []) => { + const ctorDefault = ctorDefaultParam.length ? ctorDefaultParam : DEFAULT_ARGS; + const FakeDate = new Proxy(RealDate, { construct: (target, argArray) => { const ctorArgs = argArray.length ? argArray : ctorDefault; @@ -39,11 +41,20 @@ export const createFakeDateClass = (ctorDefault) => { return FakeDate; }; -export const useFakeDate = (...args) => { - const FakeDate = createFakeDateClass(args.length ? args : DEFAULT_ARGS); +const setGlobalDateToFakeDate = (...args) => { + const FakeDate = createFakeDateClass(args); global.Date = FakeDate; }; -export const useRealDate = () => { +const setGlobalDateToRealDate = () => { global.Date = RealDate; }; + +// We use commonjs so that the test environment module can pick this up +// eslint-disable-next-line import/no-commonjs +module.exports = { + setGlobalDateToFakeDate, + setGlobalDateToRealDate, + createFakeDateClass, + RealDate, +}; diff --git a/spec/frontend/__helpers__/fake_date_spec.js b/spec/frontend/__helpers__/fake_date/fake_date_spec.js index b3ed13e238a..730765e52d2 100644 --- a/spec/frontend/__helpers__/fake_date_spec.js +++ b/spec/frontend/__helpers__/fake_date/fake_date_spec.js @@ -1,15 +1,11 @@ -import { createFakeDateClass, DEFAULT_ARGS, useRealDate } from './fake_date'; +import { createFakeDateClass } from './fake_date'; describe('spec/helpers/fake_date', () => { describe('createFakeDateClass', () => { let FakeDate; - beforeAll(() => { - useRealDate(); - }); - beforeEach(() => { - FakeDate = createFakeDateClass(DEFAULT_ARGS); + FakeDate = createFakeDateClass(); }); it('should use default args', () => { diff --git a/spec/frontend/__helpers__/fake_date/index.js b/spec/frontend/__helpers__/fake_date/index.js new file mode 100644 index 00000000000..3d1b124ce79 --- /dev/null +++ b/spec/frontend/__helpers__/fake_date/index.js @@ -0,0 +1,2 @@ +export * from './fake_date'; +export * from './jest'; diff --git a/spec/frontend/__helpers__/fake_date/jest.js b/spec/frontend/__helpers__/fake_date/jest.js new file mode 100644 index 00000000000..65e45619049 --- /dev/null +++ b/spec/frontend/__helpers__/fake_date/jest.js @@ -0,0 +1,41 @@ +import { createJestExecutionWatcher } from '../jest_execution_watcher'; +import { RealDate, createFakeDateClass } from './fake_date'; + +const throwInsideExecutionError = (fnName) => { + throw new Error(`Cannot call "${fnName}" during test execution (i.e. within "it", "beforeEach", "beforeAll", etc.). + +Instead, please move the call to "${fnName}" inside the "describe" block itself. + + describe('', () => { + + ${fnName}(); + + it('', () => { + - ${fnName}(); + }) + }) +`); +}; + +const isExecutingTest = createJestExecutionWatcher(); + +export const useDateInScope = (fnName, factory) => { + if (isExecutingTest()) { + throwInsideExecutionError(fnName); + } + + let origDate; + + beforeAll(() => { + origDate = global.Date; + global.Date = factory(); + }); + + afterAll(() => { + global.Date = origDate; + }); +}; + +export const useFakeDate = (...args) => + useDateInScope('useFakeDate', () => createFakeDateClass(args)); + +export const useRealDate = () => useDateInScope('useRealDate', () => RealDate); diff --git a/spec/frontend/__helpers__/graphql_helpers.js b/spec/frontend/__helpers__/graphql_helpers.js new file mode 100644 index 00000000000..63123aa046f --- /dev/null +++ b/spec/frontend/__helpers__/graphql_helpers.js @@ -0,0 +1,14 @@ +/** + * Returns a clone of the given object with all __typename keys omitted, + * including deeply nested ones. + * + * Only works with JSON-serializable objects. + * + * @param {object} An object with __typename keys (e.g., a GraphQL response) + * @returns {object} A new object with no __typename keys + */ +export const stripTypenames = (object) => { + return JSON.parse( + JSON.stringify(object, (key, value) => (key === '__typename' ? undefined : value)), + ); +}; diff --git a/spec/frontend/__helpers__/graphql_helpers_spec.js b/spec/frontend/__helpers__/graphql_helpers_spec.js new file mode 100644 index 00000000000..dd23fbbf4e9 --- /dev/null +++ b/spec/frontend/__helpers__/graphql_helpers_spec.js @@ -0,0 +1,23 @@ +import { stripTypenames } from './graphql_helpers'; + +describe('stripTypenames', () => { + it.each` + input | expected + ${{}} | ${{}} + ${{ __typename: 'Foo' }} | ${{}} + ${{ bar: 'bar', __typename: 'Foo' }} | ${{ bar: 'bar' }} + ${{ bar: { __typename: 'Bar' }, __typename: 'Foo' }} | ${{ bar: {} }} + ${{ bar: [{ __typename: 'Bar' }], __typename: 'Foo' }} | ${{ bar: [{}] }} + ${[]} | ${[]} + ${[{ __typename: 'Foo' }]} | ${[{}]} + ${[{ bar: [{ a: 1, __typename: 'Bar' }] }]} | ${[{ bar: [{ a: 1 }] }]} + `('given $input returns $expected, with all __typename keys removed', ({ input, expected }) => { + const actual = stripTypenames(input); + expect(actual).toEqual(expected); + expect(input).not.toBe(actual); + }); + + it('given null returns null', () => { + expect(stripTypenames(null)).toEqual(null); + }); +}); diff --git a/spec/frontend/__helpers__/init_vue_mr_page_helper.js b/spec/frontend/__helpers__/init_vue_mr_page_helper.js index b9aed63d0f6..ee01e9e6268 100644 --- a/spec/frontend/__helpers__/init_vue_mr_page_helper.js +++ b/spec/frontend/__helpers__/init_vue_mr_page_helper.js @@ -1,8 +1,8 @@ import MockAdapter from 'axios-mock-adapter'; -import initMRPage from '~/mr_notes'; import axios from '~/lib/utils/axios_utils'; -import { userDataMock, notesDataMock, noteableDataMock } from '../notes/mock_data'; +import initMRPage from '~/mr_notes'; import diffFileMockData from '../diffs/mock_data/diff_file'; +import { userDataMock, notesDataMock, noteableDataMock } from '../notes/mock_data'; export default function initVueMRPage() { const mrTestEl = document.createElement('div'); diff --git a/spec/frontend/__helpers__/jest_execution_watcher.js b/spec/frontend/__helpers__/jest_execution_watcher.js new file mode 100644 index 00000000000..0fc3d330ec3 --- /dev/null +++ b/spec/frontend/__helpers__/jest_execution_watcher.js @@ -0,0 +1,12 @@ +export const createJestExecutionWatcher = () => { + let isExecuting = false; + + beforeAll(() => { + isExecuting = true; + }); + afterAll(() => { + isExecuting = false; + }); + + return () => isExecuting; +}; diff --git a/spec/frontend/__helpers__/stub_component.js b/spec/frontend/__helpers__/stub_component.js index 45550450517..96fe3a8bc45 100644 --- a/spec/frontend/__helpers__/stub_component.js +++ b/spec/frontend/__helpers__/stub_component.js @@ -1,7 +1,32 @@ +/** + * Returns a new object with keys pointing to stubbed methods + * + * This is helpful for stubbing components like GlModal where it's supported + * in the API to call `.show()` and `.hide()` ([Bootstrap Vue docs][1]). + * + * [1]: https://bootstrap-vue.org/docs/components/modal#using-show-hide-and-toggle-component-methods + * + * @param {Object} methods - Object whose keys will be in the returned object. + */ +const createStubbedMethods = (methods = {}) => { + if (!methods) { + return {}; + } + + return Object.keys(methods).reduce( + (acc, key) => + Object.assign(acc, { + [key]: () => {}, + }), + {}, + ); +}; + export function stubComponent(Component, options = {}) { return { props: Component.props, model: Component.model, + methods: createStubbedMethods(Component.methods), // Do not render any slots/scoped slots except default // This differs from VTU behavior which renders all slots template: '<div><slot></slot></div>', |