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/vue_compat_test_setup.js')
-rw-r--r--spec/frontend/vue_compat_test_setup.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/spec/frontend/vue_compat_test_setup.js b/spec/frontend/vue_compat_test_setup.js
new file mode 100644
index 00000000000..6eba9465c80
--- /dev/null
+++ b/spec/frontend/vue_compat_test_setup.js
@@ -0,0 +1,141 @@
+/* eslint-disable import/no-commonjs */
+const Vue = require('vue');
+const VTU = require('@vue/test-utils');
+const { installCompat: installVTUCompat, fullCompatConfig } = require('vue-test-utils-compat');
+
+function getComponentName(component) {
+ if (!component) {
+ return undefined;
+ }
+
+ return (
+ component.name ||
+ getComponentName(component.extends) ||
+ component.mixins?.find((mixin) => getComponentName(mixin))
+ );
+}
+
+function isLegacyExtendedComponent(component) {
+ return Reflect.has(component, 'super') && component.super.extend({}).super === component.super;
+}
+function unwrapLegacyVueExtendComponent(selector) {
+ return isLegacyExtendedComponent(selector) ? selector.options : selector;
+}
+
+if (global.document) {
+ const compatConfig = {
+ MODE: 2,
+
+ GLOBAL_MOUNT: 'suppress-warning',
+ GLOBAL_EXTEND: 'suppress-warning',
+ GLOBAL_PROTOTYPE: 'suppress-warning',
+ RENDER_FUNCTION: 'suppress-warning',
+
+ INSTANCE_DESTROY: 'suppress-warning',
+ INSTANCE_DELETE: 'suppress-warning',
+
+ INSTANCE_ATTRS_CLASS_STYLE: 'suppress-warning',
+ INSTANCE_CHILDREN: 'suppress-warning',
+ INSTANCE_SCOPED_SLOTS: 'suppress-warning',
+ INSTANCE_LISTENERS: 'suppress-warning',
+ INSTANCE_EVENT_EMITTER: 'suppress-warning',
+ INSTANCE_EVENT_HOOKS: 'suppress-warning',
+ INSTANCE_SET: 'suppress-warning',
+ GLOBAL_OBSERVABLE: 'suppress-warning',
+ GLOBAL_SET: 'suppress-warning',
+ COMPONENT_FUNCTIONAL: 'suppress-warning',
+ COMPONENT_V_MODEL: 'suppress-warning',
+ COMPONENT_ASYNC: 'suppress-warning',
+ CUSTOM_DIR: 'suppress-warning',
+ OPTIONS_BEFORE_DESTROY: 'suppress-warning',
+ OPTIONS_DATA_MERGE: 'suppress-warning',
+ OPTIONS_DATA_FN: 'suppress-warning',
+ OPTIONS_DESTROYED: 'suppress-warning',
+ ATTR_FALSE_VALUE: 'suppress-warning',
+
+ COMPILER_V_ON_NATIVE: 'suppress-warning',
+ COMPILER_V_BIND_OBJECT_ORDER: 'suppress-warning',
+
+ CONFIG_WHITESPACE: 'suppress-warning',
+ CONFIG_OPTION_MERGE_STRATS: 'suppress-warning',
+ PRIVATE_APIS: 'suppress-warning',
+ WATCH_ARRAY: 'suppress-warning',
+ };
+
+ let compatH;
+ Vue.config.compilerOptions.whitespace = 'preserve';
+ Vue.createApp({
+ compatConfig: {
+ MODE: 3,
+ RENDER_FUNCTION: 'suppress-warning',
+ },
+ render(h) {
+ compatH = h;
+ },
+ }).mount(document.createElement('div'));
+
+ Vue.configureCompat(compatConfig);
+ installVTUCompat(VTU, fullCompatConfig, compatH);
+ VTU.config.global.renderStubDefaultSlot = true;
+
+ const noop = () => {};
+
+ VTU.config.plugins.createStubs = ({ name, component: rawComponent, registerStub }) => {
+ const component = unwrapLegacyVueExtendComponent(rawComponent);
+ const hyphenatedName = name.replace(/\B([A-Z])/g, '-$1').toLowerCase();
+
+ const stub = Vue.defineComponent({
+ name: getComponentName(component),
+ props: component.props,
+ model: component.model,
+ methods: Object.fromEntries(
+ Object.entries(component.methods ?? {}).map(([key]) => [key, noop]),
+ ),
+ render() {
+ const {
+ $slots: slots = {},
+ $scopedSlots: scopedSlots = {},
+ $parent: parent,
+ $vnode: vnode,
+ } = this;
+
+ const hasStaticDefaultSlot = 'default' in slots && !('default' in scopedSlots);
+ const isTheOnlyChild = parent?.$.subTree === vnode;
+ // this condition should be altered when https://github.com/vuejs/vue-test-utils/pull/2068 is merged
+ // and our codebase will be updated to include it (@vue/test-utils@1.3.6 I assume)
+ const shouldRenderAllSlots = !hasStaticDefaultSlot && isTheOnlyChild;
+
+ const renderSlotByName = (slotName) => {
+ const slot = scopedSlots[slotName] || slots[slotName];
+ let result;
+ if (typeof slot === 'function') {
+ try {
+ result = slot({});
+ } catch {
+ // intentionally blank
+ }
+ } else {
+ result = slot;
+ }
+ return result;
+ };
+
+ const slotContents = shouldRenderAllSlots
+ ? [...new Set([...Object.keys(slots), ...Object.keys(scopedSlots)])]
+ .map(renderSlotByName)
+ .filter(Boolean)
+ : renderSlotByName('default');
+
+ return Vue.h(`${hyphenatedName || 'anonymous'}-stub`, this.$props, slotContents);
+ },
+ });
+
+ if (typeof component === 'function') {
+ component()?.then?.((resolvedComponent) => {
+ registerStub({ source: resolvedComponent.default, stub });
+ });
+ }
+
+ return stub;
+ };
+}