Repository: vuejs/test-utils
Pull request #2185 (2023-09-11 10:53:00)

feat: allow custom `<transition>` stubs
At the moment, `@vue/test-utils` doesn't allow custom `<transition>` stubs. For example, setting:

```js
config.stubs.transition = {template: '<div />'};
```

...will still just render the default `@vue/test-utils` stub:

```html
<transition-stub appear="false" persisted="false" css="true">
```

The motivation for this change is that if you're using the `@vue/compat` migration build, these default stubs throw up the following warning:

```
Error: (deprecation ATTR_FALSE_VALUE) Attribute "persisted" with v-bind value `false` will render persisted="false" instead of removing it in Vue 3. To remove the attribute, use `null` or `undefined` instead. If the usage is intended, you can disable the compat behavior and suppress this warning with:

      configureCompat({ ATTR_FALSE_VALUE: false })

      Details: https://v3-migration.vuejs.org/breaking-changes/attribute-coercion.html
      at <Transition>
```

Since `persisted` isn't actually a [boolean HTML attribute][1], and is actually a [prop][2], we want to ignore this false positive, but don't want to disable this warning everywhere (so we can catch *actual* errors).

In order to clean up our test warnings, we would like to use a custom `<transition>` stub, which doesn't have these props. This change tweaks the `transition` stubbing logic, and only creates the default stub if `transition === true`. If it's any other truthy value, it falls back to "normal" stubbing behaviour.

## Depends on:

 - [ ] https://github.com/vuejs/test-utils/pull/2186

[1]: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
[2]: https://github.com/vuejs/core/blob/b775b71c788499ec7ee58bc2cf4cd04ed388e072/packages/runtime-core/src/components/BaseTransition.ts#L37

alecgibson: Okay I've separately raised https://github.com/vuejs/test-utils/pull/2186 (which this is now on top of), where I've commonised all the boilerplate for default stubs, so now this fix will fix *all* default stubs in the same way.
cexbrayat: Awesome, thanks @alecgibson , one of us will take a look when we have some time 👍
alecgibson: @cexbrayat I've rebased onto `main`

Patch:
diff --git a/src/vnodeTransformers/stubComponentsTransformer.ts b/src/vnodeTransformers/stubComponentsTransformer.ts
index 716a946..7f1a110 100644
--- a/src/vnodeTransformers/stubComponentsTransformer.ts
+++ b/src/vnodeTransformers/stubComponentsTransformer.ts
@@ -78,11 +78,13 @@ const createDefaultStub = (
     if (kebabTag in stubs && stubs[kebabTag] === false) return type
     if (pascalTag in stubs && stubs[pascalTag] === false) return type
 
-    return createStub({
-      name: kebabTag,
-      type,
-      renderStubDefaultSlot: true
-    })
+    if (stubs[kebabTag] === true || stubs[pascalTag] === true) {
+      return createStub({
+        name: kebabTag,
+        type,
+        renderStubDefaultSlot: true
+      })
+    }
   }
 }
 


Test patch:
diff --git a/tests/mountingOptions/global.stubs.spec.ts b/tests/mountingOptions/global.stubs.spec.ts
index 29ccbcc..80b2200 100644
--- a/tests/mountingOptions/global.stubs.spec.ts
+++ b/tests/mountingOptions/global.stubs.spec.ts
@@ -482,6 +482,24 @@ describe('mounting options: stubs', () => {
           '</transition-stub>'
       )
     })
+
+    it('custom transition stub', () => {
+      const Comp = {
+        template: `<transition><div id="content-custom-stub" /></transition>`
+      }
+      config.global.stubs = {
+        transition: {
+          template: '<div class="custom-transition-stub"><slot /></div>'
+        }
+      }
+      const wrapper = mount(Comp)
+
+      expect(wrapper.html()).toBe(
+        '<div class="custom-transition-stub">\n' +
+          '  <div id="content-custom-stub"></div>\n' +
+          '</div>'
+      )
+    })
   })
 
   describe('transition-group', () => {